diff options
Diffstat (limited to 'drivers/gles3')
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 4 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 3 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 1 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 48 | ||||
-rw-r--r-- | drivers/gles3/shaders/tonemap.glsl | 28 |
5 files changed, 45 insertions, 39 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 7160668fe8..14c436fd00 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -3931,7 +3931,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_FILMIC); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_ACES); - state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_REINHARDT); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINHARD_TONEMAPPER, env->tone_mapper == VS::ENV_TONE_MAPPER_REINHARD); state.tonemap_shader.set_conditional(TonemapShaderGLES3::KEEP_3D_LINEAR, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_KEEP_3D_LINEAR]); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, env->auto_exposure); @@ -4018,7 +4018,7 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_AUTO_EXPOSURE, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_FILMIC_TONEMAPPER, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_ACES_TONEMAPPER, false); - state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINDHART_TONEMAPPER, false); + state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_REINHARD_TONEMAPPER, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL1, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL2, false); state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_LEVEL3, false); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 797441c3a1..58c0a104c1 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -5024,6 +5024,9 @@ void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool ERR_FAIL_COND(!light); light->reverse_cull = p_enabled; + + light->version++; + light->instance_change_notify(); } void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) { diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 5203f53fa2..8e8b693eb2 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -182,7 +182,6 @@ VERTEX_SHADER_CODE color_interp = color; #ifdef USE_PIXEL_SNAP - outvec.xy = floor(outvec + 0.5).xy; #endif diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index bcaf4a57a8..598bd3465e 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -920,13 +920,14 @@ float GTR1(float NdotH, float a) { return (a2 - 1.0) / (M_PI * log(a2) * t); } -vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) { - float dielectric = (0.034 * 2.0) * specular; - // energy conservation - return mix(vec3(dielectric), albedo, metallic); // TODO: reference? +vec3 F0(float metallic, float specular, vec3 albedo) { + float dielectric = 0.16 * specular * specular; + // use albedo * metallic as colored specular reflectance at 0 angle for metallic materials; + // see https://google.github.io/filament/Filament.md.html + return mix(vec3(dielectric), albedo, vec3(metallic)); } -void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) { +void light_compute(vec3 N, vec3 L, vec3 V, vec3 B, vec3 T, vec3 light_color, vec3 attenuation, vec3 diffuse_color, vec3 transmission, float specular_blob_intensity, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) { #if defined(USE_LIGHT_SHADER_CODE) // light is written by the light shader @@ -1069,11 +1070,10 @@ LIGHT_SHADER_CODE #if defined(LIGHT_USE_ANISOTROPY) + float alpha = roughness * roughness; float aspect = sqrt(1.0 - anisotropy * 0.9); - float rx = roughness / aspect; - float ry = roughness * aspect; - float ax = rx * rx; - float ay = ry * ry; + float ax = alpha / aspect; + float ay = alpha * aspect; float XdotH = dot(T, H); float YdotH = dot(B, H); float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH); @@ -1085,11 +1085,11 @@ LIGHT_SHADER_CODE float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha); #endif // F - //float F0 = 1.0; - //float cLdotH5 = SchlickFresnel(cLdotH); - //float F = mix(cLdotH5, 1.0, F0); + vec3 f0 = F0(metallic, specular, diffuse_color); + float cLdotH5 = SchlickFresnel(cLdotH); + vec3 F = mix(vec3(cLdotH5), vec3(1.0), f0); - float specular_brdf_NL = cNdotL * D /* F */ * G; + vec3 specular_brdf_NL = cNdotL * D * F * G; specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation; #endif @@ -1191,7 +1191,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po } #endif -void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { +void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz - vertex; float light_length = length(light_rel_vec); @@ -1245,10 +1245,10 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi light_attenuation *= mix(omni_lights[idx].shadow_color_contact.rgb, vec3(1.0), shadow); } #endif //SHADOWS_DISABLED - light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, omni_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, omni_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, rim * omni_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light); + light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, omni_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, omni_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * omni_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light); } -void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { +void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent, vec3 albedo, vec3 transmission, float roughness, float metallic, float specular, float rim, float rim_tint, float clearcoat, float clearcoat_gloss, float anisotropy, float p_blob_intensity, inout vec3 diffuse_light, inout vec3 specular_light) { vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz - vertex; float light_length = length(light_rel_vec); @@ -1280,7 +1280,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi } #endif //SHADOWS_DISABLED - light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, spot_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, spot_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, rim * spot_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light); + light_compute(normal, normalize(light_rel_vec), eye_vec, binormal, tangent, spot_lights[idx].light_color_energy.rgb, light_attenuation, albedo, transmission, spot_lights[idx].light_params.z * p_blob_intensity, roughness, metallic, specular, rim * spot_attenuation, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light); } void reflection_process(int idx, vec3 vertex, vec3 normal, vec3 binormal, vec3 tangent, float roughness, float anisotropy, vec3 ambient, vec3 skybox, inout highp vec4 reflection_accum, inout highp vec4 ambient_accum) { @@ -1895,7 +1895,7 @@ FRAGMENT_SHADER_CODE specular_light *= mix(vec3(1.0), light_attenuation, specular_light_interp.a); #else - light_compute(normal, -light_direction_attenuation.xyz, eye_vec, binormal, tangent, light_color_energy.rgb, light_attenuation, albedo, transmission, light_params.z * specular_blob_intensity, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light); + light_compute(normal, -light_direction_attenuation.xyz, eye_vec, binormal, tangent, light_color_energy.rgb, light_attenuation, albedo, transmission, light_params.z * specular_blob_intensity, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, diffuse_light, specular_light); #endif #endif //#USE_LIGHT_DIRECTIONAL @@ -1969,11 +1969,11 @@ FRAGMENT_SHADER_CODE #else for (int i = 0; i < omni_light_count; i++) { - light_process_omni(omni_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light); + light_process_omni(omni_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light); } for (int i = 0; i < spot_light_count; i++) { - light_process_spot(spot_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light); + light_process_spot(spot_light_indices[i], vertex, eye_vec, normal, binormal, tangent, albedo, transmission, roughness, metallic, specular, rim, rim_tint, clearcoat, clearcoat_gloss, anisotropy, specular_blob_intensity, diffuse_light, specular_light); } #endif //USE_VERTEX_LIGHTING @@ -1994,7 +1994,7 @@ FRAGMENT_SHADER_CODE diffuse_light *= ao_light_affect; #endif - //energy conservation + // base color remapping diffuse_light *= 1.0 - metallic; // TODO: avoid all diffuse and ambient light calculations when metallic == 1 up to this point ambient_light *= 1.0 - metallic; @@ -2011,10 +2011,10 @@ FRAGMENT_SHADER_CODE vec4 r = roughness * c0 + c1; float ndotv = clamp(dot(normal, eye_vec), 0.0, 1.0); float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; - vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw; + vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - vec3 specular_color = metallic_to_specular_color(metallic, specular, albedo); - specular_light *= AB.x * specular_color + AB.y; + vec3 f0 = F0(metallic, specular, albedo); + specular_light *= env.x * f0 + env.y; #endif } diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl index dd6d78849b..80ad003c80 100644 --- a/drivers/gles3/shaders/tonemap.glsl +++ b/drivers/gles3/shaders/tonemap.glsl @@ -124,13 +124,16 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) { #endif vec3 tonemap_filmic(vec3 color, float white) { - const float A = 0.15f; - const float B = 0.50f; + // exposure bias: input scale (color *= bias, white *= bias) to make the brighness consistent with other tonemappers + // also useful to scale the input to the range that the tonemapper is designed for (some require very high input values) + // has no effect on the curve's general shape or visual properties + const float exposure_bias = 2.0f; + const float A = 0.22f * exposure_bias * exposure_bias; // bias baked into constants for performance + const float B = 0.30f * exposure_bias; const float C = 0.10f; const float D = 0.20f; - const float E = 0.02f; + const float E = 0.01f; const float F = 0.30f; - const float W = 11.2f; vec3 color_tonemapped = ((color * (A * color + C * B) + D * E) / (color * (A * color + B) + D * F)) - E / F; float white_tonemapped = ((white * (A * white + C * B) + D * E) / (white * (A * white + B) + D * F)) - E / F; @@ -139,10 +142,11 @@ vec3 tonemap_filmic(vec3 color, float white) { } vec3 tonemap_aces(vec3 color, float white) { - const float A = 2.51f; - const float B = 0.03f; - const float C = 2.43f; - const float D = 0.59f; + const float exposure_bias = 0.85f; + const float A = 2.51f * exposure_bias * exposure_bias; + const float B = 0.03f * exposure_bias; + const float C = 2.43f * exposure_bias * exposure_bias; + const float D = 0.59f * exposure_bias; const float E = 0.14f; vec3 color_tonemapped = (color * (A * color + B)) / (color * (C * color + D) + E); @@ -151,8 +155,8 @@ vec3 tonemap_aces(vec3 color, float white) { return clamp(color_tonemapped / white_tonemapped, vec3(0.0f), vec3(1.0f)); } -vec3 tonemap_reindhart(vec3 color, float white) { - return clamp((color) / (1.0f + color) * (1.0f + (color / (white))), vec3(0.0f), vec3(1.0f)); // whitepoint is probably not in linear space here! +vec3 tonemap_reinhard(vec3 color, float white) { + return clamp((white * color + color) / (color * white + white), vec3(0.0f), vec3(1.0f)); } vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped input in range [0;1] @@ -161,8 +165,8 @@ vec3 linear_to_srgb(vec3 color) { // convert linear rgb to srgb, assumes clamped } vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always outputs clamped [0;1] color -#ifdef USE_REINDHART_TONEMAPPER - return tonemap_reindhart(color, white); +#ifdef USE_REINHARD_TONEMAPPER + return tonemap_reinhard(color, white); #endif #ifdef USE_FILMIC_TONEMAPPER |