summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp4
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h1
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp7
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h1
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp1
-rw-r--r--servers/visual/rasterizer.h1
-rw-r--r--servers/visual/visual_server_scene.cpp164
7 files changed, 93 insertions, 86 deletions
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 9a514a9267..bd6fe781f0 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -2877,7 +2877,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
if (light->type == VS::LIGHT_OMNI) {
// cubemap only
- if (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE) {
+ if (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_write_depth) {
int cubemap_index = shadow_cubemaps.size() - 1;
// find an appropriate cubemap to render to
@@ -2973,7 +2973,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH_DUAL_PARABOLOID, false);
// convert cubemap to dual paraboloid if needed
- if (light->type == VS::LIGHT_OMNI && light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && p_pass == 5) {
+ if (light->type == VS::LIGHT_OMNI && (light->omni_shadow_mode == VS::LIGHT_OMNI_SHADOW_CUBE && storage->config.support_write_depth) && p_pass == 5) {
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
glBindFramebuffer(GL_FRAMEBUFFER, shadow_atlas->fbo);
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index 42ac621e45..0d917f4da2 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -473,6 +473,7 @@ public:
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
virtual void light_instance_mark_visible(RID p_light_instance);
+ virtual bool light_instances_can_render_shadow_cube() const { return storage->config.support_write_depth; }
LightInstance **render_light_instances;
int render_directional_lights;
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 430b93bac8..0d643370e0 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -4673,6 +4673,13 @@ void RasterizerStorageGLES2::initialize() {
config.support_32_bits_indices = config.extensions.has("GL_OES_element_index_uint");
#endif
+#ifdef GLES_OVER_GL
+ config.support_write_depth = true;
+#else
+ config.support_write_depth = config.extensions.has("GL_EXT_frag_depth");
+#endif
+
+
frame.count = 0;
frame.delta = 0;
frame.current_rt = NULL;
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index ae14aaa9c0..0e0804eef2 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -80,6 +80,7 @@ public:
bool use_rgba_2d_shadows;
bool support_32_bits_indices;
+ bool support_write_depth;
} config;
struct Resources {
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 1fba8535d8..02dbe096c5 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1832,6 +1832,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
storage->info.render.vertices_count += s->index_array_len * amount;
} else
#endif
+
if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 394592ec64..6f8a30070a 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -141,6 +141,7 @@ public:
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0;
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
+ virtual bool light_instances_can_render_shadow_cube() const { return true; }
virtual RID reflection_atlas_create() = 0;
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_size) = 0;
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 53e8d6a030..23ad2ec1ec 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1535,106 +1535,102 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
VS::LightOmniShadowMode shadow_mode = VSG::storage->light_omni_get_shadow_mode(p_instance->base);
- switch (shadow_mode) {
- case VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID: {
+ if (shadow_mode == VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !VSG::scene_render->light_instances_can_render_shadow_cube()) {
- for (int i = 0; i < 2; i++) {
+ for (int i = 0; i < 2; i++) {
- //using this one ensures that raster deferred will have it
+ //using this one ensures that raster deferred will have it
- float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
-
- float z = i == 0 ? -1 : 1;
- Vector<Plane> planes;
- planes.resize(5);
- planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
- planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
- planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
- planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
- planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
-
- int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
- Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
-
- for (int j = 0; j < cull_count; j++) {
-
- Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
- cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
- j--;
- } else {
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
+ float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
+ float z = i == 0 ? -1 : 1;
+ Vector<Plane> planes;
+ planes.resize(5);
+ planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
+ planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
+ planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
+ planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
+ planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
+
+ int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
+
+ for (int j = 0; j < cull_count; j++) {
+
+ Instance *instance = instance_shadow_cull_result[j];
+ if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
+ cull_count--;
+ SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
+ j--;
+ } else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
}
- }
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i);
- VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
+ }
}
- } break;
- case VS::LIGHT_OMNI_SHADOW_CUBE: {
-
- float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
- CameraMatrix cm;
- cm.set_perspective(90, 1, 0.01, radius);
-
- for (int i = 0; i < 6; i++) {
- //using this one ensures that raster deferred will have it
-
- static const Vector3 view_normals[6] = {
- Vector3(-1, 0, 0),
- Vector3(+1, 0, 0),
- Vector3(0, -1, 0),
- Vector3(0, +1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, +1)
- };
- static const Vector3 view_up[6] = {
- Vector3(0, -1, 0),
- Vector3(0, -1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, +1),
- Vector3(0, -1, 0),
- Vector3(0, -1, 0)
- };
-
- Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]);
-
- Vector<Plane> planes = cm.get_projection_planes(xform);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i);
+ VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
+ }
+ } else { //shadow cube
- int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ float radius = VSG::storage->light_get_param(p_instance->base, VS::LIGHT_PARAM_RANGE);
+ CameraMatrix cm;
+ cm.set_perspective(90, 1, 0.01, radius);
- Plane near_plane(xform.origin, -xform.basis.get_axis(2));
- for (int j = 0; j < cull_count; j++) {
+ for (int i = 0; i < 6; i++) {
- Instance *instance = instance_shadow_cull_result[j];
- if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
- cull_count--;
- SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
- j--;
- } else {
- if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
- animated_material_found = true;
- }
- instance->depth = near_plane.distance_to(instance->transform.origin);
- instance->depth_layer = 0;
+ //using this one ensures that raster deferred will have it
+
+ static const Vector3 view_normals[6] = {
+ Vector3(-1, 0, 0),
+ Vector3(+1, 0, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, +1, 0),
+ Vector3(0, 0, -1),
+ Vector3(0, 0, +1)
+ };
+ static const Vector3 view_up[6] = {
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0),
+ Vector3(0, 0, -1),
+ Vector3(0, 0, +1),
+ Vector3(0, -1, 0),
+ Vector3(0, -1, 0)
+ };
+
+ Transform xform = light_transform * Transform().looking_at(view_normals[i], view_up[i]);
+
+ Vector<Plane> planes = cm.get_projection_planes(xform);
+
+ int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+
+ Plane near_plane(xform.origin, -xform.basis.get_axis(2));
+ for (int j = 0; j < cull_count; j++) {
+
+ Instance *instance = instance_shadow_cull_result[j];
+ if (!instance->visible || !((1 << instance->base_type) & VS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
+ cull_count--;
+ SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
+ j--;
+ } else {
+ if (static_cast<InstanceGeometryData *>(instance->base_data)->material_is_animated) {
+ animated_material_found = true;
}
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
}
-
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i);
- VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
}
- //restore the regular DP matrix
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i);
+ VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
+ }
- } break;
+ //restore the regular DP matrix
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0);
}
} break;