Add transparency support for LightmapGI

Co-authored-by: Guerro323 <kaltobattle@gmail.com>
This commit is contained in:
Hendrik Brucker
2024-12-16 12:38:23 +01:00
parent 7f5c469292
commit a3525bc015
26 changed files with 442 additions and 95 deletions

View File

@ -977,7 +977,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p
glBindFramebuffer(GL_FRAMEBUFFER, sky->radiance_framebuffer);
scene_state.reset_gl_state();
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_DISABLED);
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);
scene_state.enable_gl_blend(false);
for (int i = 0; i < 6; i++) {
@ -1000,7 +1000,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p
} else {
if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {
scene_state.reset_gl_state();
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_DISABLED);
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);
scene_state.enable_gl_blend(false);
cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, sky->processing_layer);
@ -1433,6 +1433,10 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
if (surf->flags & GeometryInstanceSurface::FLAG_PASS_SHADOW) {
rl->add_element(surf);
}
} else if (p_pass_mode == PASS_MODE_MATERIAL) {
if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE | GeometryInstanceSurface::FLAG_PASS_ALPHA)) {
rl->add_element(surf);
}
} else {
if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE)) {
rl->add_element(surf);
@ -2210,7 +2214,7 @@ void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
scene_state.enable_gl_depth_test(false);
scene_state.enable_gl_depth_draw(true);
glDisable(GL_CULL_FACE);
scene_state.cull_mode = GLES3::SceneShaderData::CULL_DISABLED;
scene_state.cull_mode = RS::CULL_MODE_DISABLED;
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
}
@ -2587,7 +2591,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
scene_state.enable_gl_depth_draw(false);
scene_state.enable_gl_depth_test(false);
scene_state.enable_gl_blend(false);
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);
scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);
Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
@ -2615,7 +2619,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
scene_state.enable_gl_depth_test(true);
scene_state.enable_gl_blend(false);
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);
scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);
Transform3D transform = render_data.cam_transform;
Projection projection = render_data.cam_projection;
@ -3099,19 +3103,19 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}
// Find cull variant.
GLES3::SceneShaderData::Cull cull_mode = shader->cull_mode;
RS::CullMode cull_mode = shader->cull_mode;
if (p_pass_mode == PASS_MODE_MATERIAL || (surf->flags & GeometryInstanceSurface::FLAG_USES_DOUBLE_SIDED_SHADOWS)) {
cull_mode = GLES3::SceneShaderData::CULL_DISABLED;
cull_mode = RS::CULL_MODE_DISABLED;
} else {
bool mirror = inst->mirror;
if (p_params->reverse_cull) {
mirror = !mirror;
}
if (cull_mode == GLES3::SceneShaderData::CULL_FRONT && mirror) {
cull_mode = GLES3::SceneShaderData::CULL_BACK;
} else if (cull_mode == GLES3::SceneShaderData::CULL_BACK && mirror) {
cull_mode = GLES3::SceneShaderData::CULL_FRONT;
if (cull_mode == RS::CULL_MODE_FRONT && mirror) {
cull_mode = RS::CULL_MODE_BACK;
} else if (cull_mode == RS::CULL_MODE_BACK && mirror) {
cull_mode = RS::CULL_MODE_FRONT;
}
}
@ -3832,7 +3836,7 @@ void RasterizerSceneGLES3::_render_buffers_debug_draw(Ref<RenderSceneBuffersGLES
glActiveTexture(GL_TEXTURE0);
scene_state.enable_gl_depth_draw(true);
glDepthFunc(GL_ALWAYS);
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_DISABLED);
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);
// Loop through quadrants and copy shadows over.
for (int quadrant = 0; quadrant < 4; quadrant++) {

View File

@ -461,7 +461,7 @@ private:
bool used_depth_prepass = false;
GLES3::SceneShaderData::BlendMode current_blend_mode = GLES3::SceneShaderData::BLEND_MODE_MIX;
GLES3::SceneShaderData::Cull cull_mode = GLES3::SceneShaderData::CULL_BACK;
RS::CullMode cull_mode = RS::CULL_MODE_BACK;
bool current_blend_enabled = false;
bool current_depth_draw_enabled = false;
@ -477,7 +477,7 @@ private:
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
cull_mode = GLES3::SceneShaderData::CULL_BACK;
cull_mode = RS::CULL_MODE_BACK;
glDepthMask(GL_FALSE);
current_depth_draw_enabled = false;
@ -485,16 +485,16 @@ private:
current_depth_test_enabled = false;
}
void set_gl_cull_mode(GLES3::SceneShaderData::Cull p_mode) {
void set_gl_cull_mode(RS::CullMode p_mode) {
if (cull_mode != p_mode) {
if (p_mode == GLES3::SceneShaderData::CULL_DISABLED) {
if (p_mode == RS::CULL_MODE_DISABLED) {
glDisable(GL_CULL_FACE);
} else {
if (cull_mode == GLES3::SceneShaderData::CULL_DISABLED) {
if (cull_mode == RS::CULL_MODE_DISABLED) {
// Last time was disabled, so enable and set proper face.
glEnable(GL_CULL_FACE);
}
glCullFace(p_mode == GLES3::SceneShaderData::CULL_FRONT ? GL_FRONT : GL_BACK);
glCullFace(p_mode == RS::CULL_MODE_FRONT ? GL_FRONT : GL_BACK);
}
cull_mode = p_mode;
}

View File

@ -1882,10 +1882,18 @@ void main() {
#ifndef USE_SHADOW_TO_OPACITY
#if defined(ALPHA_SCISSOR_USED)
#ifdef RENDER_MATERIAL
if (alpha < alpha_scissor_threshold) {
alpha = 0.0;
} else {
alpha = 1.0;
}
#else
if (alpha < alpha_scissor_threshold) {
discard;
}
alpha = 1.0;
#endif // RENDER_MATERIAL
#else
#ifdef MODE_RENDER_DEPTH
#ifdef USE_OPAQUE_PREPASS
@ -2215,9 +2223,17 @@ void main() {
alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
#if defined(ALPHA_SCISSOR_USED)
#ifdef RENDER_MATERIAL
if (alpha < alpha_scissor_threshold) {
alpha = 0.0;
} else {
alpha = 1.0;
}
#else
if (alpha < alpha_scissor_threshold) {
discard;
}
#endif // RENDER_MATERIAL
#endif // !ALPHA_SCISSOR_USED
#endif // !MODE_RENDER_DEPTH

View File

@ -2505,6 +2505,19 @@ bool MaterialStorage::material_casts_shadows(RID p_material) {
return true; //by default everything casts shadows
}
RS::CullMode MaterialStorage::material_get_cull_mode(RID p_material) const {
const GLES3::Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_NULL_V(material, RS::CULL_MODE_DISABLED);
ERR_FAIL_NULL_V(material->shader, RS::CULL_MODE_DISABLED);
if (material->shader->data) {
SceneShaderData *data = dynamic_cast<SceneShaderData *>(material->shader->data);
if (data) {
return (RS::CullMode)data->cull_mode;
}
}
return RS::CULL_MODE_DISABLED;
}
void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
GLES3::Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_NULL(material);
@ -2907,7 +2920,7 @@ void SceneShaderData::set_code(const String &p_code) {
int blend_modei = BLEND_MODE_MIX;
int depth_testi = DEPTH_TEST_ENABLED;
int alpha_antialiasing_modei = ALPHA_ANTIALIASING_OFF;
int cull_modei = CULL_BACK;
int cull_modei = RS::CULL_MODE_BACK;
int depth_drawi = DEPTH_DRAW_OPAQUE;
ShaderCompiler::IdentifierActions actions;
@ -2930,9 +2943,9 @@ void SceneShaderData::set_code(const String &p_code) {
actions.render_mode_values["depth_test_disabled"] = Pair<int *, int>(&depth_testi, DEPTH_TEST_DISABLED);
actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, CULL_DISABLED);
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, CULL_FRONT);
actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, CULL_BACK);
actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_DISABLED);
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_FRONT);
actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_BACK);
actions.render_mode_flags["unshaded"] = &unshaded;
actions.render_mode_flags["wireframe"] = &wireframe;
@ -2990,7 +3003,7 @@ void SceneShaderData::set_code(const String &p_code) {
alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei);
depth_draw = DepthDraw(depth_drawi);
depth_test = DepthTest(depth_testi);
cull_mode = Cull(cull_modei);
cull_mode = RS::CullMode(cull_modei);
vertex_input_mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL; // We can always read vertices and normals.
vertex_input_mask |= uses_tangent << RS::ARRAY_TANGENT;

View File

@ -263,12 +263,6 @@ struct SceneShaderData : public ShaderData {
DEPTH_TEST_ENABLED
};
enum Cull {
CULL_DISABLED,
CULL_FRONT,
CULL_BACK
};
enum AlphaAntiAliasing {
ALPHA_ANTIALIASING_OFF,
ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
@ -292,7 +286,7 @@ struct SceneShaderData : public ShaderData {
AlphaAntiAliasing alpha_antialiasing_mode;
DepthDraw depth_draw;
DepthTest depth_test;
Cull cull_mode;
RS::CullMode cull_mode;
bool uses_point_size;
bool uses_alpha;
@ -618,6 +612,7 @@ public:
virtual bool material_is_animated(RID p_material) override;
virtual bool material_casts_shadows(RID p_material) override;
virtual RS::CullMode material_get_cull_mode(RID p_material) const override;
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override;