diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-08-19 20:06:40 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-08-19 20:07:21 -0300 |
commit | 7e5890d23d882547ae465fb7756b74be5bc1f62b (patch) | |
tree | d9e2fa279f9c8ecb9cc2c57164416e9224f66a09 /drivers | |
parent | a80371ce0a2e0f5d64e3fa9b6bbf8dba75724164 (diff) |
-Fix all shadow and culling related issues, fixes #9330
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 38 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 4 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 10 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 2 |
4 files changed, 46 insertions, 8 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index ac6ca1ec0c..6e8303563f 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1088,11 +1088,12 @@ void RasterizerSceneGLES3::gi_probe_instance_set_bounds(RID p_probe, const Vecto bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass) { + /* this is handled outside if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_DISABLED) { glDisable(GL_CULL_FACE); } else { glEnable(GL_CULL_FACE); - } + } */ if (state.current_line_width != p_material->line_width) { //glLineWidth(MAX(p_material->line_width,1.0)); @@ -1857,12 +1858,21 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform } } -void RasterizerSceneGLES3::_set_cull(bool p_front, bool p_reverse_cull) { +void RasterizerSceneGLES3::_set_cull(bool p_front, bool p_disabled, bool p_reverse_cull) { bool front = p_front; if (p_reverse_cull) front = !front; + if (p_disabled != state.cull_disabled) { + if (p_disabled) + glDisable(GL_CULL_FACE); + else + glEnable(GL_CULL_FACE); + + state.cull_disabled = p_disabled; + } + if (front != state.cull_front) { glCullFace(front ? GL_FRONT : GL_BACK); @@ -1900,7 +1910,9 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ } state.cull_front = false; + state.cull_disabled = false; glCullFace(GL_BACK); + glEnable(GL_CULL_FACE); state.current_depth_test = true; glEnable(GL_DEPTH_TEST); @@ -2101,7 +2113,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ storage->info.render.surface_switch_count++; } - _set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, p_reverse_cull); + _set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, e->sort_key & RenderList::SORT_KEY_CULL_DISABLED_FLAG, p_reverse_cull); state.scene_shader.set_uniform(SceneShaderGLES3::NORMAL_MULT, e->instance->mirror ? -1.0 : 1.0); state.scene_shader.set_uniform(SceneShaderGLES3::WORLD_TRANSFORM, e->instance->transform); @@ -2188,8 +2200,12 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G bool shadow = false; bool mirror = p_instance->mirror; + bool no_cull = false; - if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_FRONT) { + if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_DISABLED) { + no_cull = true; + mirror = false; + } else if (p_material->shader->spatial.cull_mode == RasterizerStorageGLES3::Shader::Spatial::CULL_MODE_FRONT) { mirror = !mirror; } @@ -2208,10 +2224,13 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { //shader does not use discard and does not write a vertex position, use generic material - if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) + if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) { p_material = storage->material_owner.getptr(default_material_twosided); - else + no_cull = true; + mirror = false; + } else { p_material = storage->material_owner.getptr(default_material); + } } has_alpha = false; @@ -2275,6 +2294,10 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G e->sort_key |= RenderList::SORT_KEY_MIRROR_FLAG; } + if (no_cull) { + e->sort_key |= RenderList::SORT_KEY_CULL_DISABLED_FLAG; + } + //e->light_type=0xFF; // no lights! if (shadow || p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) { @@ -4535,6 +4558,9 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, true); + if (light->reverse_cull) { + flip_facing = !flip_facing; + } _render_list(render_list.elements, render_list.element_count, light_transform, light_projection, 0, flip_facing, false, true, false, false); state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, false); diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index e1d96f23dd..740d277a3a 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -187,6 +187,7 @@ public: int reflection_probe_count; bool cull_front; + bool cull_disabled; bool used_sss; bool used_screen_texture; bool using_contact_shadows; @@ -654,6 +655,7 @@ public: SORT_KEY_MATERIAL_INDEX_SHIFT = 40, SORT_KEY_GEOMETRY_INDEX_SHIFT = 20, SORT_KEY_GEOMETRY_TYPE_SHIFT = 15, + SORT_KEY_CULL_DISABLED_FLAG = 4, SORT_KEY_SKELETON_FLAG = 2, SORT_KEY_MIRROR_FLAG = 1 @@ -779,7 +781,7 @@ public: RenderList render_list; - _FORCE_INLINE_ void _set_cull(bool p_front, bool p_reverse_cull); + _FORCE_INLINE_ void _set_cull(bool p_front, bool p_disabled, bool p_reverse_cull); _FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES3::Material *p_material, bool p_alpha_pass); _FORCE_INLINE_ void _setup_geometry(RenderList::Element *e, const Transform &p_view_transform); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 8dd083fbe8..11d5bcb207 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -4451,7 +4451,7 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) { light->omni_shadow_mode = VS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID; light->omni_shadow_detail = VS::LIGHT_OMNI_SHADOW_DETAIL_VERTICAL; light->directional_blend_splits = false; - + light->reverse_cull = false; light->version = 0; return light_owner.make_rid(light); @@ -4530,6 +4530,14 @@ void RasterizerStorageGLES3::light_set_cull_mask(RID p_light, uint32_t p_mask) { light->instance_change_notify(); } +void RasterizerStorageGLES3::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) { + + Light *light = light_owner.getornull(p_light); + ERR_FAIL_COND(!light); + + light->reverse_cull = p_enabled; +} + void RasterizerStorageGLES3::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) { Light *light = light_owner.getornull(p_light); diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 3c7ea000ba..f612d9e879 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -868,6 +868,7 @@ public: RID projector; bool shadow; bool negative; + bool reverse_cull; uint32_t cull_mask; VS::LightOmniShadowMode omni_shadow_mode; VS::LightOmniShadowDetail omni_shadow_detail; @@ -887,6 +888,7 @@ public: virtual void light_set_projector(RID p_light, RID p_texture); virtual void light_set_negative(RID p_light, bool p_enable); virtual void light_set_cull_mask(RID p_light, uint32_t p_mask); + virtual void light_set_reverse_cull_face_mode(RID p_light, bool p_enabled); virtual void light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode); virtual void light_omni_set_shadow_detail(RID p_light, VS::LightOmniShadowDetail p_detail); |