diff options
Diffstat (limited to 'shaders/cook_torrance.frag')
| -rw-r--r-- | shaders/cook_torrance.frag | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/shaders/cook_torrance.frag b/shaders/cook_torrance.frag index 1a4faf8..74a89e2 100644 --- a/shaders/cook_torrance.frag +++ b/shaders/cook_torrance.frag | |||
| @@ -1,3 +1,6 @@ | |||
| 1 | /* | ||
| 2 | [1] BRDF reference: https://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html | ||
| 3 | */ | ||
| 1 | precision highp float; | 4 | precision highp float; |
| 2 | 5 | ||
| 3 | uniform vec4 BaseColorFactor; | 6 | uniform vec4 BaseColorFactor; |
| @@ -86,8 +89,10 @@ vec3 get_ws_normal(vec3 normalWs, vec3 normalMapSample) { | |||
| 86 | } | 89 | } |
| 87 | #endif // HAS_TANGENTS || HAS_TEXCOORDS | 90 | #endif // HAS_TANGENTS || HAS_TEXCOORDS |
| 88 | 91 | ||
| 92 | // Normal distribution function (NDF). | ||
| 93 | // Eq (4) in reference [1]. | ||
| 89 | float trowbridge_reitz_GGX(float roughness, float NdotH) { | 94 | float trowbridge_reitz_GGX(float roughness, float NdotH) { |
| 90 | float a = roughness * roughness; | 95 | float a = roughness * roughness; // "alpha roughness" in the reference. |
| 91 | float a2 = a * a; | 96 | float a2 = a * a; |
| 92 | float d = NdotH * NdotH * (a2 - 1.0) + 1.0; | 97 | float d = NdotH * NdotH * (a2 - 1.0) + 1.0; |
| 93 | return a2 / (PI * d * d); | 98 | return a2 / (PI * d * d); |
| @@ -97,6 +102,8 @@ float geometry_schlick_GGX(float k, float NdotV) { | |||
| 97 | return NdotV / (NdotV * (1.0 - k) + k); | 102 | return NdotV / (NdotV * (1.0 - k) + k); |
| 98 | } | 103 | } |
| 99 | 104 | ||
| 105 | // Geometry function. | ||
| 106 | // See "Smith" under "Geometric Shadowing" in reference [1]. | ||
| 100 | float geometry_smith(float roughness, float NdotL, float NdotV) { | 107 | float geometry_smith(float roughness, float NdotL, float NdotV) { |
| 101 | float k = roughness * roughness / 2.0; // IBL | 108 | float k = roughness * roughness / 2.0; // IBL |
| 102 | return geometry_schlick_GGX(k, NdotV) * geometry_schlick_GGX(k, NdotL); | 109 | return geometry_schlick_GGX(k, NdotV) * geometry_schlick_GGX(k, NdotL); |
| @@ -138,7 +145,7 @@ vec3 cook_torrance_IBL( | |||
| 138 | vec3 irradiance, vec3 prefiltered_env, vec2 BRDF_env) { | 145 | vec3 irradiance, vec3 prefiltered_env, vec2 BRDF_env) { |
| 139 | vec3 F0 = mix(vec3(0.04), albedo, metallic); | 146 | vec3 F0 = mix(vec3(0.04), albedo, metallic); |
| 140 | vec3 F = fresnel_schlick_roughness(F0, NdotV, roughness); | 147 | vec3 F = fresnel_schlick_roughness(F0, NdotV, roughness); |
| 141 | vec3 Kd = mix(vec3(1.0) - F, vec3(0.0), metallic); | 148 | vec3 Kd = (vec3(1.0) - F) * (1.0 - metallic); |
| 142 | // A non-HDR environment map essentially has the 1/pi baked in as it does not | 149 | // A non-HDR environment map essentially has the 1/pi baked in as it does not |
| 143 | // use physical units. See: | 150 | // use physical units. See: |
| 144 | // https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ | 151 | // https://seblagarde.wordpress.com/2012/01/08/pi-or-not-to-pi-in-game-lighting-equation/ |
