diff options
author | Juan Linietsky <reduzio@gmail.com> | 2019-01-22 10:04:25 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2019-01-22 10:05:23 -0300 |
commit | 46af4b0a4b73a14f01a1aba9b0a8ab0bef05252a (patch) | |
tree | 54c7cac58401e07277910e3a1f1fb459748fd16c | |
parent | 6ab16512eb7dd8ec336b75cdaac396dfa661d0e7 (diff) |
Changes to GLES2 renderer to not use cube shadows if not available, fixes #25132
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.cpp | 4 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_scene_gles2.h | 1 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.cpp | 7 | ||||
-rw-r--r-- | drivers/gles2/rasterizer_storage_gles2.h | 1 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 1 | ||||
-rw-r--r-- | servers/visual/rasterizer.h | 1 | ||||
-rw-r--r-- | servers/visual/visual_server_scene.cpp | 164 |
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; |