summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dummy/rasterizer_dummy.h1
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp26
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp38
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h6
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp28
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h5
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp10
-rw-r--r--drivers/gles2/shaders/scene.glsl54
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp6
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h2
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp1
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl2
-rw-r--r--drivers/gles3/shaders/scene.glsl59
14 files changed, 192 insertions, 48 deletions
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index 3b31da1dd7..253936ca34 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -692,6 +692,7 @@ public:
/* RENDER TARGET */
RID render_target_create() { return RID(); }
+ void render_target_set_position(RID p_render_target, int p_x, int p_y) {}
void render_target_set_size(RID p_render_target, int p_width, int p_height) {}
RID render_target_get_texture(RID p_render_target) const { return RID(); }
void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {}
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 7232d2d95a..ee722e9d6c 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -113,9 +113,22 @@ void RasterizerCanvasGLES2::canvas_begin() {
state.canvas_shader.bind();
state.using_transparent_rt = false;
+ int viewport_x, viewport_y, viewport_width, viewport_height;
+
if (storage->frame.current_rt) {
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
state.using_transparent_rt = storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
+
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
+ // set Viewport and Scissor when rendering directly to screen
+ viewport_width = storage->frame.current_rt->width;
+ viewport_height = storage->frame.current_rt->height;
+ viewport_x = storage->frame.current_rt->x;
+ viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y;
+ glScissor(viewport_x, viewport_y, viewport_width, viewport_height);
+ glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
+ glEnable(GL_SCISSOR_TEST);
+ }
}
if (storage->frame.clear_request) {
@@ -179,6 +192,14 @@ void RasterizerCanvasGLES2::canvas_end() {
glDisableVertexAttribArray(i);
}
+ if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
+ //reset viewport to full window size
+ int viewport_width = OS::get_singleton()->get_window_size().width;
+ int viewport_height = OS::get_singleton()->get_window_size().height;
+ glViewport(0, 0, viewport_width, viewport_height);
+ glScissor(0, 0, viewport_width, viewport_height);
+ }
+
state.using_texture_rect = false;
state.using_skeleton = false;
state.using_ninepatch = false;
@@ -1192,6 +1213,11 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
void RasterizerCanvasGLES2::_copy_screen(const Rect2 &p_rect) {
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
+ ERR_PRINT_ONCE("Cannot use screen texture copying in render target set to render direct to screen");
+ return;
+ }
+
if (storage->frame.current_rt->copy_screen_effect.color == 0) {
ERR_EXPLAIN("Can't use screen texture copying in a render target configured without copy buffers");
ERR_FAIL();
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 2d9eec10d2..83e1196979 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -1011,7 +1011,7 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
has_alpha = false;
}
- RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element();
+ RenderList::Element *e = (has_alpha || p_material->shader->spatial.no_depth_test) ? render_list.add_alpha_element() : render_list.add_element();
if (!e) {
return;
@@ -2695,6 +2695,8 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
Environment *env = NULL;
int viewport_width, viewport_height;
+ int viewport_x = 0;
+ int viewport_y = 0;
bool probe_interior = false;
bool reverse_cull = false;
@@ -2734,6 +2736,13 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
viewport_width = storage->frame.current_rt->width;
viewport_height = storage->frame.current_rt->height;
+ viewport_x = storage->frame.current_rt->x;
+
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
+ viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y;
+ } else {
+ viewport_y = storage->frame.current_rt->y;
+ }
}
state.used_screen_texture = false;
@@ -2799,7 +2808,13 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
// other stuff
glBindFramebuffer(GL_FRAMEBUFFER, current_fb);
- glViewport(0, 0, viewport_width, viewport_height);
+ glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
+
+ if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
+
+ glScissor(viewport_x, viewport_y, viewport_width, viewport_height);
+ glEnable(GL_SCISSOR_TEST);
+ }
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
@@ -2834,6 +2849,10 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
+ glDisable(GL_SCISSOR_TEST);
+ }
+
glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
glBlendEquation(GL_FUNC_ADD);
@@ -2860,13 +2879,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
}
}
- if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT])) {
-
- if (sky && sky->panorama.is_valid()) {
- _draw_sky(sky, p_cam_projection, cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation);
- }
- }
-
if (probe_interior) {
env_radiance_tex = 0; //do not use radiance texture on interiors
state.default_ambient = Color(0, 0, 0, 1); //black as default ambient for interior
@@ -2877,6 +2889,14 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
render_list.sort_by_key(false);
_render_render_list(render_list.elements, render_list.element_count, cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, reverse_cull, false, false);
+ // then draw the sky after
+ if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT])) {
+
+ if (sky && sky->panorama.is_valid()) {
+ _draw_sky(sky, p_cam_projection, cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation);
+ }
+ }
+
if (storage->frame.current_rt && state.used_screen_texture) {
//copy screen texture
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index d805984dca..bd1a61688c 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -603,12 +603,10 @@ public:
struct SortByReverseDepthAndPriority {
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- uint32_t layer_A = uint32_t(A->sort_key >> SORT_KEY_PRIORITY_SHIFT);
- uint32_t layer_B = uint32_t(B->sort_key >> SORT_KEY_PRIORITY_SHIFT);
- if (layer_A == layer_B) {
+ if (A->priority == B->priority) {
return A->instance->depth > B->instance->depth;
} else {
- return layer_A < layer_B;
+ return A->priority < B->priority;
}
}
};
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index d709056709..c610f31bc1 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -4568,9 +4568,16 @@ void RasterizerStorageGLES2::instance_remove_dependency(RID p_base, RasterizerSc
void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
+ // do not allocate a render target with no size
if (rt->width <= 0 || rt->height <= 0)
return;
+ // do not allocate a render target that is attached to the screen
+ if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
+ rt->fbo = RasterizerStorageGLES2::system_fbo;
+ return;
+ }
+
GLuint color_internal_format;
GLuint color_format;
GLuint color_type = GL_UNSIGNED_BYTE;
@@ -4779,6 +4786,10 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
+ // there is nothing to clear when DIRECT_TO_SCREEN is used
+ if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN])
+ return;
+
if (rt->fbo) {
glDeleteFramebuffers(1, &rt->fbo);
glDeleteTextures(1, &rt->color);
@@ -4873,6 +4884,15 @@ RID RasterizerStorageGLES2::render_target_create() {
return render_target_owner.make_rid(rt);
}
+void RasterizerStorageGLES2::render_target_set_position(RID p_render_target, int p_x, int p_y) {
+
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->x = p_x;
+ rt->y = p_y;
+}
+
void RasterizerStorageGLES2::render_target_set_size(RID p_render_target, int p_width, int p_height) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
@@ -5002,6 +5022,14 @@ void RasterizerStorageGLES2::render_target_set_flag(RID p_render_target, RenderT
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
+ // When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as
+ // those functions change how they operate depending on the value of DIRECT_TO_SCREEN
+ if (p_flag == RENDER_TARGET_DIRECT_TO_SCREEN && p_value != rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) {
+ _render_target_clear(rt);
+ rt->flags[p_flag] = p_value;
+ _render_target_allocate(rt);
+ }
+
rt->flags[p_flag] = p_value;
switch (p_flag) {
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index 3134082e2a..af57aa3d9b 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -1175,7 +1175,7 @@ public:
}
} external;
- int width, height;
+ int x, y, width, height;
bool flags[RENDER_TARGET_FLAG_MAX];
@@ -1192,6 +1192,8 @@ public:
multisample_color(0),
multisample_depth(0),
multisample_active(false),
+ x(0),
+ y(0),
width(0),
height(0),
used_in_frame(false),
@@ -1209,6 +1211,7 @@ public:
void _render_target_allocate(RenderTarget *rt);
virtual RID render_target_create();
+ virtual void render_target_set_position(RID p_render_target, int p_x, int p_y);
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height);
virtual RID render_target_get_texture(RID p_render_target) const;
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id);
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index d00b03fb8a..9778d39a21 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -316,9 +316,14 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = snode->uniforms.front(); E; E = E->next()) {
StringBuffer<> uniform_code;
- uniform_code += "uniform ";
+ // use highp if no precision is specified to prevent different default values in fragment and vertex shader
+ SL::DataPrecision precision = E->get().precision;
+ if (precision == SL::PRECISION_DEFAULT) {
+ precision = SL::PRECISION_HIGHP;
+ }
- uniform_code += _prestr(E->get().precision);
+ uniform_code += "uniform ";
+ uniform_code += _prestr(precision);
uniform_code += _typestr(E->get().type);
uniform_code += " ";
uniform_code += _mkid(E->key());
@@ -934,6 +939,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
// No defines for particle shaders in GLES2, there are no GPU particles
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 0fa290e57c..2aef913ae8 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -1151,7 +1151,8 @@ void light_compute(
float clearcoat_gloss,
float anisotropy,
inout vec3 diffuse_light,
- inout vec3 specular_light) {
+ inout vec3 specular_light,
+ inout float alpha) {
//this makes lights behave closer to linear, but then addition of lights looks bad
//better left disabled
@@ -1306,10 +1307,10 @@ LIGHT_SHADER_CODE
// shlick+ggx as default
#if defined(LIGHT_USE_ANISOTROPY)
- float alpha = roughness * roughness;
+ float alpha_ggx = roughness * roughness;
float aspect = sqrt(1.0 - anisotropy * 0.9);
- float ax = alpha / aspect;
- float ay = alpha * aspect;
+ float ax = alpha_ggx / aspect;
+ float ay = alpha_ggx * aspect;
float XdotH = dot(T, H);
float YdotH = dot(B, H);
float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH, cNdotH);
@@ -1317,10 +1318,10 @@ LIGHT_SHADER_CODE
float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL);
#else
- float alpha = roughness * roughness;
- float D = D_GGX(cNdotH, alpha);
- //float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
- float G = V_GGX(cNdotL, cNdotV, alpha);
+ float alpha_ggx = roughness * roughness;
+ float D = D_GGX(cNdotH, alpha_ggx);
+ //float G = G_GGX_2cos(cNdotL, alpha_ggx) * G_GGX_2cos(cNdotV, alpha_ggx);
+ float G = V_GGX(cNdotL, cNdotV, alpha_ggx);
#endif
// F
vec3 f0 = F0(metallic, specular, diffuse_color);
@@ -1350,6 +1351,10 @@ LIGHT_SHADER_CODE
#endif
}
+#ifdef USE_SHADOW_TO_OPACITY
+ alpha = min(alpha, clamp(1.0 - length(attenuation), 0.0, 1.0));
+#endif
+
#endif //defined(USE_LIGHT_SHADER_CODE)
}
@@ -1535,17 +1540,21 @@ FRAGMENT_SHADER_CODE
vec3 eye_position = view;
+#if !defined(USE_SHADOW_TO_OPACITY)
+
#if defined(ALPHA_SCISSOR_USED)
if (alpha < alpha_scissor) {
discard;
}
-#endif
+#endif // ALPHA_SCISSOR_USED
#ifdef USE_DEPTH_PREPASS
if (alpha < 0.99) {
discard;
}
-#endif
+#endif // USE_DEPTH_PREPASS
+
+#endif // !USE_SHADOW_TO_OPACITY
#ifdef BASE_PASS
//none
@@ -2061,13 +2070,32 @@ FRAGMENT_SHADER_CODE
clearcoat_gloss,
anisotropy,
diffuse_light,
- specular_light);
+ specular_light,
+ alpha);
#endif //vertex lighting
#endif //USE_LIGHTING
//compute and merge
+#ifdef USE_SHADOW_TO_OPACITY
+
+ alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
+
+#if defined(ALPHA_SCISSOR_USED)
+ if (alpha < alpha_scissor) {
+ discard;
+ }
+#endif // ALPHA_SCISSOR_USED
+
+#ifdef USE_DEPTH_PREPASS
+ if (alpha < 0.99) {
+ discard;
+ }
+#endif // USE_DEPTH_PREPASS
+
+#endif // !USE_SHADOW_TO_OPACITY
+
#ifndef RENDER_DEPTH
#ifdef SHADELESS
@@ -2105,8 +2133,6 @@ FRAGMENT_SHADER_CODE
#endif
// gl_FragColor = vec4(normal, 1.0);
-#endif //unshaded
-
//apply fog
#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
@@ -2161,6 +2187,8 @@ FRAGMENT_SHADER_CODE
#endif // defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
+#endif //unshaded
+
#else // not RENDER_DEPTH
//depth render
#ifdef USE_RGBA_SHADOWS
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 9aec348291..4552fddfe8 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -2374,7 +2374,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
has_alpha = false;
}
- RenderList::Element *e = has_alpha ? render_list.add_alpha_element() : render_list.add_element();
+ RenderList::Element *e = (has_alpha || p_material->shader->spatial.no_depth_test) ? render_list.add_alpha_element() : render_list.add_element();
if (!e)
return;
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 661be28e6b..8311d0de84 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -7268,6 +7268,10 @@ RID RasterizerStorageGLES3::render_target_create() {
return render_target_owner.make_rid(rt);
}
+void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int p_x, int p_y) {
+ //only used in GLES2
+}
+
void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_width, int p_height) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
@@ -8154,7 +8158,7 @@ void RasterizerStorageGLES3::initialize() {
}
shaders.cubemap_filter.init();
- bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx.mobile");
+ bool ggx_hq = GLOBAL_GET("rendering/quality/reflections/high_quality_ggx");
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, !ggx_hq);
shaders.particles.init();
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index a4cc84ef02..3d86558407 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -297,6 +297,7 @@ public:
target(GL_TEXTURE_2D),
data_size(0),
compressed(false),
+ srgb(false),
total_data_size(0),
ignore_mipmaps(false),
mipmaps(0),
@@ -1394,6 +1395,7 @@ public:
void _render_target_allocate(RenderTarget *rt);
virtual RID render_target_create();
+ virtual void render_target_set_position(RID p_render_target, int p_x, int p_y);
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height);
virtual RID render_target_get_texture(RID p_render_target) const;
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id);
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index ad26294527..e8417900ea 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -944,6 +944,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
/* PARTICLES SHADER */
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index f65f798ff0..619e29b130 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -163,7 +163,7 @@ vec2 Hammersley(uint i, uint N) {
#else
-#define SAMPLE_COUNT 512u
+#define SAMPLE_COUNT 1024u
#endif
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 584668a09c..f08d3f4d23 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -993,7 +993,7 @@ vec3 F0(float metallic, float specular, vec3 albedo) {
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 specular, 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, inout float alpha) {
#if defined(USE_LIGHT_SHADER_CODE)
// light is written by the light shader
@@ -1135,19 +1135,19 @@ LIGHT_SHADER_CODE
#if defined(LIGHT_USE_ANISOTROPY)
- float alpha = roughness * roughness;
+ float alpha_ggx = roughness * roughness;
float aspect = sqrt(1.0 - anisotropy * 0.9);
- float ax = alpha / aspect;
- float ay = alpha * aspect;
+ float ax = alpha_ggx / aspect;
+ float ay = alpha_ggx * aspect;
float XdotH = dot(T, H);
float YdotH = dot(B, H);
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
- float alpha = roughness * roughness;
- float D = D_GGX(cNdotH, alpha);
- float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
+ float alpha_ggx = roughness * roughness;
+ float D = D_GGX(cNdotH, alpha_ggx);
+ float G = G_GGX_2cos(cNdotL, alpha_ggx) * G_GGX_2cos(cNdotV, alpha_ggx);
#endif
// F
vec3 f0 = F0(metallic, specular, diffuse_color);
@@ -1174,6 +1174,10 @@ LIGHT_SHADER_CODE
#endif
}
+#ifdef USE_SHADOW_TO_OPACITY
+ alpha = min(alpha, clamp(1.0 - length(attenuation), 0.0, 1.0));
+#endif
+
#endif //defined(USE_LIGHT_SHADER_CODE)
}
@@ -1250,7 +1254,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 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) {
+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, inout float alpha) {
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz - vertex;
float light_length = length(light_rel_vec);
@@ -1304,10 +1308,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, specular, 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, alpha);
}
-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) {
+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, inout float alpha) {
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz - vertex;
float light_length = length(light_rel_vec);
@@ -1339,7 +1343,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, specular, 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, alpha);
}
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) {
@@ -1705,11 +1709,13 @@ FRAGMENT_SHADER_CODE
/* clang-format on */
}
+#if !defined(USE_SHADOW_TO_OPACITY)
+
#if defined(ALPHA_SCISSOR_USED)
if (alpha < alpha_scissor) {
discard;
}
-#endif
+#endif // ALPHA_SCISSOR_USED
#ifdef USE_OPAQUE_PREPASS
@@ -1717,7 +1723,9 @@ FRAGMENT_SHADER_CODE
discard;
}
-#endif
+#endif // USE_OPAQUE_PREPASS
+
+#endif // !USE_SHADOW_TO_OPACITY
#if defined(ENABLE_NORMALMAP)
@@ -2044,7 +2052,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, specular, 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, alpha);
#endif
#endif //#USE_LIGHT_DIRECTIONAL
@@ -2057,17 +2065,36 @@ 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, specular, 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, alpha);
}
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, specular, 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, alpha);
}
#endif //USE_VERTEX_LIGHTING
#endif
+#ifdef USE_SHADOW_TO_OPACITY
+ alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
+
+#if defined(ALPHA_SCISSOR_USED)
+ if (alpha < alpha_scissor) {
+ discard;
+ }
+#endif // ALPHA_SCISSOR_USED
+
+#ifdef USE_OPAQUE_PREPASS
+
+ if (alpha < opaque_prepass_threshold) {
+ discard;
+ }
+
+#endif // USE_OPAQUE_PREPASS
+
+#endif // USE_SHADOW_TO_OPACITY
+
#ifdef RENDER_DEPTH
//nothing happens, so a tree-ssa optimizer will result in no fragment shader :)
#else