12.Materials 材质
介绍
材质用于为几何体的每个可见像素着色。
决定每个像素颜色的算法属于着色器中编写的。编写着色器是 WebGL 和 Three.js 最具挑战性的部分之一,但不要担心;Three.js 有许多带有预制着色器的内置材质。
我们将在以后的课程中探索如何创建我们自己的着色器。现在,让我们使用 Three.js 自带材料。
Setup 设置
启动器不包含任何对象。这是一个很好的机会来修改创建网格的基础知识。
准备我们的场景
为了测试材质,我们应该准备一个可爱的场景并加载一些纹理。
创建由 3 种不同几何体(一个球体、一个平面和一个环面)组成的 3 个网格体,并在所有 3 个几何体上使用相同的 MeshBasicMaterial。是的,您可以在多个网格体上使用一种材质。移动左侧的球体和右侧的环面以将它们分开。
该add(...)
方法支持一次添加多个对象:
/**
* Objects
*/
const material = new THREE.MeshBasicMaterial()
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(0.5, 16, 16),
material
)
sphere.position.x = - 1.5
const plane = new THREE.Mesh(
new THREE.PlaneGeometry(1, 1),
material
)
const torus = new THREE.Mesh(
new THREE.TorusGeometry(0.3, 0.2, 16, 32),
material
)
torus.position.x = 1.5
scene.add(sphere, plane, torus)
tick我们现在可以像在动画课上那样在函数上旋转对象:
/**
* Animate
*/
const clock = new THREE.Clock()
const tick = () =>
{
const elapsedTime = clock.getElapsedTime()
// Update objects
sphere.rotation.y = 0.1 * elapsedTime
plane.rotation.y = 0.1 * elapsedTime
torus.rotation.y = 0.1 * elapsedTime
sphere.rotation.x = 0.15 * elapsedTime
plane.rotation.x = 0.15 * elapsedTime
torus.rotation.x = 0.15 * elapsedTime
// ...
}
tick()
你应该看到你的 3 个物体在缓慢旋转。
我们将要发现的材料以许多不同的方式使用纹理。让我们像在纹理课程中所做的那样使用TextureLoader加载一些纹理。
所有纹理图像都位于该/static/textures/
文件夹中。现在,我们将加载/static/textures/door/
文件夹中的所有门纹理、/static/textures/matcaps/
文件夹中的第一个 matcap 纹理和/static/textures/gradients/
文件夹中的第一个渐变纹理。
确保在material
实例化之前这样做:
/**
* Textures
*/
const textureLoader = new THREE.TextureLoader()
const doorColorTexture = textureLoader.load('/textures/door/color.jpg')
const doorAlphaTexture = textureLoader.load('/textures/door/alpha.jpg')
const doorAmbientOcclusionTexture = textureLoader.load('/textures/door/ambientOcclusion.jpg')
const doorHeightTexture = textureLoader.load('/textures/door/height.jpg')
const doorNormalTexture = textureLoader.load('/textures/door/normal.jpg')
const doorMetalnessTexture = textureLoader.load('/textures/door/metalness.jpg')
const doorRoughnessTexture = textureLoader.load('/textures/door/roughness.jpg')
const matcapTexture = textureLoader.load('/textures/matcaps/1.png')
const gradientTexture = textureLoader.load('/textures/gradients/3.jpg')
为确保所有纹理都加载良好,您可以使用属性在材质上使用它们map
,正如我们在纹理课程中看到的那样。
const material = new THREE.MeshBasicMaterial({ map: doorColorTexture })
到目前为止,我们只使用了 MeshBasicMaterial ,它在我们的几何体上应用了统一的颜色或纹理。
如果您在Three.js 文档中搜索“material” ,您会发现有很多我们可以使用的类。让我们都试试看。
网格基础材质
MeshBasicMaterial可能是最“基本”的材质……但是还有很多我们还没有涉及的属性。
您可以在MeshBasicMaterial实例化前,材质参数传入的对象中设置其中的大部分属性,但您也可以直接在实例上更改这些属性:
const material = new THREE.MeshBasicMaterial({
map: doorColorTexture
})
// Equals
const material = new THREE.MeshBasicMaterial()
material.map = doorColorTexture
我们将使用第二种方法,但您可以随意使用。
map 地图
该map
属性将在几何体表面应用纹理:
material.map = doorColorTexture
color 颜色
该color
属性将在几何体表面应用统一的颜色。当您直接更改color
属性时,您必须实例化一个Color类。您可以使用许多不同的格式:
material.color = new THREE.Color('#ff0000')
material.color = new THREE.Color('#f00')
material.color = new THREE.Color('red')
material.color = new THREE.Color('rgb(255, 0, 0)')
material.color = new THREE.Color(0xff0000)
结合color
和map
用颜色为纹理着色:
material.map = doorColorTexture
material.color = new THREE.Color('#ff0000')
wireframe 线框
无论相机的距离如何,该wireframe
属性都会用 1px 的细线显示构成几何体的三角形:
material.wireframe = true
opacity 不透明度
该opacity
属性控制透明度,但要正常工作,您应该将transparent
属性设置为true
以通知 Three.js 此材质现在支持透明度:
material.transparent = true
material.opacity = 0.5
alphaMap 阿尔法地图
现在透明度开始工作了,我们可以使用该alphaMap
属性来控制纹理的透明度:
material.transparent = true
material.alphaMap = doorAlphaTexture
side 边
该side
属性可让您决定面部的哪一侧可见。默认情况下,正面是可见的 ( THREE.FrontSide
),但您可以改为显示背面 ( THREE.BackSide
) 或同时显示背面 ( THREE.DoubleSide
):
material.side = THREE.DoubleSide
您应该看到曲面的的正面和背面。
尽量避免使用**THREE.DoubleSide**
因为渲染两侧意味着要渲染两倍以上的三角形。
其中一些属性类似于wireframe
或opacity
可以与其他类型的材料一起使用。我们不会每次都重复这些。
MeshNormalMaterial 网格法线材质
MeshNormalMaterial显示漂亮的紫色、蓝色、绿色,看起来像我们在纹理课程中看到的法线纹理。这并非巧合,因为两者都与我们所说的法线有关:
const material = new THREE.MeshNormalMaterial()
法线是在每个顶点中编码的信息,包含面部外侧的方向。如果将这些法线显示为箭头,您会得到从组成几何体的每个顶点出来的直线。
您可以将法线用于许多事情,例如计算如何照亮面部或环境应如何在几何体表面反射或折射。
使用MeshNormalMaterial时,颜色将仅显示法线相对于相机的方向。如果围绕球体旋转,您会发现颜色始终相同,无论您正在查看球体的哪个部分。
虽然您可以使用我们在MeshBasicMaterial中发现的一些属性,例如wireframe、transparent、opacity和side,但您还可以使用一个新属性,称为:flatShading
material.flatShading = true
flatShading
将使面变平,这意味着法线不会在顶点之间进行插值。
MeshNormalMaterial可用于调试法线,但它看起来也很棒,您可以像 ilithya 在她的作品集https://www.ilithya.rocks上所做的那样使用它。
MeshMatcap材质
MeshMatcapMaterial是一种很棒的材料,因为它看起来很棒,同时又非常高效。
为了使其工作,MeshMatcapMaterial需要一个看起来像球体的参考纹理。
然后材质将根据相对于相机的法线方向在纹理上拾取颜色。
要设置该参考 matcap 纹理,请使用以下matcap
属性:
const material = new THREE.MeshMatcapMaterial()
material.matcap = matcapTexture
网格看起来会被照亮,并且反射光泽,但它只是一个看起来像金属的纹理。
唯一的问题是无论相机方向如何,错觉都是一样的。此外,您无法更新灯光,因为没有灯光。
尝试文件夹上可用的不同纹理/static/textures/matcaps/(只是下面一行之一):
const matcapTexture = textureLoader.load('/textures/matcaps/2.png')
const matcapTexture = textureLoader.load('/textures/matcaps/3.png')
const matcapTexture = textureLoader.load('/textures/matcaps/4.png')
const matcapTexture = textureLoader.load('/textures/matcaps/5.png')
const matcapTexture = textureLoader.load('/textures/matcaps/6.png')
const matcapTexture = textureLoader.load('/textures/matcaps/7.png')
const matcapTexture = textureLoader.load('/textures/matcaps/8.png')
关于在哪里可以找到 matcaps 纹理,您可以像任何类型的纹理一样在网络上进行简单的搜索。如果不是供个人使用,请确保您有权使用该纹理。还有这个庞大的 matcaps 列表:https
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)