| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- 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,
- })
- }
|