Add new StandardMaterial properties to allow users to control FPS-style objects (hands, weapons, tools close to the camera)

Add new shader built in Z_CLIP_SCALE to easily adjust clipping distance to avoid clipping walls etc.

Add fov_override to StandardMaterial3D to easily have a custom FOV for FPS objects

Add IN_SHADOW_PASS built-in to shaders for tweaking materials without impacting shadow maps
This commit is contained in:
clayjohn
2024-06-13 15:16:18 -07:00
parent 25a3c27c41
commit 9a1def8da1
15 changed files with 254 additions and 90 deletions

View File

@ -2744,6 +2744,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
scene_data.time = time;
scene_data.time_step = time_step;
scene_data.main_cam_transform = p_main_cam_transform;
scene_data.shadow_pass = true;
RenderDataRD render_data;
render_data.scene_data = &scene_data;
@ -2836,6 +2837,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
scene_data.time = time;
scene_data.time_step = time_step;
scene_data.main_cam_transform = p_cam_transform;
scene_data.shadow_pass = true; // Not a shadow pass, but should be treated like one.
RenderDataRD render_data;
render_data.scene_data = &scene_data;

View File

@ -79,6 +79,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
writes_modelview_or_projection = false;
uses_world_coordinates = false;
uses_particle_trails = false;
uses_z_clip_scale = false;
int depth_drawi = DEPTH_DRAW_OPAQUE;
@ -140,6 +141,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
actions.write_flag_pointers["PROJECTION_MATRIX"] = &writes_modelview_or_projection;
actions.write_flag_pointers["VERTEX"] = &uses_vertex;
actions.write_flag_pointers["POSITION"] = &uses_position;
actions.write_flag_pointers["Z_CLIP_SCALE"] = &uses_z_clip_scale;
actions.uniforms = &uniforms;
@ -613,6 +615,7 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.renames["POINT_SIZE"] = "gl_PointSize";
actions.renames["INSTANCE_ID"] = "gl_InstanceIndex";
actions.renames["VERTEX_ID"] = "gl_VertexIndex";
actions.renames["Z_CLIP_SCALE"] = "z_clip_scale";
actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold";
actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale";
@ -628,6 +631,7 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.renames["E"] = String::num(Math::E);
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR";
actions.renames["IN_SHADOW_PASS"] = "bool(scene_data_block.data.flags & SCENE_DATA_FLAGS_IN_SHADOW_PASS)";
actions.renames["VIEWPORT_SIZE"] = "read_viewport_size";
actions.renames["FRAGCOORD"] = "gl_FragCoord";
@ -717,12 +721,13 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
actions.usage_defines["LIGHT_VERTEX"] = "#define LIGHT_VERTEX_USED\n";
actions.usage_defines["PREMUL_ALPHA_FACTOR"] = "#define PREMUL_ALPHA_USED\n";
actions.usage_defines["Z_CLIP_SCALE"] = "#define Z_CLIP_SCALE_USED\n";
actions.usage_defines["ALPHA_SCISSOR_THRESHOLD"] = "#define ALPHA_SCISSOR_USED\n";
actions.usage_defines["ALPHA_HASH_SCALE"] = "#define ALPHA_HASH_USED\n";
actions.usage_defines["ALPHA_ANTIALIASING_EDGE"] = "#define ALPHA_ANTIALIASING_EDGE_USED\n";
actions.usage_defines["ALPHA_TEXTURE_COORDINATE"] = "@ALPHA_ANTIALIASING_EDGE";
actions.usage_defines["PREMUL_ALPHA_FACTOR"] = "#define PREMUL_ALPHA_USED\n";
actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n";

View File

@ -245,6 +245,7 @@ public:
bool writes_modelview_or_projection = false;
bool uses_world_coordinates = false;
bool uses_screen_texture_mipmaps = false;
bool uses_z_clip_scale = false;
RS::CullMode cull_mode = RS::CULL_MODE_DISABLED;
uint64_t last_pass = 0;
@ -268,7 +269,7 @@ public:
_FORCE_INLINE_ bool uses_shared_shadow_material() const {
bool backface_culling = cull_mode == RS::CULL_MODE_BACK;
return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_position && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && backface_culling && !uses_point_size && !uses_world_coordinates && !wireframe;
return !uses_particle_trails && !writes_modelview_or_projection && !uses_vertex && !uses_position && !uses_discard && !uses_depth_prepass_alpha && !uses_alpha_clip && !uses_alpha_antialiasing && backface_culling && !uses_point_size && !uses_world_coordinates && !wireframe && !uses_z_clip_scale;
}
virtual void set_code(const String &p_Code);

View File

@ -485,14 +485,14 @@ void SceneShaderForwardMobile::init(const String p_defines) {
const String base_define = ubershader ? "\n#define UBERSHADER\n" : "";
shader_versions.push_back(base_define + ""); // SHADER_VERSION_COLOR_PASS
shader_versions.push_back(base_define + "\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS
shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here...
shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); // SHADER_VERSION_SHADOW_PASS_DP
shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n#define SHADOW_PASS\n"); // SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here...
shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n#define SHADOW_PASS\n"); // SHADER_VERSION_SHADOW_PASS_DP
shader_versions.push_back(base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
// Multiview versions of our shaders.
shader_versions.push_back(base_define + "\n#define USE_MULTIVIEW\n"); // SHADER_VERSION_COLOR_PASS_MULTIVIEW
shader_versions.push_back(base_define + "\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW
shader_versions.push_back(base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_SHADOW_PASS_MULTIVIEW
shader_versions.push_back(base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define SHADOW_PASS\n"); // SHADER_VERSION_SHADOW_PASS_MULTIVIEW
}
Vector<RD::PipelineImmutableSampler> immutable_samplers;
@ -540,6 +540,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.renames["POINT_SIZE"] = "gl_PointSize";
actions.renames["INSTANCE_ID"] = "gl_InstanceIndex";
actions.renames["VERTEX_ID"] = "gl_VertexIndex";
actions.renames["Z_CLIP_SCALE"] = "z_clip_scale";
actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold";
actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale";
@ -555,6 +556,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.renames["E"] = String::num(Math::E);
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
actions.renames["CLIP_SPACE_FAR"] = "SHADER_SPACE_FAR";
actions.renames["IN_SHADOW_PASS"] = "IN_SHADOW_PASS";
actions.renames["VIEWPORT_SIZE"] = "read_viewport_size";
actions.renames["FRAGCOORD"] = "gl_FragCoord";
@ -644,6 +646,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
actions.usage_defines["LIGHT_VERTEX"] = "#define LIGHT_VERTEX_USED\n";
actions.usage_defines["Z_CLIP_SCALE"] = "#define Z_CLIP_SCALE_USED\n";
actions.usage_defines["ALPHA_SCISSOR_THRESHOLD"] = "#define ALPHA_SCISSOR_USED\n";
actions.usage_defines["ALPHA_HASH_SCALE"] = "#define ALPHA_HASH_USED\n";

View File

@ -400,6 +400,10 @@ void vertex_shader(vec3 vertex_input,
#endif
#endif
#ifdef Z_CLIP_SCALE_USED
float z_clip_scale = 1.0;
#endif
float roughness = 1.0;
mat4 modelview = scene_data.view_matrix * model_matrix;
@ -644,14 +648,14 @@ void vertex_shader(vec3 vertex_input,
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
#ifdef MODE_RENDER_DEPTH
if (scene_data.pancake_shadows) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS)) {
if (gl_Position.z >= 0.9999) {
gl_Position.z = 0.9999;
}
}
#endif
#ifdef MODE_RENDER_MATERIAL
if (scene_data.material_uv2_mode) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_UV2_MATERIAL)) {
vec2 uv_dest_attrib;
if (uv_scale != vec4(0.0)) {
uv_dest_attrib = (uv2_attrib.xy - 0.5) * uv_scale.zw;
@ -665,6 +669,12 @@ void vertex_shader(vec3 vertex_input,
gl_Position.w = 1.0;
}
#endif
#ifdef Z_CLIP_SCALE_USED
if (!bool(scene_data_block.data.flags & SCENE_DATA_FLAGS_IN_SHADOW_PASS)) {
gl_Position.z = mix(gl_Position.w, gl_Position.z, z_clip_scale);
}
#endif
}
void _unpack_vertex_attributes(vec4 p_vertex_in, vec3 p_compressed_aabb_position, vec3 p_compressed_aabb_size,
@ -1381,7 +1391,7 @@ void fragment_shader(in SceneData scene_data) {
// to maximize VGPR usage
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
if (scene_data.fog_enabled) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_FOG)) {
fog = fog_process(vertex);
}
@ -1391,7 +1401,7 @@ void fragment_shader(in SceneData scene_data) {
#else
vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z);
#endif
if (scene_data.fog_enabled) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_FOG)) {
//must use the full blending equation here to blend fogs
vec4 res;
float sa = 1.0 - volumetric_fog.a;
@ -1543,7 +1553,7 @@ void fragment_shader(in SceneData scene_data) {
/////////////////////// LIGHTING //////////////////////////////
#ifdef NORMAL_USED
if (scene_data.roughness_limiter_enabled) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_ROUGHNESS_LIMITER)) {
//https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
float roughness2 = roughness * roughness;
vec3 dndu = dFdx(normal), dndv = dFdy(normal);
@ -1574,7 +1584,7 @@ void fragment_shader(in SceneData scene_data) {
vec3 indirect_normal = normal;
#endif
if (scene_data.use_reflection_cubemap) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP)) {
#ifdef LIGHT_ANISOTROPY_USED
// https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
@ -1614,10 +1624,10 @@ void fragment_shader(in SceneData scene_data) {
#ifndef USE_LIGHTMAP
//lightmap overrides everything
if (scene_data.use_ambient_light) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT)) {
ambient_light = scene_data.ambient_light_color_energy.rgb;
if (scene_data.use_ambient_cubemap) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_AMBIENT_CUBEMAP)) {
vec3 ambient_dir = scene_data.radiance_inverse_xform * indirect_normal;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
vec3 cubemap_ambient = texture(samplerCubeArray(radiance_cubemap, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(ambient_dir, MAX_ROUGHNESS_LOD)).rgb;
@ -1635,7 +1645,7 @@ void fragment_shader(in SceneData scene_data) {
#ifdef LIGHT_CLEARCOAT_USED
if (scene_data.use_reflection_cubemap) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP)) {
float NoV = max(dot(geo_normal, view), 0.0001); // We want to use geometric normal, not normal_map
vec3 ref_vec = reflect(-view, geo_normal);
ref_vec = mix(ref_vec, geo_normal, clearcoat_roughness * clearcoat_roughness);

View File

@ -10,6 +10,12 @@
#define SHADER_IS_SRGB false
#define SHADER_SPACE_FAR 0.0
#ifdef SHADOW_PASS
#define IN_SHADOW_PASS true
#else
#define IN_SHADOW_PASS false
#endif
/* INPUT ATTRIBS */
// Always contains vertex position in XYZ, can contain tangent angle in W.
@ -377,6 +383,10 @@ void main() {
#endif
#endif
#ifdef Z_CLIP_SCALE_USED
float z_clip_scale = 1.0;
#endif
float roughness = 1.0;
mat4 modelview = scene_data.view_matrix * model_matrix;
@ -559,15 +569,19 @@ void main() {
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
#endif // OVERRIDE_POSITION
#if defined(Z_CLIP_SCALE_USED) && !defined(SHADOW_PASS)
gl_Position.z = mix(gl_Position.w, gl_Position.z, z_clip_scale);
#endif
#ifdef MODE_RENDER_DEPTH
if (scene_data.pancake_shadows) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS)) {
if (gl_Position.z >= 0.9999) {
gl_Position.z = 0.9999;
}
}
#endif // MODE_RENDER_DEPTH
#ifdef MODE_RENDER_MATERIAL
if (scene_data.material_uv2_mode) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_UV2_MATERIAL)) {
vec2 uv_dest_attrib;
if (uv_scale != vec4(0.0)) {
uv_dest_attrib = (uv2_attrib.xy - 0.5) * uv_scale.zw;
@ -591,6 +605,12 @@ void main() {
#define SHADER_IS_SRGB false
#define SHADER_SPACE_FAR 0.0
#ifdef SHADOW_PASS
#define IN_SHADOW_PASS true
#else
#define IN_SHADOW_PASS false
#endif
/* Include our forward mobile UBOs definitions etc. */
#include "scene_forward_mobile_inc.glsl"
@ -1122,7 +1142,7 @@ void main() {
// to maximize VGPR usage
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
if (!sc_disable_fog() && scene_data.fog_enabled) {
if (!sc_disable_fog() && bool(scene_data.flags & SCENE_DATA_FLAGS_USE_FOG)) {
fog = fog_process(vertex);
}
@ -1287,7 +1307,7 @@ void main() {
#ifndef USE_LIGHTMAP
//lightmap overrides everything
if (scene_data.use_ambient_light) {
if (bool(scene_data.flags & SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT)) {
ambient_light = scene_data.ambient_light_color_energy.rgb;
if (sc_scene_use_ambient_cubemap()) {

View File

@ -3,6 +3,15 @@
// This enables us to use this UBO in our main scene render shaders but also in
// effects that need access to this data.
#define SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT (1 << 0)
#define SCENE_DATA_FLAGS_USE_AMBIENT_CUBEMAP (1 << 1)
#define SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP (1 << 2)
#define SCENE_DATA_FLAGS_USE_ROUGHNESS_LIMITER (1 << 3)
#define SCENE_DATA_FLAGS_USE_FOG (1 << 4)
#define SCENE_DATA_FLAGS_USE_UV2_MATERIAL (1 << 5)
#define SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS (1 << 6)
#define SCENE_DATA_FLAGS_IN_SHADOW_PASS (1 << 7)
struct SceneData {
highp mat4 projection_matrix;
highp mat4 inv_projection_matrix;
@ -26,15 +35,6 @@ struct SceneData {
highp vec4 penumbra_shadow_kernel[32];
highp vec4 soft_shadow_kernel[32];
mediump mat3 radiance_inverse_xform;
mediump vec4 ambient_light_color_energy;
mediump float ambient_color_sky_mix;
bool use_ambient_light;
bool use_ambient_cubemap;
bool use_reflection_cubemap;
highp vec2 shadow_atlas_pixel_size;
highp vec2 directional_shadow_pixel_size;
@ -43,35 +43,34 @@ struct SceneData {
highp float z_far;
highp float z_near;
bool roughness_limiter_enabled;
mediump float roughness_limiter_amount;
mediump float roughness_limiter_limit;
mediump float opaque_prepass_threshold;
highp uint flags;
bool fog_enabled;
uint fog_mode;
mediump mat3 radiance_inverse_xform;
mediump vec4 ambient_light_color_energy;
mediump float ambient_color_sky_mix;
highp float fog_density;
highp float fog_height;
highp float fog_height_density;
highp float fog_depth_curve;
highp float fog_depth_begin;
highp float taa_frame_count;
highp float fog_depth_end;
mediump float fog_sun_scatter;
mediump vec3 fog_light_color;
highp float fog_depth_end;
mediump float fog_sun_scatter;
mediump float fog_aerial_perspective;
highp float time;
mediump float reflection_multiplier; // one normally, zero when rendering reflections
highp float taa_frame_count;
vec2 taa_jitter;
bool material_uv2_mode;
float emissive_exposure_normalization;
float emissive_exposure_normalization;
float IBL_exposure_normalization;
bool pancake_shadows;
uint camera_visible_layers;
float pass_alpha_multiplier;
};

View File

@ -116,7 +116,9 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
ubo.z_far = z_far;
ubo.z_near = z_near;
ubo.pancake_shadows = p_pancake_shadows;
ubo.flags = 0;
ubo.flags |= p_pancake_shadows ? SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS : 0;
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_penumbra_shadow_kernel_get(), ubo.directional_penumbra_shadow_kernel);
RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel);
@ -143,18 +145,15 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
ubo.directional_light_count = directional_light_count;
ubo.dual_paraboloid_side = dual_paraboloid_side;
ubo.opaque_prepass_threshold = opaque_prepass_threshold;
ubo.material_uv2_mode = material_uv2_mode;
ubo.fog_enabled = false;
ubo.flags |= material_uv2_mode ? SCENE_DATA_FLAGS_USE_UV2_MATERIAL : 0;
ubo.flags |= shadow_pass ? SCENE_DATA_FLAGS_IN_SHADOW_PASS : 0;
if (p_debug_mode == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
ubo.use_ambient_light = true;
ubo.flags |= SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT;
ubo.ambient_light_color_energy[0] = 1;
ubo.ambient_light_color_energy[1] = 1;
ubo.ambient_light_color_energy[2] = 1;
ubo.ambient_light_color_energy[3] = 1.0;
ubo.use_ambient_cubemap = false;
ubo.use_reflection_cubemap = false;
} else if (p_env.is_valid()) {
RS::EnvironmentBG env_bg = render_scene_render->environment_get_background(p_env);
RS::EnvironmentAmbientSource ambient_src = render_scene_render->environment_get_ambient_source(p_env);
@ -173,8 +172,7 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier;
ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier;
ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier;
ubo.use_ambient_light = true;
ubo.use_ambient_cubemap = false;
ubo.flags |= SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT;
} else {
float energy = render_scene_render->environment_get_ambient_light_energy(p_env);
Color color = render_scene_render->environment_get_ambient_light(p_env);
@ -187,20 +185,19 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
sky_transform = sky_transform.inverse() * cam_transform.basis;
RendererRD::MaterialStorage::store_transform_3x3(sky_transform, ubo.radiance_inverse_xform);
ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
ubo.use_ambient_light = ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
bool use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
bool use_ambient_light = use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
ubo.flags |= use_ambient_cubemap ? SCENE_DATA_FLAGS_USE_AMBIENT_CUBEMAP : 0;
ubo.flags |= use_ambient_light ? SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT : 0;
}
//specular
RS::EnvironmentReflectionSource ref_src = render_scene_render->environment_get_reflection_source(p_env);
if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {
ubo.use_reflection_cubemap = true;
} else {
ubo.use_reflection_cubemap = false;
ubo.flags |= SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP;
}
ubo.fog_enabled = render_scene_render->environment_get_fog_enabled(p_env);
ubo.fog_mode = render_scene_render->environment_get_fog_mode(p_env);
ubo.flags |= render_scene_render->environment_get_fog_enabled(p_env) ? SCENE_DATA_FLAGS_USE_FOG : 0;
ubo.fog_density = render_scene_render->environment_get_fog_density(p_env);
ubo.fog_height = render_scene_render->environment_get_fog_height(p_env);
ubo.fog_height_density = render_scene_render->environment_get_fog_height_density(p_env);
@ -219,10 +216,8 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
ubo.fog_sun_scatter = render_scene_render->environment_get_fog_sun_scatter(p_env);
} else {
if (p_reflection_probe_instance.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(p_reflection_probe_instance)) {
ubo.use_ambient_light = false;
} else {
ubo.use_ambient_light = true;
if (!(p_reflection_probe_instance.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(p_reflection_probe_instance))) {
ubo.flags |= SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT;
Color clear_color = p_default_bg_color;
clear_color = clear_color.srgb_to_linear();
ubo.ambient_light_color_energy[0] = clear_color.r;
@ -230,9 +225,6 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
ubo.ambient_light_color_energy[2] = clear_color.b;
ubo.ambient_light_color_energy[3] = 1.0;
}
ubo.use_ambient_cubemap = false;
ubo.use_reflection_cubemap = false;
}
if (p_camera_attributes.is_valid()) {
@ -255,7 +247,8 @@ void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p
ubo.IBL_exposure_normalization = 1.0;
}
ubo.roughness_limiter_enabled = p_opaque_render_buffers && render_scene_render->screen_space_roughness_limiter_is_active();
bool roughness_limiter_enabled = p_opaque_render_buffers && render_scene_render->screen_space_roughness_limiter_is_active();
ubo.flags |= roughness_limiter_enabled ? SCENE_DATA_FLAGS_USE_ROUGHNESS_LIMITER : 0;
ubo.roughness_limiter_amount = render_scene_render->screen_space_roughness_limiter_get_amount();
ubo.roughness_limiter_limit = render_scene_render->screen_space_roughness_limiter_get_limit();

View File

@ -75,6 +75,7 @@ public:
float opaque_prepass_threshold = 0.0;
bool material_uv2_mode = false;
float emissive_exposure_normalization = 0.0;
bool shadow_pass = false;
Size2 shadow_atlas_pixel_size;
Size2 directional_shadow_pixel_size;
@ -96,6 +97,18 @@ public:
private:
RID uniform_buffer; // loaded into this uniform buffer (supplied externally)
enum SceneDataFlags {
SCENE_DATA_FLAGS_USE_AMBIENT_LIGHT = 1 << 0,
SCENE_DATA_FLAGS_USE_AMBIENT_CUBEMAP = 1 << 1,
SCENE_DATA_FLAGS_USE_REFLECTION_CUBEMAP = 1 << 2,
SCENE_DATA_FLAGS_USE_ROUGHNESS_LIMITER = 1 << 3,
SCENE_DATA_FLAGS_USE_FOG = 1 << 4,
SCENE_DATA_FLAGS_USE_UV2_MATERIAL = 1 << 5,
SCENE_DATA_FLAGS_USE_PANCAKE_SHADOWS = 1 << 6,
SCENE_DATA_FLAGS_IN_SHADOW_PASS = 1 << 7, // Only used by Forward+ renderer.
SCENE_DATA_FLAGS_MAX
};
// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code
struct UBO {
float projection_matrix[16];
@ -117,15 +130,6 @@ private:
float penumbra_shadow_kernel[128];
float soft_shadow_kernel[128];
float radiance_inverse_xform[12];
float ambient_light_color_energy[4];
float ambient_color_sky_mix;
uint32_t use_ambient_light;
uint32_t use_ambient_cubemap;
uint32_t use_reflection_cubemap;
float shadow_atlas_pixel_size[2];
float directional_shadow_pixel_size[2];
@ -134,36 +138,34 @@ private:
float z_far;
float z_near;
uint32_t roughness_limiter_enabled;
float roughness_limiter_amount;
float roughness_limiter_limit;
float opaque_prepass_threshold;
uint32_t flags;
// Fog
uint32_t fog_enabled;
uint32_t fog_mode;
float radiance_inverse_xform[12];
float ambient_light_color_energy[4];
float ambient_color_sky_mix;
float fog_density;
float fog_height;
float fog_height_density;
float fog_depth_curve;
float fog_depth_begin;
float taa_frame_count; // Used to add break up samples over multiple frames. Value is an integer from 0 to taa_phase_count -1.
float fog_depth_end;
float fog_sun_scatter;
float fog_light_color[3];
float fog_depth_end;
float fog_sun_scatter;
float fog_aerial_perspective;
float time;
float reflection_multiplier;
float taa_frame_count; // Used to add break up samples over multiple frames. Value is an integer from 0 to taa_phase_count -1.
float taa_jitter[2];
uint32_t material_uv2_mode;
float emissive_exposure_normalization; // Needed to normalize emissive when using physical units.
float emissive_exposure_normalization; // Needed to normalize emissive when using physical units.
float IBL_exposure_normalization; // Adjusts for baked exposure.
uint32_t pancake_shadows;
uint32_t camera_visible_layers;
float pass_alpha_multiplier;
};

View File

@ -77,6 +77,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["E"] = constvt(ShaderLanguage::TYPE_FLOAT, { e_scalar });
shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["OUTPUT_IS_SRGB"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["CLIP_SPACE_FAR"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["IN_SHADOW_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
@ -87,6 +88,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["UV2"] = ShaderLanguage::TYPE_VEC2;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["POINT_SIZE"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["Z_CLIP_SCALE"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_ID"] = constt(ShaderLanguage::TYPE_INT);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["INSTANCE_CUSTOM"] = constt(ShaderLanguage::TYPE_VEC4);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX_ID"] = constt(ShaderLanguage::TYPE_INT);