初始化基础网格材质
MeshBasicMaterial
,这种材质不受光照的影响。
const material = new THREE.MeshBasicMaterial()
接下来我们往场景中添加三个网格物体
const sphere = new THREE.Mesh(new THREE.SphereBufferGeometry(0.5,16,16),material)
const plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(1,1),material)
const torus = new THREE.Mesh(new THREE.TorusBufferGeometry(0.5,0.2,16,32),material)
sphere.position.x = -1.5
torus.position.x = 1.5
scene.add(sphere,plane,torus)
const material = new THREE.MeshBasicMaterial({map:doorColorTexture})
或者这样写
const material = new THREE.MeshBasicMaterial()
material.map = doorColorTexture
const material = new THREE.MeshBasicMaterial({color:0xff0000})
另外一种写法,效仿上面设置纹理贴图,但你会发现如果直接设置材质的颜色,会报错
const material = new THREE.MeshBasicMaterial()
console.log(material.color)
material.color = 'red'
这是因为一旦材质被实例化后,它的.color
属性会是一个Color类
材质对象的一些属性可以在构造函数参数中设置,也可以访问材质对象的属性设置。
你可以通过下面俩种方式设置材质颜色属性
material.color.set('#ff00ff')
material.color = new THREE.Color('red')
颜色和纹理可以结合起来
若想设置材质透明,则必须开启透明度效果,设置.transparent
属性为true
material.transparent = true
material.opacity = 0.5
material.transparent = true
material.alphaMap = doorAlphaTexture
简单来讲,alpha贴图白色区域是可见的,黑色区域将被隐藏起来
我们可以把alpha贴图和其他纹理贴图结合起来
material.side = THREE.FrontSide
material.side = THREE.BackSide
material.side = THREE.DoubleSide
它是一种把法向量映射到RGB颜色的材质。
const material = new THREE.MeshNormalMaterial()
如果你改变下图摄像机位置,可以观察到物体颜色会有所不同。
法线可以用于照明、反射与折射等。
像transparent
,opacity
和side
这三个属性都是所有材质共有的属性
其定义材质是否使用平面着色进行渲染。
material.flatShading = true
可以观察到非平面物体表面不再那么光滑了。
但由于颜色纷呈,所以也可以试着运用到项目中
网帽材质(MeshMatcapMaterial)将通过使用法线作为参照来在看起来像球体的纹理上拾取正确的颜色来显示颜色
const material = new THREE.MeshMatcapMaterial()
我们将网帽材质的matcap
属性设置为下图matcap纹理贴图
material.matcap = matcapsTexture
查看渲染效果,我们会有一种错觉,感觉物体被照亮了一样。因此网帽材质的作用就是在场景没有光源的情况下,模拟出物体被光照的效果
如果几何体接近摄影机的“near”值,它将简单地将几何体着色为白色,如果几何体越接近摄影机的“far”值,则将几何体着色为黑色。
const material = new THREE.MeshDepthMaterial()
下图为摄像机正常观察情况
下图为摄像机靠近圆环体的观察情况
该材质对光线有反应
const material = new THREE.MeshLambertMaterial()
因此先往场景添加光源,才可以观察到物体,这里我们添加环境光和点光源
const ambientLight = new THREE.AmbientLight(0xffffff,0.5)
scene.add(ambientLight)
const pointLight = new THREE.PointLight(0xffffff,0.5)
pointLight.position.set(2,3,4)
scene.add(pointLight)
如果我们不添加光源,由于我们没有为渲染器添加背景颜色,所以我们会看到一片漆黑。
Phong网格材质与Lambert网格材质很相似,但是你可以仔细观察到上图中Lambert网格材质的球体表面有些像是线型一样的奇怪图案,而Phong网格材质的球体相对于前者这些图案不太明显,并且你还能看到Phong网格材质球体上光线的反射更为明亮。
我们可以通过shininess
属性控制光线反射高亮程度,数值越高越闪亮,并通过specular
属性控制反射的颜色
material.shininess = 100
material.specular = new THREE.Color('0xff0000')
Toon网格材质与Lambert网格材质很相似,但更偏向于卡通化。我们可以看出物体的颜色渐变非常明显
如果要使其渐变层次更丰富,我们可以将toon材质的gradientMap
属性设置为gradient渐变纹理贴图
material.gradientMap = gradientTexture
下图是渐变纹理贴图
观察下图效果,我们不能说它与Lambert网格材质十分相似,只能说是一模一样,但是很明显失去了卡通化的效果
这是因为放大滤镜magFilter试图通过拉伸来修复这个非常小的渐变纹理贴图,这过程就使用到了mip映射(mipmapping)使其变得模糊。
所以若想防止此种情况,我们可以设置纹理贴图的缩小滤镜minFilter
属性和放大滤镜magFilter
属性为THREE.NearestFilter。
关于滤镜属性可以查看我另一篇笔记three.js学习笔记(二)——textures纹理
gradientTexture.minFilter = THREE.NearestFilter
gradientTexture.magFilter = THREE.NearestFilter
gradientTexture.generateMipmaps = false
下图为5层渐变
一种基于物理的渲染(PBR)的标准材质,该材质提供了比MeshLambertMaterial 或MeshPhongMaterial 更精确和逼真的结果,代价是计算成本更高。
材质与金属的相似度。非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。
材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。
以上两种属性可通过添加GUI面板改变数值进行观察
aoMap(ambient occlusion map)环境遮挡贴图。它将在纹理较暗的地方添加阴影,因此我们必须添加另外一组uv坐标,即uv2。
在我们的例子中,它与默认UV的坐标相同,因此我们将重用它。
sphere.geometry.setAttribute('uv2',new THREE.BufferAttribute(sphere.geometry.attributes.uv.array,2))
plane.geometry.setAttribute('uv2',new THREE.BufferAttribute(plane.geometry.attributes.uv.array,2))
torus.geometry.setAttribute('uv2',new THREE.BufferAttribute(torus.geometry.attributes.uv.array,2))
为材质aoMap
属性设置ao(ambient occlusion)纹理贴图
material.aoMap = doorAmbientOcclusionTexture
我们还可以设置环境遮挡效果的强度aoMapIntensity
属性。默认值为1。零是不遮挡效果。
material.aoMapIntensity = 3.1
位移贴图会影响网格顶点的位置。换句话说就是它可以移动顶点来创建浮雕。
为材质displacementMap
属性设置位移纹理贴图,使得平面物体中间的门有凸起效果。
material.displacementMap = doorHeightTexture
物体看起来非常糟糕奇怪。这是因为我们的几何体中没有足够的顶点,所以你可以观察到平面几何体没有任何变化
重新设置几何体的分段数,给其设置更多些
const sphere = new THREE.Mesh(new THREE.SphereBufferGeometry(0.5,64,64),material)
const plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(1,1,100,100),material)
const torus = new THREE.Mesh(new THREE.TorusBufferGeometry(0.3,0.2,64,128),material)
重新观察
观察上图可以发现几何体顶点数多起来后,物体稍微变得不再那么奇怪,至少有点规则性了。
同时我们也注意到这默认位移效果有点用力过猛,这时我们可以设置displacementScale
属性:位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。默认值为1。
material.displacementScale = 0.1
同样道理,还有metalnessMap
属性和roughnessMap
属性也一样可以设置相应纹理贴图,这样我们可以不必为整个几何体指定均匀的金属程度和粗糙度,而是变为局部改变。
material.metalnessMap = doorMetalnessTexture
material.roughnessMap = doorRoughnessTexture
可以观察到整个木材表面非常光滑,铁锁位置粗糙
用于创建法线纹理贴图的纹理。它将伪造法线方向,并在物体表面上添加细节。
material.normalMap = doorNormalTexture
可以观察到这个木门已经开始有点栩栩如生了
我们可以normalScale
属性改变法线纹理贴图对材质的影响程度。典型范围是0-1。默认值是Vector2设置为(1,1)。
material.normalScale.set(0.5,0.5)
最后我们往材质中再设置alphaMap
属性,添加alpha纹理贴图
material.alphaMap = doorAlphaTexture
material.transparent = true
终于有了一扇完整的看起来正常的门了
const material = new THREE.MeshStandardMaterial()
material.map = doorColorTexture
material.aoMap = doorAmbientOcclusionTexture
material.aoMapIntensity = 1
material.displacementMap = doorHeightTexture
material.displacementScale = 0.05
material.metalnessMap = doorMetalnessTexture
material.roughnessMap = doorRoughnessTexture
material.normalMap = doorNormalTexture
material.normalScale.set(0.5,0.5)
material.alphaMap = doorAlphaTexture
material.transparent = true
物理网格材质MeshPhysicalMaterial与标准网格材质MeshStandardMaterial很相似,只不过物理网格材质具有清晰的涂层效果和更高级的基于物理的渲染属性,可以将其看作是标准网格材质的扩展
我们可以用点材质创建粒子
环境贴图是场景周围环境的图像。它可以用于反射或折射,也可以用于一般照明,支持多种材质。Three.js仅支持立方环境贴图。
使用CubeTextureLoader而不是TextureLoader
const cubeTextureLoader = new THREE.CubeTextureLoader()
const environmentMapTexture = cubeTextureLoader.load([
'/textures/environmentMaps/0/px.jpg',
'/textures/environmentMaps/0/nx.jpg',
'/textures/environmentMaps/0/py.jpg',
'/textures/environmentMaps/0/nx.jpg',
'/textures/environmentMaps/0/pz.jpg',
'/textures/environmentMaps/0/nz.jpg',
material.envMap = environmentMapTexture
观察效果。可以通过设置metalness
金属度和roughness
粗糙度控制反射情况
const material = new THREE.MeshStandardMaterial()
material.metalness = 0.7
material.roughness = 0.2
material.envMap = environmentMapTexture
gui.add(material,'metalness').min(0).max(1).step(0.0001)
gui.add(material,'roughness').min(0).max(1).step(0.0001)
polyhaven
从上面这个网站下载的环境贴图是一张HDRI图片,可以使用这个工具HDRI-to-CubeMap将HDRI转化为立方体贴图
什么是材质Material材质用于在几何体的每个可见像素上添加颜色创建材质初始化基础网格材质MeshBasicMaterialconst material = new THREE.MeshBasicMaterial()接下来我们往场景中添加三个网格物体//球形缓冲几何体const sphere = new THREE.Mesh(new THREE.SphereBufferGeometry(0.5,16,16),material)//平面缓冲几何体const plane = new THR
材质的获取 基本api使用
github:https://github.com/taixinF/methreejs
材质 polyhaven:https://polyhaven.com/hdris
图切:https://matheowis.github.io/HDRI-to-CubeMap/
在three.js中,材质决定了几何图形中的表面是如何画的。如果几何图形是骨架,定义了形状,那么材质就是皮肤。three.js 中有许多不同种类的材质,他们拥有不同的属性,像反光,纹理映射,调整透明度。
材质种类
网格基础材质(Basic Material)
最基本的材质是 MeshBasicMaterial。你能够把颜色color作为参...
反光效果Demo演示(因为是加载的模型,所以速度会慢)
(一)普通纹理
计算机图形学中的纹理既包括通常意义上物体表面的纹理即使物体表面呈现凹凸不平的沟纹,同时也包括在物体的光滑表面上的彩色图案,所谓的纹理映射就是在物体的表面上绘制彩色的图案。
在three.js中使用纹理可以实现很多...
好的,我会为您解答关于WebGL three.js的阴影与实现物体动画的问题。首先,让我们来了解一下WebGL three.js是什么。
WebGL three.js是一款基于WebGL的JavaScript 3D库,可以帮助我们快速搭建3D场景和应用。接下来我们来讲解阴影和实现物体动画的方法。
阴影是模拟物体之间的阴影效果,让3D场景更加真实。在three.js中,我们可以通过设置Mesh的castShadow和receiveShadow属性来实现阴影效果。
1. 首先,我们需要在场景中添加光源,例如SpotLight或DirectionalLight。
2. 然后,在需要投射阴影的物体上设置castShadow为true。
3. 最后,在需要接收阴影的物体上设置receiveShadow为true。
代码示例:
```javascript
// 添加光源
const light = new THREE.SpotLight(0xffffff);
light.position.set(0, 100, 0);
light.castShadow = true;
scene.add(light);
// 添加需要投射阴影的物体
const cube = new THREE.Mesh(new THREE.BoxGeometry(10, 10, 10), new THREE.MeshLambertMaterial({ color: 0xff0000 }));
cube.castShadow = true;
scene.add(cube);
// 添加需要接收阴影的物体
const plane = new THREE.Mesh(new THREE.PlaneGeometry(200, 200, 1, 1), new THREE.MeshLambertMaterial({ color: 0xffffff }));
plane.receiveShadow = true;
plane.rotation.x = -Math.PI / 2;
scene.add(plane);
二、物体动画
在three.js中,我们可以通过Tween.js库来实现物体的动画效果。Tween.js是一款JavaScript动画库,可以帮助我们实现非常丰富的动画效果。
1. 首先,我们需要在HTML文件中引入Tween.js库文件。
2. 然后,在需要动画的物体上设置初始状态。
3. 最后,通过Tween.js库来设置物体的目标状态和动画效果,例如缓动动画(ease)或弹跳动画(bounce)。
代码示例:
```javascript
// 引入Tween.js库文件
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/18.6.4/tween.min.js"></script>
// 添加需要动画的物体
const cube = new THREE.Mesh(new THREE.BoxGeometry(10, 10, 10), new THREE.MeshLambertMaterial({ color: 0xff0000 }));
cube.position.set(0, 0, 0);
scene.add(cube);
// 设置初始状态
const start = { x: 0, y: 0, z: 0 };
// 设置目标状态
const end = { x: 50, y: 50, z: 50 };
// 设置动画效果
const tween = new TWEEN.Tween(start)
.to(end, 1000)
.easing(TWEEN.Easing.Quadratic.InOut)
.onUpdate(() => {
cube.position.set(start.x, start.y, start.z);
.start();
以上是关于WebGL three.js阴影与实现物体动画的方法,希望能够对您有所帮助。
Yale Qi:
three.js学习笔记(十三)——真实渲染
Yale Qi: