diff options
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl')
-rw-r--r-- | source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl | 149 |
1 files changed, 72 insertions, 77 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl index 8792c646ec1..690ce5d527f 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_world_light_lib.glsl @@ -2,113 +2,108 @@ /* [Drobot2014a] Low Level Optimizations for GCN */ vec4 fast_rcp(vec4 v) { - return intBitsToFloat(0x7eef370b - floatBitsToInt(v)); + return intBitsToFloat(0x7eef370b - floatBitsToInt(v)); } vec3 brdf_approx(vec3 spec_color, float roughness, float NV) { - /* Very rough own approx. We don't need it to be correct, just fast. - * Just simulate fresnel effect with roughness attenuation. */ - float fresnel = exp2(-8.35 * NV) * (1.0 - roughness); - return mix(spec_color, vec3(1.0), fresnel); + /* Very rough own approx. We don't need it to be correct, just fast. + * Just simulate fresnel effect with roughness attenuation. */ + float fresnel = exp2(-8.35 * NV) * (1.0 - roughness); + return mix(spec_color, vec3(1.0), fresnel); } void prep_specular( - vec3 L, vec3 I, vec3 N, vec3 R, - out float NL, out float wrapped_NL, out float spec_angle) + vec3 L, vec3 I, vec3 N, vec3 R, out float NL, out float wrapped_NL, out float spec_angle) { - wrapped_NL = dot(L, R); - vec3 half_dir = normalize(L + I); - spec_angle = clamp(dot(half_dir, N), 0.0, 1.0); - NL = clamp(dot(L, N), 0.0, 1.0); + wrapped_NL = dot(L, R); + vec3 half_dir = normalize(L + I); + spec_angle = clamp(dot(half_dir, N), 0.0, 1.0); + NL = clamp(dot(L, N), 0.0, 1.0); } /* Normalized Blinn shading */ vec4 blinn_specular(vec4 shininess, vec4 spec_angle, vec4 NL) { - /* Pi is already divided in the light power. - * normalization_factor = (shininess + 8.0) / (8.0 * M_PI) */ - vec4 normalization_factor = shininess * 0.125 + 1.0; - vec4 spec_light = pow(spec_angle, shininess) * NL * normalization_factor; + /* Pi is already divided in the light power. + * normalization_factor = (shininess + 8.0) / (8.0 * M_PI) */ + vec4 normalization_factor = shininess * 0.125 + 1.0; + vec4 spec_light = pow(spec_angle, shininess) * NL * normalization_factor; - return spec_light; + return spec_light; } /* NL need to be unclamped. w in [0..1] range. */ vec4 wrapped_lighting(vec4 NL, vec4 w) { - vec4 w_1 = w + 1.0; - vec4 denom = fast_rcp(w_1 * w_1); - return clamp((NL + w) * denom, 0.0, 1.0); + vec4 w_1 = w + 1.0; + vec4 denom = fast_rcp(w_1 * w_1); + return clamp((NL + w) * denom, 0.0, 1.0); } vec3 get_world_lighting( - WorldData world_data, - vec3 diffuse_color, vec3 specular_color, float roughness, - vec3 N, vec3 I) + WorldData world_data, vec3 diffuse_color, vec3 specular_color, float roughness, vec3 N, vec3 I) { - vec3 specular_light = world_data.ambient_color.rgb; - vec3 diffuse_light = world_data.ambient_color.rgb; - vec4 wrap = vec4( - world_data.lights[0].diffuse_color_wrap.a, - world_data.lights[1].diffuse_color_wrap.a, - world_data.lights[2].diffuse_color_wrap.a, - world_data.lights[3].diffuse_color_wrap.a - ); + vec3 specular_light = world_data.ambient_color.rgb; + vec3 diffuse_light = world_data.ambient_color.rgb; + vec4 wrap = vec4(world_data.lights[0].diffuse_color_wrap.a, + world_data.lights[1].diffuse_color_wrap.a, + world_data.lights[2].diffuse_color_wrap.a, + world_data.lights[3].diffuse_color_wrap.a); #ifdef V3D_SHADING_SPECULAR_HIGHLIGHT - /* Prepare Specular computation. Eval 4 lights at once. */ - vec3 R = -reflect(I, N); - vec4 spec_angle, spec_NL, wrap_NL; - prep_specular(world_data.lights[0].direction.xyz, I, N, R, spec_NL.x, wrap_NL.x, spec_angle.x); - prep_specular(world_data.lights[1].direction.xyz, I, N, R, spec_NL.y, wrap_NL.y, spec_angle.y); - prep_specular(world_data.lights[2].direction.xyz, I, N, R, spec_NL.z, wrap_NL.z, spec_angle.z); - prep_specular(world_data.lights[3].direction.xyz, I, N, R, spec_NL.w, wrap_NL.w, spec_angle.w); - - vec4 gloss = vec4(1.0 - roughness); - /* Reduce gloss for smooth light. (simulate bigger light) */ - gloss *= 1.0 - wrap; - vec4 shininess = exp2(10.0 * gloss + 1.0); - - vec4 spec_light = blinn_specular(shininess, spec_angle, spec_NL); - - /* Simulate Env. light. */ - vec4 w = mix(wrap, vec4(1.0), roughness); - vec4 spec_env = wrapped_lighting(wrap_NL, w); - - spec_light = mix(spec_light, spec_env, wrap * wrap); - - /* Multiply result by lights specular colors. */ - specular_light += spec_light.x * world_data.lights[0].specular_color.rgb; - specular_light += spec_light.y * world_data.lights[1].specular_color.rgb; - specular_light += spec_light.z * world_data.lights[2].specular_color.rgb; - specular_light += spec_light.w * world_data.lights[3].specular_color.rgb; - - float NV = clamp(dot(N, I), 0.0, 1.0); - specular_color = brdf_approx(specular_color, roughness, NV); + /* Prepare Specular computation. Eval 4 lights at once. */ + vec3 R = -reflect(I, N); + vec4 spec_angle, spec_NL, wrap_NL; + prep_specular(world_data.lights[0].direction.xyz, I, N, R, spec_NL.x, wrap_NL.x, spec_angle.x); + prep_specular(world_data.lights[1].direction.xyz, I, N, R, spec_NL.y, wrap_NL.y, spec_angle.y); + prep_specular(world_data.lights[2].direction.xyz, I, N, R, spec_NL.z, wrap_NL.z, spec_angle.z); + prep_specular(world_data.lights[3].direction.xyz, I, N, R, spec_NL.w, wrap_NL.w, spec_angle.w); + + vec4 gloss = vec4(1.0 - roughness); + /* Reduce gloss for smooth light. (simulate bigger light) */ + gloss *= 1.0 - wrap; + vec4 shininess = exp2(10.0 * gloss + 1.0); + + vec4 spec_light = blinn_specular(shininess, spec_angle, spec_NL); + + /* Simulate Env. light. */ + vec4 w = mix(wrap, vec4(1.0), roughness); + vec4 spec_env = wrapped_lighting(wrap_NL, w); + + spec_light = mix(spec_light, spec_env, wrap * wrap); + + /* Multiply result by lights specular colors. */ + specular_light += spec_light.x * world_data.lights[0].specular_color.rgb; + specular_light += spec_light.y * world_data.lights[1].specular_color.rgb; + specular_light += spec_light.z * world_data.lights[2].specular_color.rgb; + specular_light += spec_light.w * world_data.lights[3].specular_color.rgb; + + float NV = clamp(dot(N, I), 0.0, 1.0); + specular_color = brdf_approx(specular_color, roughness, NV); #endif - specular_light *= specular_color; + specular_light *= specular_color; - /* Prepare diffuse computation. Eval 4 lights at once. */ - vec4 diff_NL; - diff_NL.x = dot(world_data.lights[0].direction.xyz, N); - diff_NL.y = dot(world_data.lights[1].direction.xyz, N); - diff_NL.z = dot(world_data.lights[2].direction.xyz, N); - diff_NL.w = dot(world_data.lights[3].direction.xyz, N); + /* Prepare diffuse computation. Eval 4 lights at once. */ + vec4 diff_NL; + diff_NL.x = dot(world_data.lights[0].direction.xyz, N); + diff_NL.y = dot(world_data.lights[1].direction.xyz, N); + diff_NL.z = dot(world_data.lights[2].direction.xyz, N); + diff_NL.w = dot(world_data.lights[3].direction.xyz, N); - vec4 diff_light = wrapped_lighting(diff_NL, wrap); + vec4 diff_light = wrapped_lighting(diff_NL, wrap); - /* Multiply result by lights diffuse colors. */ - diffuse_light += diff_light.x * world_data.lights[0].diffuse_color_wrap.rgb; - diffuse_light += diff_light.y * world_data.lights[1].diffuse_color_wrap.rgb; - diffuse_light += diff_light.z * world_data.lights[2].diffuse_color_wrap.rgb; - diffuse_light += diff_light.w * world_data.lights[3].diffuse_color_wrap.rgb; + /* Multiply result by lights diffuse colors. */ + diffuse_light += diff_light.x * world_data.lights[0].diffuse_color_wrap.rgb; + diffuse_light += diff_light.y * world_data.lights[1].diffuse_color_wrap.rgb; + diffuse_light += diff_light.z * world_data.lights[2].diffuse_color_wrap.rgb; + diffuse_light += diff_light.w * world_data.lights[3].diffuse_color_wrap.rgb; - /* Energy conservation with colored specular look strange. - * Limit this strangeness by using mono-chromatic specular intensity. */ - float spec_energy = dot(specular_color, vec3(0.33333)); + /* Energy conservation with colored specular look strange. + * Limit this strangeness by using mono-chromatic specular intensity. */ + float spec_energy = dot(specular_color, vec3(0.33333)); - diffuse_light *= diffuse_color * (1.0 - spec_energy); + diffuse_light *= diffuse_color * (1.0 - spec_energy); - return diffuse_light + specular_light; + return diffuse_light + specular_light; } |