第 5 课:Ray-triangle intersection
实现
uniform vec2 iResolution;
uniform float iTime;
const float c_Epsilon = 0.001;
vec3 rotateY(vec3 position)
{
float angle = sin(iTime * 0.5) * 3.14;
float x = position.x * cos(angle) + position.z * sin(angle);
float z = -position.x * sin(angle) + position.z * cos(angle);
return vec3(x, position.y, z);
}
void main() {
vec2 uv = vec2(gl_FragCoord.xy / iResolution);
vec3 P0 = vec3(0.0, -1.0, -0.5) + rotateY(vec3(-0.5, 0.0, 0.0));
vec3 P1 = vec3(0.0, 1.0, -0.5);
vec3 P2 = vec3(0.0, -1.0, -0.5) + rotateY(vec3(0.5, 0.0, 0.0));
mat3 m = mat3(P0, P1, P2);
vec4 RayOrigin = vec4(0.0, 0.0, 1.0, 1.0);
vec4 RayDir = vec4(normalize(vec3(uv * 2.0 - 1.0, -1.0)), 0.0);
// step 1
vec3 N = cross(P1 - P0, P2 - P0);
// step 2
vec4 L = vec4(N, -dot(N, P1));
float t = - (dot(L, RayOrigin) / dot(L, RayDir));
vec3 P = RayOrigin.xyz + RayDir.xyz * t;
float dist = abs(RayDir.z * t);
vec3 w = inverse(m) * P;
float w_sum = w.x + w.y + w.z;
vec3 color = vec3(2.0 - dist, 0.0, 0.0);
color *= (1.0 - step(1.0 + c_Epsilon, w_sum)) * step(c_Epsilon, w_sum);
color *= step(0.0, w.x);
color *= step(0.0, w.y);
color *= step(0.0, w.z);
gl_FragColor = vec4(color, 1.0);
}