summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp26
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h10
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp3
-rw-r--r--drivers/gles3/shaders/scene.glsl125
-rw-r--r--drivers/gles3/shaders/ssao.glsl24
-rw-r--r--drivers/gles3/shaders/ssao_blur.glsl20
6 files changed, 126 insertions, 82 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 39f027a5aa..ddcb04fa7d 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -895,7 +895,7 @@ void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_m
env->ssr_roughness = p_roughness;
}
-void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) {
+void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VisualServer::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -909,6 +909,8 @@ void RasterizerSceneGLES3::environment_set_ssao(RID p_env, bool p_enable, float
env->ssao_light_affect = p_light_affect;
env->ssao_color = p_color;
env->ssao_filter = p_blur;
+ env->ssao_quality = p_quality;
+ env->ssao_bilateral_sharpness = p_bilateral_sharpness;
}
void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) {
@@ -3186,6 +3188,15 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
+ if (env->ssao_enabled || env->ssr_enabled) {
+
+ //copy normal and roughness to effect buffer
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
+ glReadBuffer(GL_COLOR_ATTACHMENT2);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_fbo);
+ glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ }
+
if (env->ssao_enabled) {
//copy diffuse to front buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
@@ -3235,6 +3246,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
// do SSAO!
state.ssao_shader.set_conditional(SsaoShaderGLES3::ENABLE_RADIUS2, env->ssao_radius2 > 0.001);
state.ssao_shader.set_conditional(SsaoShaderGLES3::USE_ORTHOGONAL_PROJECTION, p_cam_projection.is_orthogonal());
+ state.ssao_shader.set_conditional(SsaoShaderGLES3::SSAO_QUALITY_LOW, env->ssao_quality == VS::ENV_SSAO_QUALITY_LOW);
+ state.ssao_shader.set_conditional(SsaoShaderGLES3::SSAO_QUALITY_HIGH, env->ssao_quality == VS::ENV_SSAO_QUALITY_HIGH);
state.ssao_shader.bind();
state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far());
state.ssao_shader.set_uniform(SsaoShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
@@ -3287,6 +3300,9 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::CAMERA_Z_FAR, p_cam_projection.get_z_far());
state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::CAMERA_Z_NEAR, p_cam_projection.get_z_near());
+ state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::EDGE_SHARPNESS, env->ssao_bilateral_sharpness);
+ state.ssao_blur_shader.set_uniform(SsaoBlurShaderGLES3::FILTER_SCALE, int(env->ssao_filter));
+
GLint axis[2] = { i, 1 - i };
glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::AXIS), 1, axis);
glUniform2iv(state.ssao_blur_shader.get_uniform(SsaoBlurShaderGLES3::SCREEN_SIZE), 1, ss);
@@ -3295,6 +3311,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[i]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->buffers.effect);
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.ssao.blur_fbo[1 - i]);
if (i == 0) {
glClearBufferfv(GL_COLOR, 0, white.components); // specular
@@ -3386,12 +3404,6 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
if (env->ssr_enabled) {
- //copy normal and roughness to effect buffer
- glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
- glReadBuffer(GL_COLOR_ATTACHMENT2);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_fbo);
- glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
-
//blur diffuse into effect mipmaps using separatable convolution
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
_blur_effect_buffer();
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 28a5cef0ee..ff691ddcec 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -379,7 +379,9 @@ public:
float ssao_bias;
float ssao_light_affect;
Color ssao_color;
- bool ssao_filter;
+ VS::EnvironmentSSAOQuality ssao_quality;
+ float ssao_bilateral_sharpness;
+ VS::EnvironmentSSAOBlur ssao_filter;
bool glow_enabled;
int glow_levels;
@@ -456,7 +458,9 @@ public:
ssao_radius2 = 0.0;
ssao_bias = 0.01;
ssao_light_affect = 0;
- ssao_filter = true;
+ ssao_filter = VS::ENV_SSAO_BLUR_3x3;
+ ssao_quality = VS::ENV_SSAO_QUALITY_LOW;
+ ssao_bilateral_sharpness = 4;
tone_mapper = VS::ENV_TONE_MAPPER_LINEAR;
tone_mapper_exposure = 1.0;
@@ -532,7 +536,7 @@ public:
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture);
virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness);
- virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur);
+ virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, VS::EnvironmentSSAOQuality p_quality, VS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness);
virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 44a9909bd7..296d945cda 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -2430,7 +2430,8 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
if (material->shader && material->shader->mode == VS::SHADER_SPATIAL) {
- if (!material->shader->spatial.uses_alpha && material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX) {
+ if (material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX &&
+ (!material->shader->spatial.uses_alpha || (material->shader->spatial.uses_alpha && material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))) {
can_cast_shadow = true;
}
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 2c6dd5552e..e4d76753cb 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -940,7 +940,7 @@ vec3 metallic_to_specular_color(float metallic, float specular, vec3 albedo) {
return mix(vec3(dielectric), albedo, metallic); // TODO: reference?
}
-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 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 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
@@ -959,80 +959,82 @@ LIGHT_SHADER_CODE
float NdotV = dot(N, V);
float cNdotV = max(NdotV, 0.0);
+ if (metallic < 1.0) {
#if defined(DIFFUSE_OREN_NAYAR)
- vec3 diffuse_brdf_NL;
+ vec3 diffuse_brdf_NL;
#else
- float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance
+ float diffuse_brdf_NL; // BRDF times N.L for calculating diffuse radiance
#endif
#if defined(DIFFUSE_LAMBERT_WRAP)
- //energy conserving lambert wrap shader
- diffuse_brdf_NL = max(0.0,(NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
+ //energy conserving lambert wrap shader
+ diffuse_brdf_NL = max(0.0,(NdotL + roughness) / ((1.0 + roughness) * (1.0 + roughness)));
#elif defined(DIFFUSE_OREN_NAYAR)
- {
- // see http://mimosa-pudica.net/improved-oren-nayar.html
- float LdotV = dot(L, V);
+ {
+ // see http://mimosa-pudica.net/improved-oren-nayar.html
+ float LdotV = dot(L, V);
- float s = LdotV - NdotL * NdotV;
- float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
+ float s = LdotV - NdotL * NdotV;
+ float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
- float sigma2 = roughness * roughness; // TODO: this needs checking
- vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) );
- float B = 0.45 * sigma2 / (sigma2 + 0.09);
+ float sigma2 = roughness * roughness; // TODO: this needs checking
+ vec3 A = 1.0 + sigma2 * (- 0.5 / (sigma2 + 0.33) + 0.17*diffuse_color / (sigma2 + 0.13) );
+ float B = 0.45 * sigma2 / (sigma2 + 0.09);
- diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI);
- }
+ diffuse_brdf_NL = cNdotL * (A + vec3(B) * s / t) * (1.0 / M_PI);
+ }
#elif defined(DIFFUSE_TOON)
- diffuse_brdf_NL = smoothstep(-roughness,max(roughness,0.01),NdotL);
+ diffuse_brdf_NL = smoothstep(-roughness,max(roughness,0.01),NdotL);
#elif defined(DIFFUSE_BURLEY)
- {
+ {
- vec3 H = normalize(V + L);
- float cLdotH = max(0.0,dot(L, H));
+ vec3 H = normalize(V + L);
+ float cLdotH = max(0.0,dot(L, H));
- float FD90 = 0.5 + 2.0 * cLdotH * cLdotH * roughness;
- float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotV);
- float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotL);
- diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL;
-/*
- float energyBias = mix(roughness, 0.0, 0.5);
- float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
- float fd90 = energyBias + 2.0 * VoH * VoH * roughness;
- float f0 = 1.0;
- float lightScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotL, 5.0);
- float viewScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotV, 5.0);
-
- diffuse_brdf_NL = lightScatter * viewScatter * energyFactor;*/
- }
+ float FD90 = 0.5 + 2.0 * cLdotH * cLdotH * roughness;
+ float FdV = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotV);
+ float FdL = 1.0 + (FD90 - 1.0) * SchlickFresnel(cNdotL);
+ diffuse_brdf_NL = (1.0 / M_PI) * FdV * FdL * cNdotL;
+ /*
+ float energyBias = mix(roughness, 0.0, 0.5);
+ float energyFactor = mix(roughness, 1.0, 1.0 / 1.51);
+ float fd90 = energyBias + 2.0 * VoH * VoH * roughness;
+ float f0 = 1.0;
+ float lightScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotL, 5.0);
+ float viewScatter = f0 + (fd90 - f0) * pow(1.0 - cNdotV, 5.0);
+
+ diffuse_brdf_NL = lightScatter * viewScatter * energyFactor;*/
+ }
#else
- //lambert
- diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
+ //lambert
+ diffuse_brdf_NL = cNdotL * (1.0 / M_PI);
#endif
#if defined(TRANSMISSION_USED)
- diffuse_light += light_color * diffuse_color * mix(vec3(diffuse_brdf_NL), vec3(M_PI), transmission) * attenuation;
+ diffuse_light += light_color * diffuse_color * mix(vec3(diffuse_brdf_NL), vec3(M_PI), transmission) * attenuation;
#else
- diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation;
+ diffuse_light += light_color * diffuse_color * diffuse_brdf_NL * attenuation;
#endif
#if defined(LIGHT_USE_RIM)
- float rim_light = pow(1.0-cNdotV, (1.0-roughness)*16.0);
- diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
+ float rim_light = pow(1.0-cNdotV, (1.0-roughness)*16.0);
+ diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
#endif
+ }
- if (roughness > 0.0) {
+ if (roughness > 0.0) { // FIXME: roughness == 0 should not disable specular light entirely
// D
@@ -1071,7 +1073,7 @@ LIGHT_SHADER_CODE
float cNdotH = max(dot(N,H), 0.0);
float cLdotH = max(dot(L,H), 0.0);
-#if defined(LIGHT_USE_ANISOTROPY)
+# if defined(LIGHT_USE_ANISOTROPY)
float aspect = sqrt(1.0-anisotropy*0.9);
float rx = roughness/aspect;
@@ -1083,11 +1085,11 @@ LIGHT_SHADER_CODE
float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH);
float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
-#else
+# else
float alpha = roughness * roughness;
float D = D_GGX(cNdotH, alpha);
float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
-#endif
+# endif
// F
float F0 = 1.0; // FIXME
float cLdotH5 = SchlickFresnel(cLdotH);
@@ -1099,21 +1101,24 @@ LIGHT_SHADER_CODE
#endif
#if defined(LIGHT_USE_CLEARCOAT)
-
+ if (clearcoat_gloss > 0.0) {
# if !defined(SPECULAR_SCHLICK_GGX) && !defined(SPECULAR_BLINN)
- vec3 H = normalize(V + L);
+ vec3 H = normalize(V + L);
# endif
# if !defined(SPECULAR_SCHLICK_GGX)
- float cNdotH = max(dot(N,H), 0.0);
- float cLdotH = max(dot(L,H), 0.0);
- float cLdotH5 = SchlickFresnel(cLdotH);
+ float cNdotH = max(dot(N,H), 0.0);
+ float cLdotH = max(dot(L,H), 0.0);
+ float cLdotH5 = SchlickFresnel(cLdotH);
#endif
- float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss));
- float Fr = mix(.04, 1.0, cLdotH5);
- float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25);
+ float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss));
+ float Fr = mix(.04, 1.0, cLdotH5);
+ float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25);
- specular_light += .25*clearcoat*Gr*Fr*Dr;
+ float specular_brdf_NL = 0.25 * clearcoat * Gr * Fr * Dr * cNdotL;
+
+ specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
+ }
#endif
}
@@ -1195,7 +1200,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 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 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 );
@@ -1249,11 +1254,11 @@ void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 bino
light_attenuation*=mix(omni_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- 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,rim,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,rim,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 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 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 );
@@ -1283,7 +1288,7 @@ void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 bi
light_attenuation*=mix(spot_lights[idx].shadow_color_contact.rgb,vec3(1.0),shadow);
}
- 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,rim,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,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
@@ -1916,7 +1921,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,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,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
#endif
@@ -1954,11 +1959,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,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,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,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,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,specular_blob_intensity,diffuse_light,specular_light);
}
#endif //USE_VERTEX_LIGHTING
@@ -1985,7 +1990,7 @@ FRAGMENT_SHADER_CODE
//energy conservation
- diffuse_light *= 1.0-metallic; // TODO: avoid diffuse and ambient light calculations when metallic == 1
+ 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;
diff --git a/drivers/gles3/shaders/ssao.glsl b/drivers/gles3/shaders/ssao.glsl
index c668e63745..219f0957e0 100644
--- a/drivers/gles3/shaders/ssao.glsl
+++ b/drivers/gles3/shaders/ssao.glsl
@@ -13,8 +13,24 @@ void main() {
#define TWO_PI 6.283185307179586476925286766559
+#ifdef SSAO_QUALITY_HIGH
+
+#define NUM_SAMPLES (80)
+
+#endif
+
+#ifdef SSAO_QUALITY_LOW
+
#define NUM_SAMPLES (15)
+#endif
+
+#if !defined(SSAO_QUALITY_LOW) && !defined(SSAO_QUALITY_HIGH)
+
+#define NUM_SAMPLES (40)
+
+#endif
+
// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
// miplevel to maintain reasonable spatial locality in the cache
// If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing.
@@ -212,12 +228,12 @@ void main() {
//visibility=-C.z/camera_z_far;
//return;
-
- //vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
-
+#if 0
+ vec3 n_C = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
+#else
vec3 n_C = reconstructCSFaceNormal(C);
n_C = -n_C;
-
+#endif
// Hash function used in the HPG12 AlchemyAO paper
float randomPatternRotationAngle = mod(float((3 * ssC.x ^ ssC.y + ssC.x * ssC.y) * 10), TWO_PI);
diff --git a/drivers/gles3/shaders/ssao_blur.glsl b/drivers/gles3/shaders/ssao_blur.glsl
index c7c978dc37..472dc21acf 100644
--- a/drivers/gles3/shaders/ssao_blur.glsl
+++ b/drivers/gles3/shaders/ssao_blur.glsl
@@ -15,6 +15,7 @@ void main() {
uniform sampler2D source_ssao; //texunit:0
uniform sampler2D source_depth; //texunit:1
+uniform sampler2D source_normal; //texunit:3
layout(location = 0) out float visibility;
@@ -24,7 +25,7 @@ layout(location = 0) out float visibility;
// Tunable Parameters:
/** Increase to make depth edges crisper. Decrease to reduce flicker. */
-#define EDGE_SHARPNESS (4.0)
+uniform float edge_sharpness;
/** Step in 2-pixel intervals since we already blurred against neighbors in the
first AO pass. This constant can be increased while R decreases to improve
@@ -34,7 +35,8 @@ layout(location = 0) out float visibility;
unobjectionable after shading was applied but eliminated most temporal incoherence
from using small numbers of sample taps.
*/
-#define SCALE (3)
+
+uniform int filter_scale;
/** Filter radius in pixels. This will be multiplied by SCALE. */
#define R (4)
@@ -63,13 +65,14 @@ void main() {
ivec2 ssC = ivec2(gl_FragCoord.xy);
float depth = texelFetch(source_depth, ssC, 0).r;
+ //vec3 normal = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
depth = depth * 2.0 - 1.0;
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
float depth_divide = 1.0 / camera_z_far;
- depth*=depth_divide;
+// depth*=depth_divide;
/*
if (depth > camera_z_far*0.999) {
@@ -92,20 +95,23 @@ void main() {
// so the IF statement has no runtime cost
if (r != 0) {
- ivec2 ppos = ssC + axis * (r * SCALE);
+ ivec2 ppos = ssC + axis * (r * filter_scale);
float value = texelFetch(source_ssao, clamp(ppos,ivec2(0),clamp_limit), 0).r;
- float temp_depth = texelFetch(source_depth, clamp(ssC,ivec2(0),clamp_limit), 0).r;
+ ivec2 rpos = clamp(ppos,ivec2(0),clamp_limit);
+ float temp_depth = texelFetch(source_depth, rpos, 0).r;
+ //vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0;
temp_depth = temp_depth * 2.0 - 1.0;
temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near));
- temp_depth *= depth_divide;
+// temp_depth *= depth_divide;
// spatial domain: offset gaussian tap
float weight = 0.3 + gaussian[abs(r)];
+ //weight *= max(0.0,dot(temp_normal,normal));
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
weight *= max(0.0, 1.0
- - (EDGE_SHARPNESS * 2000.0) * abs(temp_depth - depth)
+ - edge_sharpness * abs(temp_depth - depth)
);
sum += value * weight;