threejs-d-5.0

threejs-d-5.0

一、置换与置换贴图

.displacementMap : Texture

位移贴图会影响网格顶点的位置,与仅影响材质的光照和阴影的其他贴图不同,移位的顶点可以投射阴影,阻挡其他对象, 以及充当真实的几何体。位移纹理是指:网格的所有顶点被映射为图像中每个像素的值(白色是最高的),并且被重定位。

.displacementScale : Float

位移贴图对网格的影响程度(黑色是无位移,白色是最大位移)。如果没有设置位移贴图,则不会应用此值。默认值为1。

//main.js+
const textureLoader = new THREE.TextureLoader();
const mbColortexture = textureLoader.load('./texture/road_with_tram_rails_24_71_diffuse.jpg') 
const mbHeighttexture = textureLoader.load('./texture/road_with_tram_rails_24_71_height.jpg') 
mbColortexture.wrapS = THREE.RepeatWrapping
mbColortexture.wrapT = THREE.RepeatWrapping
mbColortexture.center.set(0.5,0.5)
// mbColortexture.rotation = Math.PI / 4
const geometry = new THREE.BoxGeometry( 1, 1, 1,100,100,100 );
const material = new THREE.MeshStandardMaterial( { 
    color: '#ffffff',
    map:mbColortexture,
    displacementMap:mbHeighttexture,
    displacementScale:0.05

 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

置换效果图:

二、粗糙度与粗糙度贴图

.roughness : Float

材质的粗糙程度。0.0表示平滑的镜面反射,1.0表示完全漫反射。默认值为1.0。如果还提供roughnessMap,则两个值相乘。

.roughnessMap : Texture

该纹理的绿色通道用于改变材质的粗糙度。

//main.js+
const textureLoader = new THREE.TextureLoader();
const mbColortexture = textureLoader.load('./texture/road_with_tram_rails_24_71_diffuse.jpg') 
const mbHeighttexture = textureLoader.load('./texture/road_with_tram_rails_24_71_height.jpg') 
const mbRoughnesstexture = textureLoader.load('./texture/road_with_tram_rails_24_71_roughness.jpg') 
mbColortexture.wrapS = THREE.RepeatWrapping
mbColortexture.wrapT = THREE.RepeatWrapping
mbColortexture.center.set(0.5,0.5)
// mbColortexture.rotation = Math.PI / 4
const geometry = new THREE.BoxGeometry( 1, 1, 1,50,50,50 );
const material = new THREE.MeshStandardMaterial( { 
    color: '#ffffff',
    map:mbColortexture,
    displacementMap:mbHeighttexture,
    displacementScale:0.05,
    // roughness:0,
    roughnessMap:mbRoughnesstexture

 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

粗糙度为0效果:

加载粗糙度纹理:

三、金属度与金属贴图

.metalness : Float

材质与金属的相似度。非金属材质,如木材或石材,使用0.0,金属使用1.0,通常没有中间值。 默认值为0.0。0.0到1.0之间的值可用于生锈金属的外观。如果还提供了metalnessMap,则两个值相乘。

.metalnessMap : Texture

该纹理的蓝色通道用于改变材质的金属度。

//main.js+
const textureLoader = new THREE.TextureLoader();
const mbColortexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_diffuse.jpg') 
const mbHeighttexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_height.jpg') 
const mbRoughnesstexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_roughness.jpg') 
const mbMetalnesstexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_metalness.jpg') 

mbColortexture.wrapS = THREE.RepeatWrapping
mbColortexture.wrapT = THREE.RepeatWrapping
mbColortexture.center.set(0.5,0.5)
// mbColortexture.rotation = Math.PI / 4
const geometry = new THREE.PlaneGeometry( 1, 1,100,100 );
const material = new THREE.MeshStandardMaterial( { 
    color: '#ffffff',
    map:mbColortexture,
    displacementMap:mbHeighttexture,
    displacementScale:0.05,
    roughness:0.2,
    roughnessMap:mbRoughnesstexture,
    metalnessMap:mbMetalnesstexture,
    metalness:0.3

 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

添加金属和金属贴图前:

添加金属和金属贴图后:

四、法线和法线贴图

.normalMap : Texture

用于创建法线贴图的纹理。RGB值会影响每个像素片段的曲面法线,并更改颜色照亮的方式。法线贴图不会改变曲面的实际形状,只会改变光照。 In case the material has a normal map authored using the left handed convention, the y component of normalScale should be negated to compensate for the different handedness.

.normalMapType : Integer

法线贴图的类型。

选项为THREE.TangentSpaceNormalMap(默认)和THREE.ObjectSpaceNormalMap。

.normalScale : Vector2

法线贴图对材质的影响程度。典型范围是0-1。默认值是Vector2设置为(1,1)

//main.js+
const textureLoader = new THREE.TextureLoader();
const mbColortexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_diffuse.jpg') 
const mbHeighttexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_height.jpg') 
const mbRoughnesstexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_roughness.jpg') 
const mbMetalnesstexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_metalness.jpg') 
const mbNormaltexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_normal.jpg') 

mbColortexture.wrapS = THREE.RepeatWrapping
mbColortexture.wrapT = THREE.RepeatWrapping
mbColortexture.center.set(0.5,0.5)
// mbColortexture.rotation = Math.PI / 4
const geometry = new THREE.PlaneGeometry( 1, 1,100,100 );
const material = new THREE.MeshStandardMaterial( { 
    color: '#ffffff',
    map:mbColortexture,
    displacementMap:mbHeighttexture,
    displacementScale:0.05,
    roughness:0.2,
    roughnessMap:mbRoughnesstexture,
    metalnessMap:mbMetalnesstexture,
    metalness:0.3,
    normalMap:mbNormaltexture

 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

添加法线贴图后:

贴图到这里就已经很逼真了,当然,不同的材质所使用的贴图也有一定的区别。

五、纹理加载回调

1.纹理回调

.load ( url : String, onLoad : Function, onProgress : Function, onError : Function ) : Texture

url — 文件的URL或者路径,也可以为 Data URI.
onLoad — 加载完成时将调用。回调参数为将要加载的texture.
onProgress — 将在加载过程中进行调用。参数为XMLHttpRequest实例,实例包含total和loaded字节。
onError — 在加载错误时被调用。

//main.js+
const textureLoader = new THREE.TextureLoader();
const mbColortexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_diffuse.jpg') 
const mbHeighttexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_height.jpg') 
const mbRoughnesstexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_roughness.jpg') 
const mbMetalnesstexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_metalness.jpg') 
const event = {};
event.onLoad = function(e){
    console.log('加载完成了')
}
event.onProgress = function(e){
    console.log(e)
    console.log('正在加载')
}
event.onError = function(e){
    console.log('加载错误了')
    console.log(e)
}
const mbNormaltexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_normal.jpg',
event.onLoad,//加载完成调用
event.onProgress,//加载过程中调用
event.onError//加载错误调用
) 

mbColortexture.wrapS = THREE.RepeatWrapping
mbColortexture.wrapT = THREE.RepeatWrapping
mbColortexture.center.set(0.5,0.5)
// mbColortexture.rotation = Math.PI / 4
const geometry = new THREE.PlaneGeometry( 1, 1,100,100 );
const material = new THREE.MeshStandardMaterial( { 
    color: '#ffffff',
    map:mbColortexture,
    displacementMap:mbHeighttexture,
    displacementScale:0.05,
    roughness:0.2,
    roughnessMap:mbRoughnesstexture,
    metalnessMap:mbMetalnesstexture,
    metalness:0.3,
    normalMap:mbNormaltexture

 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

加载中

onProgress

加载完成

onLoad

加载错误

onError

2.纹理加载器

其功能是处理并跟踪已加载和待处理的数据,管理我们加载的纹理

//main.js+
const event = {};
event.onLoad = function(e){
    console.log('加载完成了')
}
event.onProgress = function( url,itemsLoaded,itemsTotal){
    console.log('url:'+ url)//当前加载纹理路径
    console.log('itemsLoaded:' + itemsLoaded )//加载当前纹理位置
    console.log('itemsTotal:' + itemsTotal)//纹理总数
    console.log('加载角度:' + ((itemsLoaded / itemsTotal) * 100).toFixed(2) + '%')//纹理加载进度
}
event.onError = function(e){
    console.log('加载错误了')
    console.log(e)
}
const manager = new THREE.LoadingManager(
    event.onLoad,
    event.onProgress,
    event.onError
    );

const textureLoader = new THREE.TextureLoader(manager);//装载加载器
const mbColortexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_diffuse.jpg') 
const mbHeighttexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_height.jpg') 
const mbRoughnesstexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_roughness.jpg') 
const mbMetalnesstexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_metalness.jpg') 
const mbNormaltexture = textureLoader.load('./texture/welded_and_painted_metal_panels_26_64_normal.jpg') 
mbColortexture.wrapS = THREE.RepeatWrapping
mbColortexture.wrapT = THREE.RepeatWrapping
mbColortexture.center.set(0.5,0.5)
// mbColortexture.rotation = Math.PI / 4
const geometry = new THREE.PlaneGeometry( 1, 1,100,100 );
const material = new THREE.MeshStandardMaterial( { 
    color: '#ffffff',
    map:mbColortexture,
    displacementMap:mbHeighttexture,
    displacementScale:0.05,
    roughness:0.2,
    roughnessMap:mbRoughnesstexture,
    metalnessMap:mbMetalnesstexture,
    metalness:0.3,
    normalMap:mbNormaltexture

 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

六、环境纹理

创建一个由6张图片所组成的纹理对象。

(前后,上下,左右)也可以是 hdr(一张图)

const loader = new THREE.CubeTextureLoader();
loader.setPath( 'textures/cube/pisa/' );

const textureCube = loader.load( [
    'px.png', 'nx.png',
    'py.png', 'ny.png',
    'pz.png', 'nz.png'
] );
const material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube } );
scene.background = textureCube;
scene.environment = textureCube;//若该值不为null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。 然而,该属性不能够覆盖已存在的、已分配给 MeshStandardMaterial.envMap 的贴图

七、HDR

HDR

那么我们也是要知道如何加载hdr

高动态范围成像(英語:High Dynamic Range Imaging,简称HDRIHDR),在计算机图形学与电影摄影术中,是用来实现比普通数位图像技术更大曝光动态范围(即更大的明暗差别)的一组技术。高动态范围成像的目的就是要正确地表示真实世界中从太阳光直射到最暗的阴影这样大的范围亮度。

.mapping : number

图像将如何应用到物体(对象)上。默认值是THREE.UVMapping对象类型, 即UV坐标将被用于纹理映射。

EquirectangularReflectionMapping 和 EquirectangularRefractionMapping 用于等距圆柱投影的环境贴图,也被叫做经纬线映射贴图。等距圆柱投影贴图表示沿着其水平中线360°的视角,以及沿着其垂直轴向180°的视角。贴图顶部和底部的边缘分别对应于它所映射的球体的北极和南极。

//main.js+
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'
const rgbeLoader = new RGBELoader();
rgbeLoader.loadAsync('./texture/ruin1.hdr').then((texture)=>{
    texture.mapping = THREE.EquirectangularReflectionMapping;
    scene.background = texture;
    scene.environment = texture;
})
const geometry = new THREE.SphereGeometry( 15, 100, 50 );
const material = new THREE.MeshStandardMaterial( { 
    color: '#ffffff',
    metalness:0.5,
    roughness:0.05
 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );

八、灯光与阴影

阴影需要满足的条件

1.材质应满足对灯光有反应(环境光由于是四面八方的光,所以不具备阴影的条件)

2.渲染器开启阴影计算:renderer.shadowMap.enabled = true

3.光照投射阴影:light.castShadow = true

4.物体投射阴影:cube.castShadow = true(投影主体)

5.物体接收投射阴影:plane.receiveShadow = true(接收主体)

//main.js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls' 
import dat from 'dat.gui'

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;//渲染器开启阴影计算
document.body.appendChild( renderer.domElement );

const axesHelper = new THREE.AxesHelper( 30 );//轴的线段长度. 默认为 1.
scene.add( axesHelper );//添加到场景


const geometry = new THREE.SphereGeometry( 15, 100, 50 );
const material = new THREE.MeshStandardMaterial();
const cube = new THREE.Mesh( geometry, material );
cube.castShadow = true;//物体投射阴影
scene.add( cube );

const geometryP = new THREE.PlaneGeometry( 100,100 );
const materialP = new THREE.MeshStandardMaterial();
const plane = new THREE.Mesh( geometryP, materialP );
plane.rotation.x = -Math.PI / 2
plane.position.set(0,-15,0)
plane.receiveShadow = true//物体接收投射阴影
scene.add( plane );

const light = new THREE.PointLight( 0xffffff, 1, 100 );
light.position.set( 10, 50, 10 );
light.castShadow = true;//光照投射阴影
scene.add( light ); 

const gui = new dat.GUI();
gui.add(light.position,'x')
.min(0)
.max(30)
.name('移动x坐标')
.step(0.1)
gui.add(light.position,'y')
.min(0)
.max(30)
.name('移动y坐标')
.step(0.1)
gui.add(light.position,'z')
.min(0)
.max(30)
.name('移动z坐标')
.step(0.1)
const controls = new OrbitControls( camera,renderer.domElement  );
camera.position.set(0,20,100);
controls.update();
function animate() {
    requestAnimationFrame( animate );
    controls.update();
    renderer.render( scene, camera );
}
animate();

window.addEventListener('resize',()=>{
    // console.log('屏幕变化了')
    camera.aspect = window.innerWidth/window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth,window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
})

总结:

我们还有一些灯光,例如点光源和聚光灯,它们的属性我们就不一一来讲了,相信我们到了这,文档已经可以比较熟悉的查阅了。加油!!!

参考文档:

[HDR讲解]: “https://zh.m.wikipedia.org/zh/%E9%AB%98%E5%8A%A8%E6%80%81%E8%8C%83%E5%9B%B4%E6%88%90%E5%83%8F"

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2022-2023 alan_mf
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信