@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
44 lines (36 loc) • 1.63 kB
JavaScript
// language=GLSL
export default `
vec3 inverseTransformDirection( in vec3 normal, in mat4 matrix ) {
// matrix is assumed to be orthogonal
return normalize( ( vec4( normal, 0.0 ) * matrix ).xyz );
}
// source: https://graphics.stanford.edu/papers/envmap/envmap.pdf
vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {
// normal is assumed to have unit length
float x = normal.x, y = normal.y, z = normal.z;
// band 0
vec3 result = shCoefficients[ 0 ] * 0.8862269254527579;
// band 1
result -= shCoefficients[ 1 ] * 1.0233267079464885 * y;
result += shCoefficients[ 2 ] * 1.0233267079464885 * z;
result -= shCoefficients[ 3 ] * 1.0233267079464885 * x;
// band 2
result += shCoefficients[ 4 ] * 0.8580855308097834 * x * y;
result -= shCoefficients[ 5 ] * 0.8580855308097834 * y * z;
result += shCoefficients[ 6 ] * ( 0.7431238683011272 * z * z - 0.24770795610037571 );
result -= shCoefficients[ 7 ] * 0.8580855308097834 * x * z;
result += shCoefficients[ 8 ] * 0.4290427654048917 * ( x * x - y * y );
return result;
}
uniform vec3 sh[ 9 ]; // sh coefficients
uniform float intensity; // light probe intensity
varying vec3 vNormal;
void main() {
vec3 normal = normalize( vNormal );
vec3 worldNormal = normalize(inverseTransformDirection( normal, viewMatrix ));
vec3 irradiance = shGetIrradianceAt( worldNormal, sh );
vec3 outgoingLight = 1.0 * irradiance * intensity;
gl_FragColor = linearToOutputTexel( vec4( outgoingLight, 1.0 ) );
}
`