不旋转x轴的时候
手拖动一下,看看不同角度的
x轴旋转90度的时候
uScale 控制 驼峰的高度(规模)
uHumpDensity控制驼峰的密度(驼峰的数量)
uHumpDensity控制驼峰的密度(驼峰的数量),图片中的注释,写错了,应该是
uHumpDensity 控制 驼峰的密度,
这是值为1的时候,就是个平面,没有一点驼峰,
值越大,驼峰越多
main.js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js'
// @ts-ignore
import basicVertexShader from './shader/12/raw/vertex.glsl?raw'
// @ts-ignore
import basicFragmentShader from './shader/12/raw/fragment.glsl?raw'
const gui = new GUI()
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 2)
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
// --------------------------------------------------------------------
const params = {
uHumpDensity: 14, // 驼峰的密度
uScale: 0.1 // 驼峰的高度(规模)
}
const planeGeometry = new THREE.PlaneGeometry(1, 1, 1024, 1024)
const shaderMaterial = new THREE.ShaderMaterial({
vertexShader: basicVertexShader,
fragmentShader: basicFragmentShader,
side: THREE.DoubleSide,
transparent: true,
uniforms: {
uTime: {
value: 0
},
uHumpDensity: {
value: params.uHumpDensity
},
uScale: {
value: params.uScale
}
}
})
const plane = new THREE.Mesh(planeGeometry, shaderMaterial)
// 将平面,绕X轴旋转90度,使其垂直于Y轴(向上)方向,从而水平放置
// plane.rotation.x = Math.PI / 2
scene.add(plane)
// 驼峰的密度
gui
.add(params, 'uHumpDensity')
.min(1)
.max(50)
.step(1)
.onChange(value => {
shaderMaterial.uniforms.uHumpDensity.value = value
})
// 驼峰的高度(规模)
gui
.add(params, 'uScale')
.min(0)
.max(0.8)
.step(0.01)
.onChange(value => {
shaderMaterial.uniforms.uScale.value = value
})
// --------------------------------------------------------------------
//#region
const renderer = new THREE.WebGLRenderer({ antialias: true })
// renderer.shadowMap.enabled = true
renderer.toneMapping = THREE.ReinhardToneMapping
renderer.toneMappingExposure = 1
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
const clock = new THREE.Clock()
const render = () => {
// 获取,自Clock对象创建以来,经过的秒数
const elapsedTime = clock.getElapsedTime()
// 色器中的uTime变量,就会随着时间的推移而更新
shaderMaterial.uniforms.uTime.value = elapsedTime
controls.update()
requestAnimationFrame(render)
renderer.render(scene, camera)
}
render()
window.addEventListener('resize', () => {
// 重置相机的宽高比
camera.aspect = window.innerWidth / window.innerHeight
// 更新相机的投影矩阵
camera.updateProjectionMatrix()
// 重置渲染器的宽高比
renderer.setSize(window.innerWidth, window.innerHeight)
// 更新渲染器的像素比
renderer.setPixelRatio(window.devicePixelRatio)
})
//#endregion
vertex.glsl
precision lowp float;
uniform float uTime;
uniform float uHumpDensity;
uniform float uScale;
void main() {
vec4 modelPosition = modelMatrix*vec4(position, 1.0);
float elevation = sin(modelPosition.x*uHumpDensity);
`这是鸡蛋托的效果`
// float elevation = sin(modelPosition.x*uHumpDensity)*sin(modelPosition.z*uHumpDensity);
elevation *= uScale;
modelPosition.y += elevation;
// 计算顶点在裁剪空间中的位置,gl_Position,是GLSL内置的输出变量,用于存储顶点的最终位置
gl_Position = projectionMatrix*viewMatrix*modelPosition;
}
fragment.glsl
precision lowp float;
uniform vec3 uHighColor;
uniform vec3 uLowColor;
uniform float uOpacity;
void main() {
gl_FragColor = vec4(1, 1, 0, 1);
}