diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-09-04 20:27:02 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-09-04 20:27:45 -0300 |
commit | e611ff5f0110210221a6f90250bdd65f5fb3ff2d (patch) | |
tree | 5bd62d6661946a304bded89e28351fe79c341d74 /drivers/gles3 | |
parent | 44adf75cd53c22f146fc2e2dbba7d7efab3c0a0d (diff) |
Fix opaque pre pass, closes #10472
Diffstat (limited to 'drivers/gles3')
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 68 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 7 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 6 |
3 files changed, 41 insertions, 40 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 6bef039dd1..690709e585 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1939,6 +1939,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ bool prev_use_instancing = false; storage->info.render.draw_call_count += p_element_count; + bool prev_opaque_prepass = false; for (int i = 0; i < p_element_count; i++) { @@ -2072,6 +2073,13 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ } } + bool use_opaque_prepass = e->sort_key & RenderList::SORT_KEY_OPAQUE_PRE_PASS; + + if (use_opaque_prepass != prev_opaque_prepass) { + state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, use_opaque_prepass); + rebind = true; + } + bool use_instancing = e->instance->base_type == VS::INSTANCE_MULTIMESH || e->instance->base_type == VS::INSTANCE_PARTICLES; if (use_instancing != prev_use_instancing) { @@ -2127,6 +2135,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ prev_shading = shading; prev_skeleton = skeleton; prev_use_instancing = use_instancing; + prev_opaque_prepass = use_opaque_prepass; first = false; } @@ -2148,9 +2157,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_VERTEX_LIGHTING, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, false); } -void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow) { +void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass) { RasterizerStorageGLES3::Material *m = NULL; RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material); @@ -2182,22 +2192,21 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo ERR_FAIL_COND(!m); - _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow); + _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass); while (m->next_pass.is_valid()) { m = storage->material_owner.getornull(m->next_pass); if (!m || !m->shader || !m->shader->valid) break; - _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow); + _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass); } } -void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, 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_depth_pass) { bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture; bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX; bool has_alpha = has_base_alpha || has_blend_alpha; - bool shadow = false; bool mirror = p_instance->mirror; bool no_cull = false; @@ -2217,7 +2226,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G state.used_screen_texture = true; } - if (p_shadow) { + if (p_depth_pass) { if (has_blend_alpha || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) return; //bye @@ -2252,14 +2261,14 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G e->geometry->index = current_geometry_index++; } - if (!p_shadow && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) { + if (!p_depth_pass && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) { e->sort_key |= SORT_KEY_NO_DIRECTIONAL_FLAG; } e->sort_key |= uint64_t(e->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT; e->sort_key |= uint64_t(e->instance->base_type) << RenderList::SORT_KEY_GEOMETRY_TYPE_SHIFT; - if (!p_shadow) { + if (!p_depth_pass) { if (e->material->last_pass != render_pass) { e->material->last_pass = render_pass; @@ -2269,17 +2278,6 @@ 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_OPAQUE_DEPTH_LAYER_SHIFT; - 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(); - - if (!oe) - return; - - copymem(oe, e, sizeof(RenderList::Element)); - } - if (e->instance->gi_probe_instances.size()) { e->sort_key |= SORT_KEY_GI_PROBES_FLAG; } @@ -2302,24 +2300,20 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G //e->light_type=0xFF; // no lights! - if (shadow || p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - - e->sort_key |= SORT_KEY_UNSHADED_FLAG; - } + if (p_depth_pass) { + if (p_material->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) { - if (!shadow && (p_material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) { + e->sort_key |= SORT_KEY_UNSHADED_FLAG; + } - e->sort_key |= SORT_KEY_VERTEX_LIT_FLAG; + if (p_material->shader->spatial.depth_draw_mode == RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) { + e->sort_key |= RenderList::SORT_KEY_OPAQUE_PRE_PASS; + } } - 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(); + if (!p_depth_pass && (p_material->shader->spatial.uses_vertex_lighting || storage->config.force_vertex_shading)) { - eo->instance = e->instance; - eo->geometry = e->geometry; - eo->material = e->material; - eo->sort_key = e->sort_key; + e->sort_key |= SORT_KEY_VERTEX_LIT_FLAG; } } @@ -3032,7 +3026,7 @@ void RasterizerSceneGLES3::_copy_texture_to_front_buffer(GLuint p_texture) { storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false); } -void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_shadow) { +void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass) { current_geometry_index = 0; current_material_index = 0; @@ -3057,7 +3051,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p int mat_idx = inst->materials[i].is_valid() ? i : -1; RasterizerStorageGLES3::Surface *s = mesh->surfaces[i]; - _add_geometry(s, inst, NULL, mat_idx, p_shadow); + _add_geometry(s, inst, NULL, mat_idx, p_depth_pass); } //mesh->last_pass=frame; @@ -3080,7 +3074,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p for (int i = 0; i < ssize; i++) { RasterizerStorageGLES3::Surface *s = mesh->surfaces[i]; - _add_geometry(s, inst, multi_mesh, -1, p_shadow); + _add_geometry(s, inst, multi_mesh, -1, p_depth_pass); } } break; @@ -3089,7 +3083,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getptr(inst->base); ERR_CONTINUE(!immediate); - _add_geometry(immediate, inst, NULL, -1, p_shadow); + _add_geometry(immediate, inst, NULL, -1, p_depth_pass); } break; case VS::INSTANCE_PARTICLES: { @@ -3111,7 +3105,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p for (int j = 0; j < ssize; j++) { RasterizerStorageGLES3::Surface *s = mesh->surfaces[j]; - _add_geometry(s, inst, particles, -1, p_shadow); + _add_geometry(s, inst, particles, -1, p_depth_pass); } } diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 5503dba5c4..b3fd6fa2a0 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -664,6 +664,7 @@ public: //bits 12-8 geometry type SORT_KEY_GEOMETRY_TYPE_SHIFT = 8, //bits 0-7 for flags + SORT_KEY_OPAQUE_PRE_PASS = 8, SORT_KEY_CULL_DISABLED_FLAG = 4, SORT_KEY_SKELETON_FLAG = 2, SORT_KEY_MIRROR_FLAG = 1 @@ -805,9 +806,9 @@ public: void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows); - _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow); + _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_passs); - _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow); + _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass); void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy); @@ -820,7 +821,7 @@ public: void _copy_to_front_buffer(Environment *env); void _copy_texture_to_front_buffer(GLuint p_texture); //used for debug - void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_shadow); + void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass); void _blur_effect_buffer(); void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection); diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index 7c60a8ee97..c699f1fe8c 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -1590,6 +1590,12 @@ FRAGMENT_SHADER_CODE } #endif +#ifdef USE_OPAQUE_PREPASS + + if (alpha<0.99) { + discard; + } +#endif #if defined(ENABLE_NORMALMAP) |