import * as THREE from 'three' /** * 创建瀑布流光材质 * - 结合纹理沿 Y 轴流动 + Fresnel 边缘光 * - 用于 "di" 部件的边缘流光效果 */ export function createRimFlowMaterial(): THREE.ShaderMaterial { const textureLoader = new THREE.TextureLoader() const pubuTex = textureLoader.load('/assets/pubu.jpeg') pubuTex.wrapS = THREE.RepeatWrapping pubuTex.wrapT = THREE.RepeatWrapping pubuTex.repeat.set(1, 3) return new THREE.ShaderMaterial({ uniforms: { uTime: { value: 0 }, uColor: { value: new THREE.Color(0x00ccff) }, uIntensity: { value: 1.0 }, uSpeed: { value: 0.08 }, uTexture: { value: pubuTex }, }, vertexShader: ` varying vec3 vNormal; varying vec3 vViewDir; varying vec3 vWorldPos; varying vec2 vUv; void main() { vec4 worldPos = modelMatrix * vec4(position, 1.0); vWorldPos = worldPos.xyz; vNormal = normalize(normalMatrix * normal); vViewDir = normalize(cameraPosition - worldPos.xyz); vUv = uv; gl_Position = projectionMatrix * viewMatrix * worldPos; } `, fragmentShader: ` uniform vec3 uColor; uniform float uTime; uniform float uIntensity; uniform float uSpeed; uniform sampler2D uTexture; varying vec3 vNormal; varying vec3 vViewDir; varying vec2 vUv; varying vec3 vWorldPos; void main() { // Fresnel 边缘检测 float rim = 1.0 - max(dot(vNormal, vViewDir), 0.0); rim = pow(rim, 2.5); // UV 沿 Y 轴流动(瀑布下落) vec2 flowUv = vUv; flowUv.y += uTime * uSpeed; // 采样贴图 vec4 texColor = texture2D(uTexture, flowUv); float flow = texColor.r; // 不透明,流动区域亮蓝色 vec3 baseColor = vec3(0.02, 0.05, 0.12); vec3 glowColor = uColor; vec3 finalColor = mix(baseColor, glowColor, flow * 0.8); gl_FragColor = vec4(finalColor, 1.0); } `, transparent: false, side: THREE.DoubleSide, }) }