bool rayToLightUV( in vec3 pos, in mat3 lightFrame, in vec3 lightPos, in float width, in float height, in vec3 rayDir, out vec2 uv ) { float d0 = dot( lightPos, lightFrame[2] ); float d1 = dot( pos, lightFrame[2] ); float fac = dot( rayDir, lightFrame[2] ); if ((d0 < d1) || ( fac < 0.001 )) { uv = vec2(-1.0); return false; } float t = (d0 - d1) / fac; vec3 hitPos = pos + t * rayDir; width *= dot(lightFrame[0], lightFrame[0]); height *= dot(lightFrame[1], lightFrame[1]); hitPos -= lightPos; uv.x = ( dot(hitPos, lightFrame[0]) / width ) + 0.5; uv.y = ( dot(hitPos, lightFrame[1]) / height ) + 0.5; return true; } float computeMicroHit( in vec3 pos, in mat3 tanFrame, in vec3 lightPos, in mat3 lightFrame, in float width, in float height, in vec3 viewDir, out vec2 UV[5] ) { vec3 rayDir = reflect( -viewDir, tanFrame[2] ); vec2 ctrUV; bool isHit = rayToLightUV( pos, lightFrame, lightPos, width, height, rayDir, ctrUV ); if ((!isHit) || ( dot(rayDir, tanFrame[2]) < 0.001 )) { return 0.0; } vec3 H0 = 0.99749686716 * tanFrame[2] + 0.005 * tanFrame[0]; vec3 H1 = 0.99749686716 * tanFrame[2] - 0.005 * tanFrame[0]; vec3 H2 = 0.99749686716 * tanFrame[2] + 0.005 * tanFrame[1]; vec3 H3 = 0.99749686716 * tanFrame[2] - 0.005 * tanFrame[1]; vec3 R[4]; R[0] = reflect( -viewDir, H0 ); R[1] = reflect( -viewDir, H1 ); R[2] = reflect( -viewDir, H2 ); R[3] = reflect( -viewDir, H3 ); rayToLightUV( pos, lightFrame, lightPos, width, height, R[0], UV[0] ); rayToLightUV( pos, lightFrame, lightPos, width, height, R[1], UV[1] ); rayToLightUV( pos, lightFrame, lightPos, width, height, R[2], UV[2] ); rayToLightUV( pos, lightFrame, lightPos, width, height, R[3], UV[3] ); UV[4] = ctrUV; return clamp( dot(rayDir, tanFrame[2]), 0.0, 1.0 ); }