diff options
Diffstat (limited to 'shaders/cook_torrance.frag')
| -rw-r--r-- | shaders/cook_torrance.frag | 98 |
1 files changed, 57 insertions, 41 deletions
diff --git a/shaders/cook_torrance.frag b/shaders/cook_torrance.frag index 9ff5a8d..f6c6048 100644 --- a/shaders/cook_torrance.frag +++ b/shaders/cook_torrance.frag | |||
| @@ -10,19 +10,26 @@ uniform float MetallicFactor; | |||
| 10 | uniform float RoughnessFactor; | 10 | uniform float RoughnessFactor; |
| 11 | uniform vec3 EmissiveFactor; | 11 | uniform vec3 EmissiveFactor; |
| 12 | 12 | ||
| 13 | #ifdef HAS_ALBEDO_MAP | 13 | #if HAS_TRANSPARENCY |
| 14 | #define ALPHA_MODE_MASK 1 | ||
| 15 | #define ALPHA_MODE_BLEND 2 | ||
| 16 | uniform int AlphaMode; | ||
| 17 | uniform float AlphaCutoff; | ||
| 18 | #endif | ||
| 19 | |||
| 20 | #if HAS_ALBEDO_MAP | ||
| 14 | uniform sampler2D BaseColorTexture; | 21 | uniform sampler2D BaseColorTexture; |
| 15 | #endif | 22 | #endif |
| 16 | #ifdef HAS_METALLIC_ROUGHNESS_MAP | 23 | #if HAS_METALLIC_ROUGHNESS_MAP |
| 17 | uniform sampler2D MetallicRoughnessTexture; | 24 | uniform sampler2D MetallicRoughnessTexture; |
| 18 | #endif | 25 | #endif |
| 19 | #ifdef HAS_EMISSIVE_MAP | 26 | #if HAS_EMISSIVE_MAP |
| 20 | uniform sampler2D EmissiveTexture; | 27 | uniform sampler2D EmissiveTexture; |
| 21 | #endif | 28 | #endif |
| 22 | #ifdef HAS_OCCLUSION_MAP | 29 | #if HAS_OCCLUSION_MAP |
| 23 | uniform sampler2D AmbientOcclusionTexture; | 30 | uniform sampler2D AmbientOcclusionTexture; |
| 24 | #endif | 31 | #endif |
| 25 | #ifdef HAS_NORMAL_MAP | 32 | #if HAS_NORMAL_MAP |
| 26 | uniform sampler2D NormalMap; | 33 | uniform sampler2D NormalMap; |
| 27 | #endif | 34 | #endif |
| 28 | 35 | ||
| @@ -37,13 +44,13 @@ uniform vec3 CameraPosition; // World space. | |||
| 37 | 44 | ||
| 38 | // World-space position, normal and tangent. | 45 | // World-space position, normal and tangent. |
| 39 | in vec3 Position; | 46 | in vec3 Position; |
| 40 | #ifdef HAS_NORMALS | 47 | #if HAS_NORMALS |
| 41 | in vec3 Normal; | 48 | in vec3 Normal; |
| 42 | #endif | 49 | #endif |
| 43 | #ifdef HAS_TANGENTS | 50 | #if HAS_TANGENTS |
| 44 | in vec4 Tangent; | 51 | in vec4 Tangent; |
| 45 | #endif | 52 | #endif |
| 46 | #ifdef HAS_TEXCOORDS | 53 | #if HAS_TEXCOORDS |
| 47 | in vec2 Texcoord; | 54 | in vec2 Texcoord; |
| 48 | #endif | 55 | #endif |
| 49 | 56 | ||
| @@ -61,7 +68,7 @@ layout (location = 0) out vec4 Colour; | |||
| 61 | #if defined(HAS_NORMAL_MAP) && (defined(HAS_TANGENTS) || defined(HAS_TEXCOORDS)) | 68 | #if defined(HAS_NORMAL_MAP) && (defined(HAS_TANGENTS) || defined(HAS_TEXCOORDS)) |
| 62 | vec3 get_ws_normal(vec3 normalWs, vec3 normalMapSample) { | 69 | vec3 get_ws_normal(vec3 normalWs, vec3 normalMapSample) { |
| 63 | vec3 N = normalize(Normal); | 70 | vec3 N = normalize(Normal); |
| 64 | #ifdef HAS_TANGENTS | 71 | #if HAS_TANGENTS |
| 65 | //vec3 T = normalize(tangent.xyz - dot(tangent.xyz, N) * N); | 72 | //vec3 T = normalize(tangent.xyz - dot(tangent.xyz, N) * N); |
| 66 | vec3 T = Tangent.xyz; | 73 | vec3 T = Tangent.xyz; |
| 67 | vec3 B = Tangent.w * cross(N, T); | 74 | vec3 B = Tangent.w * cross(N, T); |
| @@ -145,8 +152,8 @@ vec3 cook_torrance_IBL( | |||
| 145 | vec3 albedo, float metallic, float roughness, float occlusion, | 152 | vec3 albedo, float metallic, float roughness, float occlusion, |
| 146 | float NdotV, | 153 | float NdotV, |
| 147 | vec3 irradiance, vec3 prefiltered_env, vec2 BRDF_env) { | 154 | vec3 irradiance, vec3 prefiltered_env, vec2 BRDF_env) { |
| 148 | vec3 F0 = mix(vec3(0.04), albedo, metallic); | 155 | vec3 F0 = mix(vec3(0.04), albedo, metallic); // albedo = F0 for metals |
| 149 | vec3 F = fresnel_schlick_roughness(F0, NdotV, roughness); | 156 | vec3 F = fresnel_schlick_roughness(F0, NdotV, roughness); |
| 150 | vec3 Kd = (vec3(1.0) - F) * (1.0 - metallic); | 157 | vec3 Kd = (vec3(1.0) - F) * (1.0 - metallic); |
| 151 | // A non-HDR environment map essentially has the 1/pi baked in as it does not | 158 | // A non-HDR environment map essentially has the 1/pi baked in as it does not |
| 152 | // use physical units. See: | 159 | // use physical units. See: |
| @@ -159,36 +166,19 @@ vec3 cook_torrance_IBL( | |||
| 159 | 166 | ||
| 160 | void main() | 167 | void main() |
| 161 | { | 168 | { |
| 162 | // TODO: Also use the specular F0 map from the model, and emissive. Make sure | ||
| 163 | // to use all maps. | ||
| 164 | // https://sketchfab.com/models/b81008d513954189a063ff901f7abfe4 | ||
| 165 | #ifdef HAS_NORMAL_MAP | ||
| 166 | vec3 normalMapSample = texture(NormalMap, Texcoord).xyz * 2.0 - 1.0; | ||
| 167 | vec3 N = get_ws_normal(Normal, normalMapSample); | ||
| 168 | #elif HAS_NORMALS | ||
| 169 | vec3 N = normalize(Normal); | ||
| 170 | #endif | ||
| 171 | vec3 V = normalize(CameraPosition - Position); | ||
| 172 | vec3 R = reflect(-V, N); | ||
| 173 | // Not needed for IBL. | ||
| 174 | //vec3 L = N; | ||
| 175 | //vec3 H = normalize(L + V); | ||
| 176 | |||
| 177 | float NdotV = max(0.0, dot(N, V)); | ||
| 178 | // Not needed for IBL. | ||
| 179 | //float NdotL = max(0.0, dot(N,L)); | ||
| 180 | //float NdotH = max(0.0, dot(N,H)); | ||
| 181 | //float HdotV = clamp(dot(H,V), 0.0, 1.0); // Clamp to prevent black spots. | ||
| 182 | |||
| 183 | // TODO: BaseColorFactor and BaseColorTexture are vec4/rgba quantities | ||
| 184 | // respectively. Handle the alpha channel. | ||
| 185 | // TODO: Other factors. | 169 | // TODO: Other factors. |
| 186 | #ifdef HAS_ALBEDO_MAP | 170 | #if HAS_ALBEDO_MAP |
| 187 | vec3 albedo = vec3(BaseColorFactor) * texture(BaseColorTexture, Texcoord).rgb; | 171 | vec4 base_colour = vec4(BaseColorFactor) * texture(BaseColorTexture, Texcoord); |
| 188 | #else | 172 | #else |
| 189 | vec3 albedo = vec3(BaseColorFactor); | 173 | vec4 base_colour = vec4(BaseColorFactor); |
| 190 | #endif | 174 | #endif |
| 191 | #ifdef HAS_METALLIC_ROUGHNESS_MAP | 175 | vec3 albedo = base_colour.rgb; |
| 176 | #if HAS_TRANSPARENCY | ||
| 177 | if ((AlphaMode == ALPHA_MODE_MASK) && (base_colour.a < AlphaCutoff)) { | ||
| 178 | discard; | ||
| 179 | } | ||
| 180 | #endif | ||
| 181 | #if HAS_METALLIC_ROUGHNESS_MAP | ||
| 192 | // Spec: "Its green channel contains roughness values and its blue channel | 182 | // Spec: "Its green channel contains roughness values and its blue channel |
| 193 | // contains metalness values." | 183 | // contains metalness values." |
| 194 | vec2 metal_roughness | 184 | vec2 metal_roughness |
| @@ -197,12 +187,12 @@ void main() | |||
| 197 | #else | 187 | #else |
| 198 | vec2 metal_roughness = vec2(MetallicFactor, RoughnessFactor); | 188 | vec2 metal_roughness = vec2(MetallicFactor, RoughnessFactor); |
| 199 | #endif | 189 | #endif |
| 200 | #ifdef HAS_EMISSIVE_MAP | 190 | #if HAS_EMISSIVE_MAP |
| 201 | vec3 emissive = EmissiveFactor * texture(EmissiveTexture, Texcoord).rgb; | 191 | vec3 emissive = EmissiveFactor * texture(EmissiveTexture, Texcoord).rgb; |
| 202 | #else | 192 | #else |
| 203 | vec3 emissive = EmissiveFactor; | 193 | vec3 emissive = EmissiveFactor; |
| 204 | #endif | 194 | #endif |
| 205 | #ifdef HAS_OCCLUSION_MAP | 195 | #if HAS_OCCLUSION_MAP |
| 206 | float occlusion = texture(AmbientOcclusionTexture, Texcoord).r; | 196 | float occlusion = texture(AmbientOcclusionTexture, Texcoord).r; |
| 207 | #else | 197 | #else |
| 208 | float occlusion = 1.0; | 198 | float occlusion = 1.0; |
| @@ -210,6 +200,32 @@ void main() | |||
| 210 | float metallic = metal_roughness.x; | 200 | float metallic = metal_roughness.x; |
| 211 | float roughness = metal_roughness.y; | 201 | float roughness = metal_roughness.y; |
| 212 | 202 | ||
| 203 | // TODO: Also use the specular F0 map from the model, and emissive. Make sure | ||
| 204 | // to use all maps. | ||
| 205 | // https://sketchfab.com/models/b81008d513954189a063ff901f7abfe4 | ||
| 206 | #if HAS_NORMAL_MAP | ||
| 207 | // Spec: "After dequantization, texel values MUST be mapped as follows: | ||
| 208 | // red [0.0 .. 1.0] to X [-1 .. 1], | ||
| 209 | // green [0.0 .. 1.0] to Y [-1 .. 1], | ||
| 210 | // blue (0.5 .. 1.0] to Z ( 0 .. 1]. | ||
| 211 | // Normal textures SHOULD NOT contain blue values less than or equal to 0.5." | ||
| 212 | vec3 normalMapSample = texture(NormalMap, Texcoord).xyz * 2.0 - 1.0; | ||
| 213 | vec3 N = get_ws_normal(Normal, normalMapSample); | ||
| 214 | #elif HAS_NORMALS | ||
| 215 | vec3 N = normalize(Normal); | ||
| 216 | #endif | ||
| 217 | vec3 V = normalize(CameraPosition - Position); | ||
| 218 | vec3 R = reflect(-V, N); | ||
| 219 | // Not needed for IBL. | ||
| 220 | //vec3 L = N; | ||
| 221 | //vec3 H = normalize(L + V); | ||
| 222 | |||
| 223 | float NdotV = max(0.0, dot(N, V)); | ||
| 224 | // Not needed for IBL. | ||
| 225 | //float NdotL = max(0.0, dot(N,L)); | ||
| 226 | //float NdotH = max(0.0, dot(N,H)); | ||
| 227 | //float HdotV = clamp(dot(H,V), 0.0, 1.0); // Clamp to prevent black spots. | ||
| 228 | |||
| 213 | // For a single light direction: | 229 | // For a single light direction: |
| 214 | // vec3 brdf = cook_torrance(albedo, metallic, roughness, NdotL, NdotV, NdotH, HdotV); | 230 | // vec3 brdf = cook_torrance(albedo, metallic, roughness, NdotL, NdotV, NdotH, HdotV); |
| 215 | // vec3 Li = texture(Sky, N).rgb; | 231 | // vec3 Li = texture(Sky, N).rgb; |
| @@ -268,5 +284,5 @@ void main() | |||
| 268 | // //colour = B * 0.5 + 0.5; | 284 | // //colour = B * 0.5 + 0.5; |
| 269 | // } | 285 | // } |
| 270 | 286 | ||
| 271 | Colour = vec4(colour, 1.0); | 287 | Colour = vec4(colour, base_colour.a); |
| 272 | } | 288 | } |
