乱
main.js
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import gsap from 'gsap'
import vertexShader from './shader/11-03/vertex.glsl?raw'
import fragmentShader from './shader/11-03/fragment.glsl?raw'
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(90, window.innerHeight / window.innerHeight, 0.1, 1000)
camera.position.set(0, 0, 2)
camera.aspect = window.innerWidth / window.innerHeight
scene.add(camera)
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)
`【loadAsync:异步加载hdr,返回一个Promise】`
const rgbeLoader = new RGBELoader()
rgbeLoader.loadAsync('../public/assets/2k.hdr').then(texture => {
texture.mapping = THREE.EquirectangularReflectionMapping
scene.background = texture
scene.environment = texture
})
`【着色器材质】`
const shaderMaterial = new THREE.ShaderMaterial({
vertexShader: vertexShader,
fragmentShader: fragmentShader,
side: THREE.DoubleSide,
})
`【加载灯笼的glb】`
const gltfLoader = new GLTFLoader()
gltfLoader.load('../public/assets/model/flyLight.glb', gltf => {
console.log('gltf=', gltf)
for (let i = 0; i < 150; i++) {
let flyLight = gltf.scene.clone(true)
flyLight.children[1].material = shaderMaterial
let x = (Math.random() - 0.5) * 300
let z = (Math.random() - 0.5) * 300
let y = Math.random() * 60 + 25
flyLight.position.set(x, y, z)
gsap.to(flyLight.rotation, {
y: 2 * Math.PI,
duration: 10 + Math.random() * 30,
repeat: -1
})
gsap.to(flyLight.position, {
x: '+=' + Math.random() * 5,
y: '+=' + Math.random() * 20,
duration: 5 + Math.random() * 10,
yoyo: true,
repeat: -1
})
scene.add(flyLight)
}
})
`【渲染器】`
const renderer = new THREE.WebGLRenderer({ alpha: true })
renderer.shadowMap.enabled = true
【最新版本属性名字有改变】:`renderer.outputEncoding`已经变更为`renderer.outputColorSpace`
renderer.outputColorSpace = THREE.SRGBColorSpace
renderer.toneMapping = THREE.ACESFilmicToneMapping
renderer.toneMappingExposure = 0.2
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
`【轨道控制器】`
const controls = new OrbitControls(camera, renderer.domElement)
controls.enableDamping = true
controls.autoRotate = true
controls.autoRotateSpeed = 0.1
`最大极角 == 最小极角:代表,相机会被锁定在这个角度上,无法上下移动(锁定相机镜头)`
controls.maxPolarAngle = (Math.PI / 3) * 2
controls.minPolarAngle = (Math.PI / 3) * 2
function animate() {
controls.update()
requestAnimationFrame(animate)
renderer.render(scene, camera)
}
animate()
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
})
vertex.glsl
precision lowp float;
varying vec4 vPosition;
varying vec4 gPosition;
void main() {
vec4 modelPosition = modelMatrix*vec4(position, 1.0);
vPosition = modelPosition;
gPosition = vec4(position, 1.0);
gl_Position = projectionMatrix*viewMatrix*modelPosition;
}
fragment.glsl
precision lowp float;
varying vec4 vPosition;
varying vec4 gPosition;
void main() {
vec4 redColor = vec4(1, 0, 0, 1);
vec4 yellowColor = vec4(1, 1, 0.5, 1);
vec4 mixColor = mix(yellowColor, redColor, gPosition.y/3.0);
if(gl_FrontFacing) {
gl_FragColor = vec4(mixColor.xyz-(vPosition.y-20.0)/80.0-0.1, 1);
} else {
gl_FragColor = vec4(mixColor.xyz, 1);
}
}