diff options
-rw-r--r-- | gfx/shaders/cook_torrance.frag | 26 |
1 files changed, 12 insertions, 14 deletions
diff --git a/gfx/shaders/cook_torrance.frag b/gfx/shaders/cook_torrance.frag index fcedef6..1adb4ae 100644 --- a/gfx/shaders/cook_torrance.frag +++ b/gfx/shaders/cook_torrance.frag | |||
@@ -112,7 +112,7 @@ vec3 fresnel_schlick_roughness(vec3 F0, float NdotV, float roughness) { | |||
112 | 112 | ||
113 | // Cook-Torrance BRDF for a single light direction. | 113 | // Cook-Torrance BRDF for a single light direction. |
114 | vec3 cook_torrance( | 114 | vec3 cook_torrance( |
115 | vec3 albedo, float metallic, float roughness, vec3 emissive, | 115 | vec3 albedo, float metallic, float roughness, |
116 | float NdotL, float NdotV, float NdotH, float HdotV) { | 116 | float NdotL, float NdotV, float NdotH, float HdotV) { |
117 | vec3 F0 = mix(vec3(0.04), albedo, metallic); | 117 | vec3 F0 = mix(vec3(0.04), albedo, metallic); |
118 | float D = trowbridge_reitz_GGX(roughness, NdotH); | 118 | float D = trowbridge_reitz_GGX(roughness, NdotH); |
@@ -122,23 +122,20 @@ vec3 cook_torrance( | |||
122 | vec3 diffuse = Kd*albedo*INV_PI; | 122 | vec3 diffuse = Kd*albedo*INV_PI; |
123 | // Take a max to prevent division by 0 when either dot product is 0. | 123 | // Take a max to prevent division by 0 when either dot product is 0. |
124 | vec3 specular = (D*F*G) / max(4.0 * NdotV * NdotL, 0.0001); | 124 | vec3 specular = (D*F*G) / max(4.0 * NdotV * NdotL, 0.0001); |
125 | return emissive + diffuse + specular; | 125 | return diffuse + specular; |
126 | } | 126 | } |
127 | 127 | ||
128 | // Cook-Torrance BRDF for IBL. | 128 | // Cook-Torrance BRDF for IBL. |
129 | vec3 cook_torrance_IBL( | 129 | vec3 cook_torrance_IBL( |
130 | vec3 albedo, float metallic, float roughness, vec3 emissive, float occlusion, | 130 | vec3 albedo, float metallic, float roughness, float occlusion, |
131 | float NdotV, | 131 | float NdotV, |
132 | vec3 irradiance, vec3 prefiltered_env, vec2 BRDF_env, vec3 ambient) { | 132 | vec3 irradiance, vec3 prefiltered_env, vec2 BRDF_env) { |
133 | vec3 F0 = mix(vec3(0.04), albedo, metallic); | 133 | vec3 F0 = mix(vec3(0.04), albedo, metallic); |
134 | vec3 F = fresnel_schlick_roughness(F0, NdotV, roughness); | 134 | vec3 F = fresnel_schlick_roughness(F0, NdotV, roughness); |
135 | vec3 Kd = mix(vec3(1.0) - F, vec3(0.0), metallic); | 135 | vec3 Kd = mix(vec3(1.0) - F, vec3(0.0), metallic); |
136 | vec3 diffuse = Kd * albedo * INV_PI * irradiance; | 136 | vec3 diffuse = Kd * albedo * INV_PI * irradiance; |
137 | vec3 specular = prefiltered_env * (F * BRDF_env.x + BRDF_env.y); | 137 | vec3 specular = prefiltered_env * (F * BRDF_env.x + BRDF_env.y); |
138 | float ambient_strength = 0.05; // TODO: Make ambient strength a parameter. | 138 | return occlusion * (diffuse + specular); |
139 | ambient *= ambient_strength * occlusion; | ||
140 | emissive *= EmissiveFactor; | ||
141 | return emissive + ambient + diffuse + specular; | ||
142 | } | 139 | } |
143 | 140 | ||
144 | void main() | 141 | void main() |
@@ -182,30 +179,31 @@ void main() | |||
182 | vec2 metal_roughness = vec2(MetallicFactor, RoughnessFactor); | 179 | vec2 metal_roughness = vec2(MetallicFactor, RoughnessFactor); |
183 | #endif | 180 | #endif |
184 | #ifdef HAS_EMISSIVE_MAP | 181 | #ifdef HAS_EMISSIVE_MAP |
185 | vec3 emissive = texture(EmissiveTexture, Texcoord).rgb; | 182 | vec3 emissive = EmissiveFactor * texture(EmissiveTexture, Texcoord).rgb; |
186 | #else | 183 | #else |
187 | vec3 emissive = vec3(0.0); | 184 | vec3 emissive = EmissiveFactor; |
188 | #endif | 185 | #endif |
189 | #ifdef HAS_OCCLUSION_MAP | 186 | #ifdef HAS_OCCLUSION_MAP |
190 | float occlusion = texture(AmbientOcclusionTexture, Texcoord).r; | 187 | float occlusion = texture(AmbientOcclusionTexture, Texcoord).r; |
191 | #else | 188 | #else |
192 | float occlusion = 0.0; | 189 | float occlusion = 1.0; |
193 | #endif | 190 | #endif |
194 | float metallic = metal_roughness.x; | 191 | float metallic = metal_roughness.x; |
195 | float roughness = metal_roughness.y; | 192 | float roughness = metal_roughness.y; |
196 | 193 | ||
197 | // For a single light direction: | 194 | // For a single light direction: |
198 | // vec3 brdf = cook_torrance(albedo, metallic, roughness, emissive, NdotL, NdotV, NdotH, HdotV); | 195 | // vec3 brdf = cook_torrance(albedo, metallic, roughness, NdotL, NdotV, NdotH, HdotV); |
199 | // vec3 Li = texture(Sky, N).rgb; | 196 | // vec3 Li = texture(Sky, N).rgb; |
200 | // vec3 colour = brdf * Li * NdotL; | 197 | // vec3 colour = brdf * Li * NdotL; |
201 | 198 | ||
202 | // For IBL: | 199 | // For IBL: |
203 | vec3 irradiance = texture(IrradianceMap, N).rgb; | 200 | vec3 irradiance = texture(IrradianceMap, N).rgb; |
204 | vec3 prefiltered_env = textureLod(PrefilteredEnvironmentMap, R, roughness * MaxReflectionLOD).rgb; | 201 | vec3 prefiltered_env = textureLod(PrefilteredEnvironmentMap, R, roughness * MaxReflectionLOD).rgb; |
205 | vec3 ambient = textureLod(PrefilteredEnvironmentMap, R, MaxReflectionLOD).rgb; | ||
206 | vec2 BRDF_env = texture(BRDFIntegrationMap, vec2(NdotV, roughness)).rg; | 202 | vec2 BRDF_env = texture(BRDFIntegrationMap, vec2(NdotV, roughness)).rg; |
207 | vec3 colour = cook_torrance_IBL( | 203 | vec3 colour = cook_torrance_IBL( |
208 | albedo, metallic, roughness, emissive, occlusion, NdotV, irradiance, prefiltered_env, BRDF_env, ambient); | 204 | albedo, metallic, roughness, occlusion, NdotV, irradiance, prefiltered_env, BRDF_env); |
205 | |||
206 | colour += emissive; | ||
209 | 207 | ||
210 | // Reinhard tone mapping. | 208 | // Reinhard tone mapping. |
211 | colour = colour / (colour + vec3(1.0)); | 209 | colour = colour / (colour + vec3(1.0)); |