diff options
Diffstat (limited to 'drivers/gles3/rasterizer_scene_gles3.cpp')
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 86 |
1 files changed, 61 insertions, 25 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 30a77c4b39..52c7327baf 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -120,7 +120,7 @@ void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas, int p_size) { ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); - p_size = nearest_power_of_2(p_size); + p_size = next_power_of_2(p_size); if (p_size == shadow_atlas->size) return; @@ -185,7 +185,7 @@ void RasterizerSceneGLES3::shadow_atlas_set_quadrant_subdivision(RID p_atlas, in ERR_FAIL_INDEX(p_quadrant, 4); ERR_FAIL_INDEX(p_subdivision, 16384); - uint32_t subdiv = nearest_power_of_2(p_subdivision); + uint32_t subdiv = next_power_of_2(p_subdivision); if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer subdiv <<= 1; } @@ -310,7 +310,7 @@ bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_in } uint32_t quad_size = shadow_atlas->size >> 1; - int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, nearest_power_of_2(quad_size * p_coverage)); + int desired_fit = MIN(quad_size / shadow_atlas->smallest_subdiv, next_power_of_2(quad_size * p_coverage)); int valid_quadrants[4]; int valid_quadrant_count = 0; @@ -479,7 +479,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_size ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas); ERR_FAIL_COND(!reflection_atlas); - int size = nearest_power_of_2(p_size); + int size = next_power_of_2(p_size); if (size == reflection_atlas->size) return; @@ -554,7 +554,7 @@ void RasterizerSceneGLES3::reflection_atlas_set_subdivision(RID p_ref_atlas, int ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_ref_atlas); ERR_FAIL_COND(!reflection_atlas); - uint32_t subdiv = nearest_power_of_2(p_subdiv); + uint32_t subdiv = next_power_of_2(p_subdiv); if (subdiv & 0xaaaaaaaa) { //sqrt(subdiv) must be integer subdiv <<= 1; } @@ -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); @@ -2180,38 +2192,45 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo } } -void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *m, bool p_shadow) { +void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow) { - bool has_base_alpha = (m->shader->spatial.uses_alpha && !m->shader->spatial.uses_alpha_scissor) || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded; - bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop; + bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture || p_material->shader->spatial.unshaded; + bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || p_material->shader->spatial.ontop; bool has_alpha = has_base_alpha || has_blend_alpha; bool shadow = false; bool mirror = p_instance->mirror; + bool no_cull = false; - if (m->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; } - if (m->shader->spatial.uses_sss) { + if (p_material->shader->spatial.uses_sss) { state.used_sss = true; } - if (m->shader->spatial.uses_screen_texture) { + if (p_material->shader->spatial.uses_screen_texture) { state.used_screen_texture = true; } if (p_shadow) { - if (has_blend_alpha || (has_base_alpha && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) + if (has_blend_alpha || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) return; //bye - if (!m->shader->spatial.uses_alpha_scissor && !m->shader->spatial.writes_modelview_or_projection && !m->shader->spatial.uses_vertex && !m->shader->spatial.uses_discard && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + 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) - m = storage->material_owner.getptr(default_material_twosided); - else - m = storage->material_owner.getptr(default_material); + if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) { + p_material = storage->material_owner.getptr(default_material_twosided); + no_cull = true; + mirror = false; + } else { + p_material = storage->material_owner.getptr(default_material); + } } has_alpha = false; @@ -2223,7 +2242,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G return; e->geometry = p_geometry; - e->material = m; + e->material = p_material; e->instance = p_instance; e->owner = p_owner; e->sort_key = 0; @@ -2250,7 +2269,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT; e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_DEPTH_LAYER_SHIFT; - if (!has_blend_alpha && has_alpha && m->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + if (!has_blend_alpha && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { //if nothing exists, add this element as opaque too RenderList::Element *oe = render_list.add_element(); @@ -2275,17 +2294,31 @@ 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 || m->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) { + if (shadow || p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) { e->sort_key |= SORT_KEY_UNSHADED_FLAG; } - if (!shadow && (m->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) { + if (!shadow && (p_material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) { e->sort_key |= SORT_KEY_VERTEX_LIT_FLAG; } + + if (!shadow && has_alpha && p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + //depth prepass for alpha + RenderList::Element *eo = render_list.add_element(); + + eo->instance = e->instance; + eo->geometry = e->geometry; + eo->material = e->material; + eo->sort_key = e->sort_key; + } } void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy) { @@ -4535,6 +4568,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); @@ -4757,7 +4793,7 @@ void RasterizerSceneGLES3::initialize() { { //directional light shadow directional_shadow.light_count = 0; - directional_shadow.size = nearest_power_of_2(GLOBAL_GET("rendering/quality/directional_shadow/size")); + directional_shadow.size = next_power_of_2(GLOBAL_GET("rendering/quality/directional_shadow/size")); glGenFramebuffers(1, &directional_shadow.fbo); glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo); glGenTextures(1, &directional_shadow.depth); |