每个像素运行一次拖动数字,或直接改代码
uniform mat4 projectionMatrix;
uniform float uRadius;
uniform float uWriteDepth;
in vec2 vUv;
in vec3 vViewPos;
out vec4 fragColor;
void main() {
vec2 p = vUv * 2.0 - 1.0;
float r2 = dot(p, p);
if (r2 > 1.0) discard;
vec3 N = vec3(p, sqrt(1.0 - r2));
vec3 surface = vViewPos + vec3(0.0, 0.0, N.z * uRadius);
vec4 clip = projectionMatrix * vec4(surface, 1.0);
float sphereDepth = clip.z / clip.w * 0.5 + 0.5;
gl_FragDepth = mix(gl_FragCoord.z, sphereDepth, uWriteDepth);
float light = max(dot(N, normalize(vec3(-0.5, 0.7, 0.8))), 0.0);
fragColor = vec4(vec3(0.48, 0.83, 0.69) * (0.2 + 0.8 * light), 1.0);
}JS 这一侧
光栅化给每个片元一个深度;写 gl_FragDepth 可以覆盖它。一张平面卡片因此能和方块像真正的球一样穿插。
试一试
- 关掉「写入 gl_FragDepth」,方块和卡片怎样相交?
- 把半径调大,球面更鼓
- 把 N.z 换成 0.0,深度又变回平面