renderer.toneMappingExposure = 0.1
class SphereSky{
constructor(radius, uTime, envMap, nightMap){
const geometry = new THREE.SphereGeometry(radius, 32, 32)
const material = new THREE.MeshBasicMaterial({
map : envMap,
side : THREE.BackSide,
})
this.mesh = new THREE.Mesh(geometry, material)
this.mesh.rotation.y = - Math.PI / 2
}
material.onBeforeCompile = shader => {
shader.fragmentShader = shader.fragmentShader.replace(
'#include <dithering_fragment>',
'#include <dithering_fragment>
gl_FragColor = mix(vec4(0.0,0.0,0.0,1.0),gl_FragColor,0.1)
// 0,0,0,1.0为全黑,gl_FragColor为材质本色
'
)
addSun(){
let sunGeometry = new THREE.SphereGeometry(
100,
32,
32,
)
let sunMaterial = new THREE.MeshStandarMaterial({
emissive : 0xfffcc
})
this.sun = new THREE.Mesh(sunGeometry,sunMaterial)
this.sun.position.set(500,500,4000)
this.mesh.add(this.sun)
let sunLight = new THREE.DirectionLight(0xffffcc,2)
this.sun.add(sunLight)
sunLight.castShadow = true
sunLight.shadow.camera.near = 0.1
sunLight.shadow.camera.far = 100000
sunLight.shadow.camera.left = -10000
sunLight.shadow.camera.right = 10000
sunLight.shadow.camera.top = 1000
sunLight.shadow.camera.bottom = -1000
sunLight.shadow.mapSize.width = 20480
sunLight.shadow.mapSize.height = 20480
sunLIght.shadow.radius = 5
}
updateSun(time){
this.sun.position.z = Math.cos(((time - 6)* 2 * Math.PI) / 24) * 4000
this.sun.position.y = Math.sin(((time - 6) * 2 * Math.PI) / 24) * 4000
}
}
}
动态变化函数
let sphereSky = new SphereSky()
// gsap动态修改时间
let uTime = {
value : 0,
}
gsap.to(uTime,{
value : 24,
duration : 24,
repeat : -1,// 重复
ease : 'linear',
onUpdate
sphereSky.updateSun(uTime.value)
// 根据值来修改渲染器色调映射的值
if(uTime.value > 6){ / /大于六点就是早上
sphereSky.sun.visible =true
}
if(uTime.value > 18){ // 大于16点就是晚上
sphereSky.sun.visible = false // 隐藏太阳
}
if(Math.abs(uTime.value - 12) < 4){ // 8点到16点亮度不变
renderer.toneMappingExposure = 1
}
if(Math.abs(uTime.value - 12) >= 6){ // 18点以后亮度不变
renderer.toneMappingExposure = 0.3
}
// [0,8],[16,18]这两个区间亮度随强度变化
if(Math.abs(uTime.value - 12) >= 4 || Math.abs(uTime.value - 12) <= 6 ){
// [0,8] x越大,strength越大, [16,18]x越大,strength越小
let strength = 1 - Math.abs(uTime.value - 12) / 2
strength < 0.3 ? strength = 0.3 : strength = strength
renderer.toneMappingExposure = strength
}
})
添加太阳光光晕效果
const textureLoader = new THREE.TextureLoader()
const textureFlare0 = textureLoader.load()
const textureFlare1 = textureLoader.load()
const lensflare = new Lensflare()
lensflare.addElement(new LensflareElement(
textureFlare0,
700,
0,
))
lensflare.addElement(new LensflareElement(
textureFlare0,
500,
0.4,
))
lensflare.addElement(new LensflareElement(
textureFlare0,
300,
0.75,
))
lensflare.addElement(new LensflareElement(
textureFlare0,
150,
1,
))
sunLight.add(lensflare)
开启晚上led效果
// 获取led的材质
traverse(child => {
//声明一个变量存储led材质
let ledMaterial
if(child.isMesh &&
child.material.name == 'Led' &&
ledMaterial == null
){
ledMaterial = child.material
}
})
// 创建一个视屏材质
let video = document.createElement('video')
video.src = 'path'
video.autoplay = true
video.loop = true
video.muted = true
video.play()
let videoMaterial = new THREE.VideoTexture(video)
// 之前的发光效果 通道
this.unrealBloomPass = new UnrealBloomPass()
this.unrealBloomPass.enabled = false
this.unrealBloomPass.threshold = 0.25
this.unrealBloomPass.strength = 1
this.unrealBloomPass.radius = 2
// 早上的回调
() => {
ledMaterial.emissive = new THREE.Color(0x000000)
// 关闭发光效果通道
this.unrealBloomPass.enabled = false
}
// 夜晚的回调
() => {
ledMaterial.emissive = new THREE.Color(0x99cc99)
ledMaterial.emissiveMap = videoMaterial
ledMaterial.emissiveIntensity = 1
// 开启发光效果通道
this.unrealBloomPass.enabled = true
}
if(uTime.value > 6 && uTime.value <= 18 && !this.isDay){ / /大于六点并且小于十八点就是早上
sphereSky.sun.visible =true
this.isDay = true
dayCallback()
}
if((uTime.value > 18 || uTime.value < 6) && this.isDay){ // 大于18点或者小于6点就是晚上
sphereSky.sun.visible = false // 隐藏太阳
this.isDay = false
nightCallback()
}