3.js - 鸡蛋托

3.js - 鸡蛋托_第1张图片


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轴(向上)方向,从而水平放置`  '【不旋转x轴,就看不到效果】'
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)*sin(modelPosition.z*uHumpDensity);
	
	elevation *= uScale;
	
	modelPosition.y += elevation;
	
	// 计算顶点在裁剪空间中的位置,gl_Position,是GLSL内置的输出变量,用于存储顶点的最终位置
	gl_Position = projectionMatrix*viewMatrix*modelPosition;
}

fragment.glsl

precision lowp float;

void main() {
	gl_FragColor = vec4(1, 1, 0, 1);
}

你可能感兴趣的:(three.js,three.js)