Three Shader应用实例

基础环境搭建: 将官方文件夹下waternormal.jpg复制到textures文件夹下 创建Water模型: sun = new THREE.Vector3

基础环境搭建:

在这里插入图片描述

将官方文件夹下waternormal.jpg复制到textures文件夹下
创建Water模型:

    sun = new THREE.Vector3(0, 0, 0)water = new Water(new THREE.PlaneGeometry(10000, 10000),{waterNormals: new THREE.TextureLoader().load('textures/waternormals.jpg',function (texture) {texture.wrapS = texture.wrapT = THREE.RepeatWrapping}),sunDirection: sun,sunColor: 0xffffff,waterColor: 0x001e0f,})water.rotation.x = -Math.PI / 2scene.add(water)

在这里插入图片描述

渲染函数添加:

    water.material.uniforms['time'].value += 1.0 / 60.0

实现水纹(随时间变化)波动

创建天空模型:

    sky = new Sky()sky.scale.setScalar(10000)scene.add(sky)

将sky模型中材质的sunPosition属性值同sun位置关联:

    sky.material.uniforms['sunPosition'].value.copy(sun)

在这里插入图片描述

色调映射

THREE.ACESFilmicToneMapping
这些常量定义了WebGLRenderer中toneMapping的属性。 这个属性用于在普通计算机显示器或者移动设备屏幕等低动态范围介质上,模拟、逼近高动态范围(HDR)效果。

    renderer.toneMapping = THREE.ACESFilmicToneMapping

在这里插入图片描述

添加立方体对象:

    const geometry = new THREE.BoxGeometry(30, 30, 30)const material = new THREE.MeshStandardMaterial({ roughness: 0 })cube = new THREE.Mesh(geometry, material)scene.add(cube)

添加动作效果:

performance.now()方法返回一个精确到毫秒的表示为从time origin之后到当前调用时经过的时间 DOMHighResTimeStamp 。

    const time = window.performance.now() * 0.001cube.rotation.x = time * 0.5cube.position.y = Math.sin(time) * 20 + 5cube.rotation.z = time * 0.5

在这里插入图片描述

立方体表面添加光滑反射效果:

PMREMGenerator( renderer : WebGLRenderer )
这个类从一个cubeMap环境纹理生成一个预过滤的、Mipmapped Radiance Environment Map (PMREM)。这允许基于材料粗糙度快速访问不同级别的模糊。它被包装成一种特殊的CubeUV格式,允许我们执行自定义插值,从而支持RGBE等非线性格式。与传统的mipmap链不同,它只向下到LOD_MIN级别(上面),然后在相同的LOD_MIN分辨率下创建额外的更过滤的“mips”,与更高的粗糙度级别相关。通过这种方式,我们在限制采样计算的同时,保持了平滑插值漫射照明的分辨率。

.fromScene (scene: scene, sigma: Number, near: Number, far: Number): WebGLRenderTarget
scene—给定的场景。
sigma -(可选)指定一个以弧度为单位的模糊半径,应用于PMREM生成之前的场景。 默认值为0。
near -(可选)近平面值。 默认是0.1。
far -(可选)远平面值。 默认是100。
从提供的场景生成PMREM,如果网络带宽较低,这可能比使用映像更快。 可选的近面和远面确保场景是完整渲染的(cubeCamera被放置在原点)。

WebGLRenderTarget:render target是一个缓冲,就是在这个缓冲中,视频卡为正在后台渲染的场景绘制像素。它用于不同的效果,例如用于在一个图像显示在屏幕上之前先做一些处理。
.texture : Texture
纹理实例保存这渲染的像素,用作进一步处理的输入值

Scene.environment : Texture
若该值不为null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。 然而,该属性不能够覆盖已存在的、已分配给 MeshStandardMaterial.envMap 的贴图。默认为null。

	...pmremGenerator = new THREE.PMREMGenerator(renderer)...renderTarget = pmremGenerator.fromScene(sky)scene.environment = renderTarget.texture

在这里插入图片描述

创建GUI控制Sun位置及水面相关属性:
创建Sun位置控制器:
sun位置变量供GUI使用:

sunParams = {elevation: 2,//极角 theta角 纬度azimuth: -150//方位角 phi角 经度
}

MathUtils…degToRad ( degrees : Float ) : Float--------------将度转化为弧度。
Vector3.setFromSphericalCoords ( radius : Float, phi : Float, theta : Float ) : this------------------------------------从球坐标中的radius、phi和theta设置该向量。

球坐标(Spherical):一个点的spherical coordinates(球坐标)。
Spherical( radius : Float, phi : Float, theta : Float )
radius - 半径值,或者说从该点到原点的 Euclidean distance(欧几里得距离,即直线距离)。默认值为1.0。
phi - 与 y (up) 轴的极角(以弧度为单位)。默认值为 0。
theta - 绕 y (up) 轴的赤道角(方位角)(以弧度为单位)。默认值为 0。
极角(phi)位于正 y 轴和负 y 轴上。赤道角(方位角)(theta)从正 z 开始。

function buildGUI() {gui = new GUI()const skyFolder = gui.addFolder('SKY')skyFolder.add(sunParams, 'elevation', 0, 90, 0.1).onChange(updateSun)skyFolder.add(sunParams, 'azimuth', -180, 180, 0.1).onChange(updateSun)
}function updateSun() {const theta = THREE.MathUtils.degToRad(90 - sunParams.elevation)const phi = THREE.MathUtils.degToRad(sunParams.azimuth)sun.setFromSphericalCoords(1, theta, phi)sky.material.uniforms['sunPosition'].value.copy(sun)
}

在这里插入图片描述

创建Water属性控制器:

    let waterParams = water.material.uniformsconst waterFolder = gui.addFolder('WATER')waterFolder.add(waterParams.distortionScale, 'value', 0, 40, 0.1).name('distortionScale')waterFolder.add(waterParams.size, 'value', 0.1, 10, 0.1).name('size')

试着改下属性值观察变化:

    const skyUniforms = sky.material.uniformsskyUniforms['turbidity'].value = 10skyUniforms['rayleigh'].value = 2skyUniforms['mieCoefficient'].value = 0.005skyUniforms['mieDirectionalG'].value = 0.8

轨道控制器设置下:

    controls.maxPolarAngle = Math.PI * 0.495controls.minDistance = 40controls.maxDistance = 200

在这里插入图片描述