相关文章推荐
狂野的橡皮擦  ·  ThreeJS ...·  2 周前    · 
买醉的草稿本  ·  curl查看请求头-掘金·  1 年前    · 
正直的皮蛋  ·  Oops!!! - 简书·  1 年前    · 
八块腹肌的白开水  ·  Python - 从 aspx ...·  1 年前    · 

基础网格材质 MeshBasicMaterial

初始化基础网格材质 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)

map属性可以为材质设置其纹理贴图

const material = new THREE.MeshBasicMaterial({map:doorColorTexture})

或者这样写

const material = new THREE.MeshBasicMaterial()
material.map = doorColorTexture

color属性可以在实例化材质时设置材质颜色

// 材质颜色设置红色
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')

颜色和纹理可以结合起来
在这里插入图片描述

opacity属性设置材质透明度

若想设置材质透明,则必须开启透明度效果,设置.transparent属性为true

material.transparent = true
material.opacity = 0.5	

alphaMap属性设置alpha贴图

//alphaMap属性同样需要开启transparent属性
material.transparent = true
material.alphaMap = doorAlphaTexture

什么是alpha贴图?

简单来讲,alpha贴图白色区域是可见的,黑色区域将被隐藏起来在这里插入图片描述
我们可以把alpha贴图和其他纹理贴图结合起来
在这里插入图片描述

side属性设置渲染哪一面

material.side = THREE.FrontSide   //正面 (默认)
material.side = THREE.BackSide	  //背面
material.side = THREE.DoubleSide  //双面都渲染

其中一些属性(如线框或不透明度)可用于其他类型的材质

法线网格材质MeshNormalMaterial

它是一种把法向量映射到RGB颜色的材质。

const material = new THREE.MeshNormalMaterial()

如果你改变下图摄像机位置,可以观察到物体颜色会有所不同。
法线可以用于照明、反射与折射等。
在这里插入图片描述

法线网格材质和基础网格材质拥有一些共同属性

transparentopacityside这三个属性都是所有材质共有的属性

flatShading属性

其定义材质是否使用平面着色进行渲染。

material.flatShading = true

可以观察到非平面物体表面不再那么光滑了。
在这里插入图片描述

法线网格材质通常被用于调试法线

但由于颜色纷呈,所以也可以试着运用到项目中

网帽材质MeshMatcapMaterial

网帽材质(MeshMatcapMaterial)将通过使用法线作为参照来在看起来像球体的纹理上拾取正确的颜色来显示颜色

const material = new THREE.MeshMatcapMaterial()

我们将网帽材质的matcap属性设置为下图matcap纹理贴图

material.matcap = matcapsTexture

在这里插入图片描述
查看渲染效果,我们会有一种错觉,感觉物体被照亮了一样。因此网帽材质的作用就是在场景没有光源的情况下,模拟出物体被光照的效果
在这里插入图片描述
在这里插入图片描述

网帽材质贴图获取网站

深度网格材质MeshDepthMaterial

如果几何体接近摄影机的“near”值,它将简单地将几何体着色为白色,如果几何体越接近摄影机的“far”值,则将几何体着色为黑色。

const material = new THREE.MeshDepthMaterial()

下图为摄像机正常观察情况
在这里插入图片描述
下图为摄像机靠近圆环体的观察情况
在这里插入图片描述

Lambert网格材质MeshLambertMaterial

该材质对光线有反应

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网格材质MeshPhongMaterial

Phong网格材质与Lambert网格材质很相似,但是你可以仔细观察到上图中Lambert网格材质的球体表面有些像是线型一样的奇怪图案,而Phong网格材质的球体相对于前者这些图案不太明显,并且你还能看到Phong网格材质球体上光线的反射更为明亮。

在这里插入图片描述
我们可以通过shininess属性控制光线反射高亮程度,数值越高越闪亮,并通过specular属性控制反射的颜色

material.shininess = 100
material.specular = new THREE.Color('0xff0000')

Toon网格材质 MeshToonMaterial

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
// 因为我们的渐变纹理贴图的缩小滤镜minFilter属性使用了NearestFilter
// 所以我们可以为该纹理停用mipmapping,使得GPU不再处理其mip映射
gradientTexture.generateMipmaps = false

在这里插入图片描述
下图为5层渐变
在这里插入图片描述

标准网格材质MeshStandardMaterial

一种基于物理的渲染(PBR)的标准材质,该材质提供了比MeshLambertMaterial 或MeshPhongMaterial 更精确和逼真的结果,代价是计算成本更高。

metalness属性

材质与金属的相似度。非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。

roughness属性

材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。
以上两种属性可通过添加GUI面板改变数值进行观察

aoMap属性

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属性

位移贴图会影响网格顶点的位置。换句话说就是它可以移动顶点来创建浮雕。
为材质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属性

同样道理,还有metalnessMap属性和roughnessMap属性也一样可以设置相应纹理贴图,这样我们可以不必为整个几何体指定均匀的金属程度和粗糙度,而是变为局部改变。

// 为避免反射效果变得怪异,记得先把前面的metalness属性和roughness属性给重设为默认值
material.metalnessMap = doorMetalnessTexture
material.roughnessMap = doorRoughnessTexture

可以观察到整个木材表面非常光滑,铁锁位置粗糙
在这里插入图片描述

normalMap属性

用于创建法线纹理贴图的纹理。它将伪造法线方向,并在物体表面上添加细节。

material.normalMap = doorNormalTexture

在这里插入图片描述
可以观察到这个木门已经开始有点栩栩如生了
在这里插入图片描述
我们可以normalScale属性改变法线纹理贴图对材质的影响程度。典型范围是0-1。默认值是Vector2设置为(1,1)。

// 可以发现细节程度变小了
material.normalScale.set(0.5,0.5)

alphaMap属性

最后我们往材质中再设置alphaMap属性,添加alpha纹理贴图

material.alphaMap = doorAlphaTexture
// 使用alphaMAp记得开启transparent属性
material.transparent = true

终于有了一扇完整的看起来正常的门了
在这里插入图片描述

// 标准网格材质(MeshStandardMaterial)
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

物理网格材质MeshPhysicalMaterial与标准网格材质MeshStandardMaterial很相似,只不过物理网格材质具有清晰的涂层效果和更高级的基于物理的渲染属性,可以将其看作是标准网格材质的扩展

点材质PointsMaterial

我们可以用点材质创建粒子

环境贴图Environment maps

环境贴图是场景周围环境的图像。它可以用于反射或折射,也可以用于一般照明,支持多种材质。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',

设置envMap属性

material.envMap = environmentMapTexture

观察效果。可以通过设置metalness金属度和roughness粗糙度控制反射情况
在这里插入图片描述

//环境贴图environment map
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: 加载glsl的时候,vite,以字符串形式加载.glsl文件即可,即在文件后面加上“raw”参数即可: import basicVertextShader from './shader/basic/vertex.glsl?raw' import basicFragmentShader from './shader/basic/fragment.glsl?raw' three.js学习笔记(十三)——真实渲染 Yale Qi: THREE.GammaEncoding 属性还存在