rimFlow.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import * as THREE from 'three'
  2. /**
  3. * 创建瀑布流光材质
  4. * - 结合纹理沿 Y 轴流动 + Fresnel 边缘光
  5. * - 用于 "di" 部件的边缘流光效果
  6. */
  7. export function createRimFlowMaterial(): THREE.ShaderMaterial {
  8. const textureLoader = new THREE.TextureLoader()
  9. const pubuTex = textureLoader.load('/assets/pubu.jpeg')
  10. pubuTex.wrapS = THREE.RepeatWrapping
  11. pubuTex.wrapT = THREE.RepeatWrapping
  12. pubuTex.repeat.set(1, 3)
  13. return new THREE.ShaderMaterial({
  14. uniforms: {
  15. uTime: { value: 0 },
  16. uColor: { value: new THREE.Color(0x00ccff) },
  17. uIntensity: { value: 1.0 },
  18. uSpeed: { value: 0.08 },
  19. uTexture: { value: pubuTex },
  20. },
  21. vertexShader: `
  22. varying vec3 vNormal;
  23. varying vec3 vViewDir;
  24. varying vec3 vWorldPos;
  25. varying vec2 vUv;
  26. void main() {
  27. vec4 worldPos = modelMatrix * vec4(position, 1.0);
  28. vWorldPos = worldPos.xyz;
  29. vNormal = normalize(normalMatrix * normal);
  30. vViewDir = normalize(cameraPosition - worldPos.xyz);
  31. vUv = uv;
  32. gl_Position = projectionMatrix * viewMatrix * worldPos;
  33. }
  34. `,
  35. fragmentShader: `
  36. uniform vec3 uColor;
  37. uniform float uTime;
  38. uniform float uIntensity;
  39. uniform float uSpeed;
  40. uniform sampler2D uTexture;
  41. varying vec3 vNormal;
  42. varying vec3 vViewDir;
  43. varying vec2 vUv;
  44. varying vec3 vWorldPos;
  45. void main() {
  46. // Fresnel 边缘检测
  47. float rim = 1.0 - max(dot(vNormal, vViewDir), 0.0);
  48. rim = pow(rim, 2.5);
  49. // UV 沿 Y 轴流动(瀑布下落)
  50. vec2 flowUv = vUv;
  51. flowUv.y += uTime * uSpeed;
  52. // 采样贴图
  53. vec4 texColor = texture2D(uTexture, flowUv);
  54. float flow = texColor.r;
  55. // 不透明,流动区域亮蓝色
  56. vec3 baseColor = vec3(0.02, 0.05, 0.12);
  57. vec3 glowColor = uColor;
  58. vec3 finalColor = mix(baseColor, glowColor, flow * 0.8);
  59. gl_FragColor = vec4(finalColor, 1.0);
  60. }
  61. `,
  62. transparent: false,
  63. side: THREE.DoubleSide,
  64. })
  65. }