🎯 提示词

PROMPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
使用 Three.js 实现【内发光效果】,具体要求:

【核心特效】
- 菲涅尔反射实现边缘发光
- 平面径向发光效果
- 透明渐变边缘

【场景与光照】
- 深灰色背景
- 无光源(自发光材质)

【交互与控制】
- OrbitControls 轨道控制器

【技术要求】
- Three.js 最新版本
- ShaderMaterial 自定义着色器
- 菲涅尔反射公式

📖 效果拆解

层次 视觉效果 技术实现
基础 球体模型 SphereGeometry
核心特效 菲涅尔边缘发光 法线与视线点积计算
增强细节 平面径向发光 距离场发光算法
辅助 坐标轴辅助 AxesHelper

🔧 核心技术点

1. 菲涅尔反射公式

通过计算法线向量与视线方向的点积,实现边缘发光效果。

GLSL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
uniform vec3 uColor;
uniform float uBias;
uniform float uPower;
uniform float uScale;

varying vec3 vNormal;
varying vec3 vPositionNormal;

float fresnelReflex() {
    return pow(uBias + uScale * abs(dot(vNormal, vPositionNormal)), uPower);
}

void main() {
    float opacity = fresnelReflex();
    gl_FragColor = vec4(uColor, opacity);
}

2. 视图空间法线计算

在顶点着色器中将法线转换到视图空间,便于后续计算。

GLSL
1
2
3
4
5
6
7
8
9
10
varying vec3 vNormal;
varying vec3 vPositionNormal;

void main() {
  // 视图空间下的单位法线向量
  vNormal = normalize(normalMatrix * normal);
  // 视图空间下的单位坐标向量
  vPositionNormal = normalize((modelViewMatrix * vec4(position, 1.0)).xyz);
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

3. 平面径向发光

使用距离场算法实现平面上的径向发光效果。

GLSL
1
2
3
4
5
6
7
8
float glow(vec2 coord, float radius, float intensity) {
  return pow(radius / length(coord), intensity);
}

void main() {
  float ratio = glow(vUV - vec2(0.5), 0.1, 3.0);
  gl_FragColor = vec4(uColor * ratio, ratio);
}

💡 调试与优化

问题类型 表现形式 解决方案
发光效果不明显 边缘没有发光 调整 uBiasuScaleuPower 参数组合
透明度混合错误 画面有黑块或闪烁 设置 transparent: truedepthWrite: false
模型平整效果差 规则几何体发光不明显 使用法线贴图增加表面细节
性能问题 复杂模型帧率下降 降低几何体细分或使用 LOD

🚀 扩展思路

变体效果 核心改动 难度
动态颜色变化 添加时间变量控制颜色色相 ⭐⭐
多层发光 使用多个菲涅尔层叠加 ⭐⭐
脉冲呼吸效果 添加正弦函数控制发光强度
环境映射叠加 结合 CubeTexture 实现反射 ⭐⭐⭐

本文档由 ThreeLab 编辑整理,如需转载,请注明出处。