|
@@ -1939,6 +1939,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
|
bool prev_use_instancing = false;
|
|
bool prev_use_instancing = false;
|
|
|
|
|
|
storage->info.render.draw_call_count += p_element_count;
|
|
storage->info.render.draw_call_count += p_element_count;
|
|
|
|
+ bool prev_opaque_prepass = false;
|
|
|
|
|
|
for (int i = 0; i < p_element_count; i++) {
|
|
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;
|
|
bool use_instancing = e->instance->base_type == VS::INSTANCE_MULTIMESH || e->instance->base_type == VS::INSTANCE_PARTICLES;
|
|
|
|
|
|
if (use_instancing != prev_use_instancing) {
|
|
if (use_instancing != prev_use_instancing) {
|
|
@@ -2127,6 +2135,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
|
|
prev_shading = shading;
|
|
prev_shading = shading;
|
|
prev_skeleton = skeleton;
|
|
prev_skeleton = skeleton;
|
|
prev_use_instancing = use_instancing;
|
|
prev_use_instancing = use_instancing;
|
|
|
|
+ prev_opaque_prepass = use_opaque_prepass;
|
|
first = false;
|
|
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_GI_PROBES, false);
|
|
state.scene_shader.set_conditional(SceneShaderGLES3::USE_CONTACT_SHADOWS, 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_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;
|
|
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);
|
|
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);
|
|
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()) {
|
|
while (m->next_pass.is_valid()) {
|
|
m = storage->material_owner.getornull(m->next_pass);
|
|
m = storage->material_owner.getornull(m->next_pass);
|
|
if (!m || !m->shader || !m->shader->valid)
|
|
if (!m || !m->shader || !m->shader->valid)
|
|
break;
|
|
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_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_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX;
|
|
bool has_alpha = has_base_alpha || has_blend_alpha;
|
|
bool has_alpha = has_base_alpha || has_blend_alpha;
|
|
- bool shadow = false;
|
|
|
|
|
|
|
|
bool mirror = p_instance->mirror;
|
|
bool mirror = p_instance->mirror;
|
|
bool no_cull = false;
|
|
bool no_cull = false;
|
|
@@ -2217,7 +2226,7 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
|
|
state.used_screen_texture = true;
|
|
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))
|
|
if (has_blend_alpha || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
|
|
return; //bye
|
|
return; //bye
|
|
@@ -2252,14 +2261,14 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
|
|
e->geometry->index = current_geometry_index++;
|
|
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 |= 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->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT;
|
|
e->sort_key |= uint64_t(e->instance->base_type) << RenderList::SORT_KEY_GEOMETRY_TYPE_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) {
|
|
if (e->material->last_pass != render_pass) {
|
|
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->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
|
|
e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_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()) {
|
|
if (e->instance->gi_probe_instances.size()) {
|
|
e->sort_key |= SORT_KEY_GI_PROBES_FLAG;
|
|
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!
|
|
//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);
|
|
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_geometry_index = 0;
|
|
current_material_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;
|
|
int mat_idx = inst->materials[i].is_valid() ? i : -1;
|
|
RasterizerStorageGLES3::Surface *s = mesh->surfaces[i];
|
|
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;
|
|
//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++) {
|
|
for (int i = 0; i < ssize; i++) {
|
|
|
|
|
|
RasterizerStorageGLES3::Surface *s = mesh->surfaces[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;
|
|
} 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);
|
|
RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getptr(inst->base);
|
|
ERR_CONTINUE(!immediate);
|
|
ERR_CONTINUE(!immediate);
|
|
|
|
|
|
- _add_geometry(immediate, inst, NULL, -1, p_shadow);
|
|
|
|
|
|
+ _add_geometry(immediate, inst, NULL, -1, p_depth_pass);
|
|
|
|
|
|
} break;
|
|
} break;
|
|
case VS::INSTANCE_PARTICLES: {
|
|
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++) {
|
|
for (int j = 0; j < ssize; j++) {
|
|
|
|
|
|
RasterizerStorageGLES3::Surface *s = mesh->surfaces[j];
|
|
RasterizerStorageGLES3::Surface *s = mesh->surfaces[j];
|
|
- _add_geometry(s, inst, particles, -1, p_shadow);
|
|
|
|
|
|
+ _add_geometry(s, inst, particles, -1, p_depth_pass);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|