Implement render mode fog_disabled and BaseMaterial3D setting Disable Fog

This commit is contained in:
Milan Gruner 2023-09-04 00:04:14 +02:00
parent 75de1ca768
commit 45a33cc749
10 changed files with 45 additions and 2 deletions

View File

@ -176,6 +176,9 @@
<member name="disable_ambient_light" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the object receives no ambient light.
</member>
<member name="disable_fog" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the object will not be affected by fog (neither volumetric nor depth fog). This is useful for unshaded or transparent materials (e.g. particles), which without this setting will be affected even if fully transparent.
</member>
<member name="disable_receive_shadows" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the object receives no shadow that would otherwise be cast onto it.
</member>
@ -697,7 +700,10 @@
<constant name="FLAG_ALBEDO_TEXTURE_MSDF" value="20" enum="Flags">
Enables multichannel signed distance field rendering shader.
</constant>
<constant name="FLAG_MAX" value="21" enum="Flags">
<constant name="FLAG_DISABLE_FOG" value="21" enum="Flags">
Disables receiving depth-based or volumetric fog.
</constant>
<constant name="FLAG_MAX" value="22" enum="Flags">
Represents the size of the [enum Flags] enum.
</constant>
<constant name="DIFFUSE_BURLEY" value="0" enum="DiffuseMode">

View File

@ -962,7 +962,9 @@ void main() {
float clearcoat_roughness = 0.0;
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
#ifndef FOG_DISABLED
vec4 fog = vec4(0.0);
#endif // !FOG_DISABLED
#if defined(CUSTOM_RADIANCE_USED)
vec4 custom_radiance = vec4(0.0);
#endif
@ -1075,6 +1077,7 @@ void main() {
#ifndef MODE_RENDER_DEPTH
#ifndef FOG_DISABLED
#ifndef CUSTOM_FOG_USED
#ifndef DISABLE_FOG
// fog must be processed as early as possible and then packed.
@ -1088,6 +1091,7 @@ void main() {
uint fog_rg = packHalf2x16(fog.rg);
uint fog_ba = packHalf2x16(fog.ba);
#endif // !FOG_DISABLED
// Convert colors to linear
albedo = srgb_to_linear(albedo);
@ -1300,6 +1304,8 @@ void main() {
frag_color.rgb += emission + ambient_light;
#endif
#endif //MODE_UNSHADED
#ifndef FOG_DISABLED
fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba));
#ifndef DISABLE_FOG
@ -1310,7 +1316,8 @@ void main() {
frag_color.rgb *= (1.0 - fog.a);
#endif // BASE_PASS
}
#endif
#endif // !DISABLE_FOG
#endif // !FOG_DISABLED
// Tonemap before writing as we are writing to an sRGB framebuffer
frag_color.rgb *= exposure;

View File

@ -1358,6 +1358,7 @@ MaterialStorage::MaterialStorage() {
actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;

View File

@ -777,6 +777,9 @@ void BaseMaterial3D::_update_shader() {
if (flags[FLAG_USE_SHADOW_TO_OPACITY]) {
code += ",shadow_to_opacity";
}
if (flags[FLAG_DISABLE_FOG]) {
code += ",fog_disabled";
}
if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) {
code += ",depth_prepass_alpha";
@ -2725,6 +2728,7 @@ void BaseMaterial3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "diffuse_mode", PROPERTY_HINT_ENUM, "Burley,Lambert,Lambert Wrap,Toon"), "set_diffuse_mode", "get_diffuse_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "SchlickGGX,Toon,Disabled"), "set_specular_mode", "get_specular_mode");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_ambient_light"), "set_flag", "get_flag", FLAG_DISABLE_AMBIENT_LIGHT);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "disable_fog"), "set_flag", "get_flag", FLAG_DISABLE_FOG);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
@ -2977,6 +2981,7 @@ void BaseMaterial3D::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_SUBSURFACE_MODE_SKIN);
BIND_ENUM_CONSTANT(FLAG_PARTICLE_TRAILS_MODE);
BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_MSDF);
BIND_ENUM_CONSTANT(FLAG_DISABLE_FOG);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);

View File

@ -256,6 +256,7 @@ public:
FLAG_SUBSURFACE_MODE_SKIN,
FLAG_PARTICLE_TRAILS_MODE,
FLAG_ALBEDO_TEXTURE_MSDF,
FLAG_DISABLE_FOG,
FLAG_MAX
};

View File

@ -707,6 +707,7 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
actions.base_texture_binding_index = 1;
actions.texture_layout_set = RenderForwardClustered::MATERIAL_UNIFORM_SET;

View File

@ -610,6 +610,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
actions.render_mode_defines["fog_disabled"] = "#define FOG_DISABLED\n";
actions.base_texture_binding_index = 1;
actions.texture_layout_set = RenderForwardMobile::MATERIAL_UNIFORM_SET;

View File

@ -802,7 +802,9 @@ void fragment_shader(in SceneData scene_data) {
float clearcoat_roughness = 0.0;
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
#ifndef FOG_DISABLED
vec4 fog = vec4(0.0);
#endif // !FOG_DISABLED
#if defined(CUSTOM_RADIANCE_USED)
vec4 custom_radiance = vec4(0.0);
#endif
@ -962,6 +964,7 @@ void fragment_shader(in SceneData scene_data) {
/////////////////////// FOG //////////////////////
#ifndef MODE_RENDER_DEPTH
#ifndef FOG_DISABLED
#ifndef CUSTOM_FOG_USED
// fog must be processed as early as possible and then packed.
// to maximize VGPR usage
@ -997,6 +1000,7 @@ void fragment_shader(in SceneData scene_data) {
uint fog_rg = packHalf2x16(fog.rg);
uint fog_ba = packHalf2x16(fog.ba);
#endif //!FOG_DISABLED
#endif //!MODE_RENDER_DEPTH
/////////////////////// DECALS ////////////////////////////////
@ -2250,8 +2254,10 @@ void fragment_shader(in SceneData scene_data) {
diffuse_light *= 1.0 - metallic;
ambient_light *= 1.0 - metallic;
#ifndef FOG_DISABLED
//restore fog
fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba));
#endif //!FOG_DISABLED
#ifdef MODE_SEPARATE_SPECULAR
@ -2268,8 +2274,10 @@ void fragment_shader(in SceneData scene_data) {
specular_buffer = vec4(specular_light, metallic);
#endif
#ifndef FOG_DISABLED
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
#endif //!FOG_DISABLED
#else //MODE_SEPARATE_SPECULAR
@ -2280,8 +2288,10 @@ void fragment_shader(in SceneData scene_data) {
//frag_color = vec4(1.0);
#endif //USE_NO_SHADING
#ifndef FOG_DISABLED
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
#endif //!FOG_DISABLED
#endif //MODE_SEPARATE_SPECULAR

View File

@ -694,7 +694,9 @@ void main() {
float clearcoat_roughness = 0.0;
float anisotropy = 0.0;
vec2 anisotropy_flow = vec2(1.0, 0.0);
#ifndef FOG_DISABLED
vec4 fog = vec4(0.0);
#endif // !FOG_DISABLED
#if defined(CUSTOM_RADIANCE_USED)
vec4 custom_radiance = vec4(0.0);
#endif
@ -860,6 +862,7 @@ void main() {
/////////////////////// FOG //////////////////////
#ifndef MODE_RENDER_DEPTH
#ifndef FOG_DISABLED
#ifndef CUSTOM_FOG_USED
// fog must be processed as early as possible and then packed.
// to maximize VGPR usage
@ -874,6 +877,7 @@ void main() {
uint fog_rg = packHalf2x16(fog.rg);
uint fog_ba = packHalf2x16(fog.ba);
#endif //!FOG_DISABLED
#endif //!MODE_RENDER_DEPTH
/////////////////////// DECALS ////////////////////////////////
@ -1744,8 +1748,10 @@ void main() {
diffuse_light *= 1.0 - metallic;
ambient_light *= 1.0 - metallic;
#ifndef FOG_DISABLED
//restore fog
fog = vec4(unpackHalf2x16(fog_rg), unpackHalf2x16(fog_ba));
#endif // !FOG_DISABLED
#ifdef MODE_MULTIPLE_RENDER_TARGETS
@ -1762,8 +1768,10 @@ void main() {
specular_buffer = vec4(specular_light, metallic);
#endif // MODE_UNSHADED
#ifndef FOG_DISABLED
diffuse_buffer.rgb = mix(diffuse_buffer.rgb, fog.rgb, fog.a);
specular_buffer.rgb = mix(specular_buffer.rgb, vec3(0.0), fog.a);
#endif // !FOG_DISABLED
#else //MODE_MULTIPLE_RENDER_TARGETS
@ -1773,8 +1781,10 @@ void main() {
frag_color = vec4(emission + ambient_light + diffuse_light + specular_light, alpha);
#endif // MODE_UNSHADED
#ifndef FOG_DISABLED
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a);
#endif // !FOG_DISABLED
// On mobile we use a UNORM buffer with 10bpp which results in a range from 0.0 - 1.0 resulting in HDR breaking
// We divide by sc_luminance_multiplier to support a range from 0.0 - 2.0 both increasing precision on bright and darker images

View File

@ -227,6 +227,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage") });
shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage_and_one") });
shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("debug_shadow_splits") });
shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("fog_disabled") });
}
/************ CANVAS ITEM **************************/