跳到主要内容
← Ray Tracing

Ray Tracing

Ray-triangle intersection

shader-learning 自学第 5 课:Ray-triangle intersection

实时渲染 · 2D 片段 GLSL

第 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);
}