门 Threejs贴图为了更好的渲染

渲染结果图
门模型使用标准网格材质(),一种基于物理的渲染 。使用PBR方式渲染 。
思路: (1) 建立立方体模 (2)设置基本颜色.map属性添加颜色贴图 color.png (贴图效果与颜色是叠加的)一个简单的带有纹理的立方体的们就成形了 .map:
颜色贴图 。可以选择包括一个alpha通道,通常与.或. 。默认为null 。纹理贴图颜色由漫反射颜色.color调节 。
因此可以选择添加一个alpha贴图去除纹理门框边缘的位置,下面是文档给出的解释:
.:
alpha贴图是一张灰度纹理,用于控制整个表面的不透明度 。(黑色:完全透明;白色:完全不透明) 。默认值为null 。
(3)此时的门的边缘线并不明显,可以添加aoMap属性环境遮挡贴图 。细化效果 。
.aoMap:
该纹理的红色通道用作环境遮挡贴图 。默认值为null 。aoMap需要第二组UV 。设置第二组uv下面代码中有体现 。
.:Float
环境遮挡效果的强度 。默认值为1 。零是不遮挡效果 。
(4)此时的呈像给人还是二维的感觉,使用.属性,添加位移贴图达到三位的校效果 。.:
位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象,以及充当真实的几何体 。位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位 。
.:Float
位移贴图对网格的影响程度(黑色是无位移,白色是最大位移) 。如果没有设置位移贴图,则不会应用此值 。默认值为1 。
注:应当设立立方体的段数.***(设置长/宽/高应该划分为几段,默认为1),此处设置为了增加顶点的个数,因为位移贴图是通过影响网格顶点的位置来实现的,段数越多模型越精细 。
(5)此处已经使用了四张贴图 。我们看后面的贴图的使用 。
为了让门的金属部分效果更逼真,.设置金属贴图(图片中越倾向白色越靠近金属)
.:Float
材质与金属的相似度 。非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值 。默认值为0.0 。0.0到1.0之间的值可用于生锈金属的外观 。如果还提供了,则两个值相乘 。
.:
该纹理的蓝色通道用于改变材质的金属度 。
(6)为了让门更加贴切与生活 。可以添加属性,导入粗糙度贴图,设置粗糙度(黑色粗糙,白色光滑) .:Float
材质的粗糙程度 。0.0表示平滑的镜面反射,1.0表示完全漫反射 。默认值为1.0 。如果还提供,则两个值相乘 。
.:
该纹理的绿色通道用于改变材质的粗糙度 。
(7)因为日常光照下,门的面是漫反射反光强度不同,所以最后在添加一个法线贴图拉 。.:
用于创建法线贴图的纹理 。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式 。法线贴图不会改变曲面的实际形状,只会改变光照 。
现在这个门的模型就创建完成了 。贴图放在了代码后面 。需要的朋友可以自己粘贴 。
import * as THREE from "three";import {Clock, TextureLoader, WebGLRenderer} from "three";import {fromHalfFloat} from "three/src/extras/DataUtils";// 导入轨道控制器import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";// 1. 创建场景const scene = new THREE.Scene();// 2. 创建相机const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);camera.position.set(0,0,10);scene.add(camera);const loader = new TextureLoader();const load1 = loader.load("./textures/door/color.jpg");const load2 = loader.load("./textures/door/ambientOcclusion.jpg");const load3 = loader.load("./textures/door/alpha.jpg");// 导入金属贴图const metalnessTexture = loader.load("./textures/door/metalness.jpg");// 导入粗糙度贴图const roughnessTexture = loader.load("./textures/door/roughness.jpg");//导入置换贴图作位移使用const doorHeightTexture = loader.load("./textures/door/height.jpg");// 导入法线贴图const normalTexture = loader.load("./textures/door/normal.jpg");// 添加我物体创建物体let geometry = new THREE.BoxGeometry(2,2,2,100,100,100);let material = new THREE.MeshStandardMaterial({color : 0xffff00,map : load1,// 颜色贴图aoMapIntensity :0.7,alphaMap : load3,// alpha贴图是一张灰度纹理,用于控制整个表面的不透明度transparent :true,aoMap : load2,// 该纹理的红色通道用作环境遮挡贴图 。默认值为null 。aoMap需要第二组UVside : THREE.DoubleSide,metalness: 1,metalnessMap: metalnessTexture,roughness: 1,roughnessMap: roughnessTexture,// 黑色粗糙,白色光滑displacementMap: doorHeightTexture,displacementScale: 0.1,normalMap: normalTexture,});let mesh = new THREE.Mesh(geometry,material);scene.add(mesh);/** 设置第二组uv */geometry.setAttribute("uv2",new THREE.BufferAttribute(geometry.attributes.uv.array,2));// 灯光// 环境光const light = new THREE.AmbientLight(0xffffff, 0.5); // soft white lightscene.add(light);//直线光源const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);directionalLight.position.set(10, 10, 10);scene.add(directionalLight);// 初始化渲染器var renderer = new WebGLRenderer();renderer.setSize(window.innerWidth,window.innerHeight);// 将webgl渲染的canvas 内容添加进入 bodydocument.body.appendChild(renderer.domElement);// 创建轨道控制器const controls = new OrbitControls(camera,renderer.domElement);controls.enableDamping = true;// 设置阻尼var helper = new THREE.AxesHelper(5);scene.add(helper);function render(){controls.update();renderer.render(scene,camera);// 渲染下一帧就会调用render 函数requestAnimationFrame(render);// 请求动画帧}render();// 监听页面变化,更新渲染画面window.addEventListener("resize",()=>{// 1. 更新摄像头camera.aspect = window.innerWidth / window.innerHeight;// 2. 更新摄像机的投影矩阵camera.updateProjectionMatrix();// 3. 更新渲染器renderer.setSize(window.innerWidth,window.innerHeight);// 4. 更新渲染器的像素比renderer.setPixelRatio(window.devicePixelRatio);})window.addEventListener("dblclick",()=>{const fullScreenElement = document.fullscreenElement;// 是否全屏if (!fullScreenElement) {renderer.domElement.requestFullscreen();} else {document.exitFullscreen();}});