mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 11:32:13 +00:00
Add multiple specialization constants to Forward+ and Mobile.
This commit is contained in:
parent
1bffd6c73b
commit
53099c56f0
@ -395,6 +395,10 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
|
||||
RID xforms_uniform_set = surf->owner->transforms_uniform_set;
|
||||
|
||||
SceneShaderForwardClustered::ShaderSpecialization pipeline_specialization = p_params->base_specialization;
|
||||
pipeline_specialization.multimesh = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH);
|
||||
pipeline_specialization.multimesh_format_2d = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D);
|
||||
pipeline_specialization.multimesh_has_color = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR);
|
||||
pipeline_specialization.multimesh_has_custom_data = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA);
|
||||
|
||||
if constexpr (p_pass_mode == PASS_MODE_COLOR) {
|
||||
pipeline_specialization.use_light_soft_shadows = element_info.uses_softshadow;
|
||||
|
@ -374,6 +374,10 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip
|
||||
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
|
||||
specialization_constants.push_back(sc);
|
||||
|
||||
sc.constant_id = 1;
|
||||
sc.int_value = p_pipeline_key.shader_specialization.packed_1;
|
||||
specialization_constants.push_back(sc);
|
||||
|
||||
RID shader_rid = get_shader_variant(p_pipeline_key.version, p_pipeline_key.color_pass_flags, p_pipeline_key.ubershader);
|
||||
ERR_FAIL_COND(shader_rid.is_null());
|
||||
|
||||
|
@ -117,7 +117,17 @@ public:
|
||||
uint32_t packed_0;
|
||||
};
|
||||
|
||||
uint32_t packed_1;
|
||||
union {
|
||||
struct {
|
||||
uint32_t multimesh : 1;
|
||||
uint32_t multimesh_format_2d : 1;
|
||||
uint32_t multimesh_has_color : 1;
|
||||
uint32_t multimesh_has_custom_data : 1;
|
||||
};
|
||||
|
||||
uint32_t packed_1;
|
||||
};
|
||||
|
||||
uint32_t packed_2;
|
||||
};
|
||||
|
||||
|
@ -911,14 +911,19 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
Color clear_color = p_default_bg_color;
|
||||
bool load_color = false;
|
||||
bool copy_canvas = false;
|
||||
bool use_ambient_cubemap = false;
|
||||
bool use_reflection_cubemap = false;
|
||||
|
||||
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
|
||||
clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black
|
||||
} else if (is_environment(p_render_data->environment)) {
|
||||
RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(p_render_data->environment);
|
||||
RS::EnvironmentBG bg_mode = environment_get_background(p_render_data->environment);
|
||||
float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment);
|
||||
bg_energy_multiplier *= environment_get_bg_intensity(p_render_data->environment);
|
||||
RS::EnvironmentReflectionSource reflection_source = environment_get_reflection_source(p_render_data->environment);
|
||||
use_ambient_cubemap = (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY;
|
||||
use_reflection_cubemap = (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY;
|
||||
|
||||
if (p_render_data->camera_attributes.is_valid()) {
|
||||
bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
|
||||
@ -963,7 +968,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
}
|
||||
|
||||
// setup sky if used for ambient, reflections, or background
|
||||
if (draw_sky || draw_sky_fog_only || (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
|
||||
if (draw_sky || draw_sky_fog_only || (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY) {
|
||||
RENDER_TIMESTAMP("Setup Sky");
|
||||
RD::get_singleton()->draw_command_begin_label("Setup Sky");
|
||||
|
||||
@ -1008,13 +1013,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
SceneShaderForwardMobile::ShaderSpecialization base_specialization = scene_shader.default_specialization;
|
||||
|
||||
{
|
||||
//figure out spec constants
|
||||
|
||||
if (p_render_data->directional_light_count > 0) {
|
||||
base_specialization.use_directional_soft_shadows = p_render_data->directional_light_soft_shadows;
|
||||
} else {
|
||||
base_specialization.disable_directional_lights = true;
|
||||
}
|
||||
base_specialization.use_directional_soft_shadows = p_render_data->directional_light_count > 0 ? p_render_data->directional_light_soft_shadows : false;
|
||||
base_specialization.directional_lights = p_render_data->directional_light_count;
|
||||
|
||||
if (!is_environment(p_render_data->environment) || !environment_get_fog_enabled(p_render_data->environment)) {
|
||||
base_specialization.disable_fog = true;
|
||||
@ -1023,6 +1023,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
if (p_render_data->environment.is_valid() && environment_get_fog_mode(p_render_data->environment) == RS::EnvironmentFogMode::ENV_FOG_MODE_DEPTH) {
|
||||
base_specialization.use_depth_fog = true;
|
||||
}
|
||||
|
||||
base_specialization.scene_use_ambient_cubemap = use_ambient_cubemap;
|
||||
base_specialization.scene_use_reflection_cubemap = use_reflection_cubemap;
|
||||
base_specialization.scene_roughness_limiter_enabled = p_render_data->render_buffers.is_valid() && screen_space_roughness_limiter_is_active();
|
||||
}
|
||||
|
||||
{
|
||||
@ -2144,7 +2148,10 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
||||
}
|
||||
|
||||
SceneShaderForwardMobile::ShaderSpecialization pipeline_specialization = p_params->base_specialization;
|
||||
pipeline_specialization.is_multimesh = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH);
|
||||
pipeline_specialization.multimesh = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH);
|
||||
pipeline_specialization.multimesh_format_2d = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D);
|
||||
pipeline_specialization.multimesh_has_color = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR);
|
||||
pipeline_specialization.multimesh_has_custom_data = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA);
|
||||
|
||||
SceneState::PushConstant push_constant;
|
||||
push_constant.base_index = i + p_params->element_offset;
|
||||
@ -2165,10 +2172,10 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
||||
} else {
|
||||
pipeline_specialization.use_light_projector = inst->use_projector;
|
||||
pipeline_specialization.use_light_soft_shadows = inst->use_soft_shadow;
|
||||
pipeline_specialization.disable_omni_lights = inst->omni_light_count == 0;
|
||||
pipeline_specialization.disable_spot_lights = inst->spot_light_count == 0;
|
||||
pipeline_specialization.disable_reflection_probes = inst->reflection_probe_count == 0;
|
||||
pipeline_specialization.disable_decals = inst->decals_count == 0;
|
||||
pipeline_specialization.omni_lights = inst->omni_light_count;
|
||||
pipeline_specialization.spot_lights = inst->spot_light_count;
|
||||
pipeline_specialization.reflection_probes = inst->reflection_probe_count;
|
||||
pipeline_specialization.decals = inst->decals_count;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
|
||||
|
@ -237,6 +237,7 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli
|
||||
"VERSION:", p_pipeline_key.version,
|
||||
"SPEC PACKED #0:", p_pipeline_key.shader_specialization.packed_0,
|
||||
"SPEC PACKED #1:", p_pipeline_key.shader_specialization.packed_1,
|
||||
"SPEC PACKED #2:", p_pipeline_key.shader_specialization.packed_2,
|
||||
"RENDER PASS:", p_pipeline_key.render_pass,
|
||||
"WIREFRAME:", p_pipeline_key.wireframe);
|
||||
#endif
|
||||
|
@ -65,25 +65,35 @@ public:
|
||||
uint32_t use_directional_soft_shadows : 1;
|
||||
uint32_t decal_use_mipmaps : 1;
|
||||
uint32_t projector_use_mipmaps : 1;
|
||||
uint32_t disable_omni_lights : 1;
|
||||
uint32_t disable_spot_lights : 1;
|
||||
uint32_t disable_reflection_probes : 1;
|
||||
uint32_t disable_directional_lights : 1;
|
||||
uint32_t disable_decals : 1;
|
||||
uint32_t disable_fog : 1;
|
||||
uint32_t use_depth_fog : 1;
|
||||
uint32_t is_multimesh : 1;
|
||||
uint32_t use_lightmap_bicubic_filter : 1;
|
||||
uint32_t multimesh : 1;
|
||||
uint32_t multimesh_format_2d : 1;
|
||||
uint32_t multimesh_has_color : 1;
|
||||
uint32_t multimesh_has_custom_data : 1;
|
||||
uint32_t scene_use_ambient_cubemap : 1;
|
||||
uint32_t scene_use_reflection_cubemap : 1;
|
||||
uint32_t scene_roughness_limiter_enabled : 1;
|
||||
uint32_t padding : 5;
|
||||
uint32_t soft_shadow_samples : 6;
|
||||
uint32_t penumbra_shadow_samples : 6;
|
||||
uint32_t directional_soft_shadow_samples : 6;
|
||||
};
|
||||
|
||||
uint32_t packed_0;
|
||||
};
|
||||
|
||||
union {
|
||||
uint32_t directional_penumbra_shadow_samples : 6;
|
||||
struct {
|
||||
uint32_t directional_soft_shadow_samples : 6;
|
||||
uint32_t directional_penumbra_shadow_samples : 6;
|
||||
uint32_t omni_lights : 4;
|
||||
uint32_t spot_lights : 4;
|
||||
uint32_t reflection_probes : 4;
|
||||
uint32_t directional_lights : 4;
|
||||
uint32_t decals : 4;
|
||||
};
|
||||
|
||||
uint32_t packed_1;
|
||||
};
|
||||
|
||||
|
@ -211,6 +211,13 @@ vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec
|
||||
}
|
||||
#endif
|
||||
|
||||
uint multimesh_stride() {
|
||||
uint stride = sc_multimesh_format_2d() ? 2 : 3;
|
||||
stride += sc_multimesh_has_color() ? 1 : 0;
|
||||
stride += sc_multimesh_has_custom_data() ? 1 : 0;
|
||||
return stride;
|
||||
}
|
||||
|
||||
void vertex_shader(vec3 vertex_input,
|
||||
#ifdef NORMAL_USED
|
||||
in vec3 normal_input,
|
||||
@ -219,7 +226,7 @@ void vertex_shader(vec3 vertex_input,
|
||||
in vec3 tangent_input,
|
||||
in vec3 binormal_input,
|
||||
#endif
|
||||
in uint instance_index, in bool is_multimesh, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) {
|
||||
in uint instance_index, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) {
|
||||
vec4 instance_custom = vec4(0.0);
|
||||
#if defined(COLOR_USED)
|
||||
color_interp = color_attrib;
|
||||
@ -248,7 +255,7 @@ void vertex_shader(vec3 vertex_input,
|
||||
mat4 matrix;
|
||||
mat4 read_model_matrix = model_matrix;
|
||||
|
||||
if (is_multimesh) {
|
||||
if (sc_multimesh()) {
|
||||
//multimesh, instances are for it
|
||||
|
||||
#ifdef USE_PARTICLE_TRAILS
|
||||
@ -296,25 +303,10 @@ void vertex_shader(vec3 vertex_input,
|
||||
#endif
|
||||
|
||||
#else
|
||||
uint stride = 0;
|
||||
{
|
||||
//TODO implement a small lookup table for the stride
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
|
||||
stride += 2;
|
||||
} else {
|
||||
stride += 3;
|
||||
}
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
|
||||
stride += 1;
|
||||
}
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
|
||||
stride += 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint stride = multimesh_stride();
|
||||
uint offset = stride * (gl_InstanceIndex + multimesh_offset);
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
|
||||
if (sc_multimesh_format_2d()) {
|
||||
matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
|
||||
offset += 2;
|
||||
} else {
|
||||
@ -322,14 +314,14 @@ void vertex_shader(vec3 vertex_input,
|
||||
offset += 3;
|
||||
}
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
|
||||
if (sc_multimesh_has_color()) {
|
||||
#ifdef COLOR_USED
|
||||
color_interp *= transforms.data[offset];
|
||||
#endif
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
|
||||
if (sc_multimesh_has_custom_data()) {
|
||||
instance_custom = transforms.data[offset];
|
||||
}
|
||||
|
||||
@ -427,7 +419,7 @@ void vertex_shader(vec3 vertex_input,
|
||||
// Then we combine the translations from the model matrix and the view matrix using emulated doubles.
|
||||
// We add the result to the vertex and ignore the final lost precision.
|
||||
vec3 model_origin = model_matrix[3].xyz;
|
||||
if (is_multimesh) {
|
||||
if (sc_multimesh()) {
|
||||
vertex = mat3(matrix) * vertex;
|
||||
model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision);
|
||||
}
|
||||
@ -708,9 +700,7 @@ void _unpack_vertex_attributes(vec4 p_vertex_in, vec3 p_compressed_aabb_position
|
||||
|
||||
void main() {
|
||||
uint instance_index = draw_call.instance_index;
|
||||
|
||||
bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH);
|
||||
if (!is_multimesh) {
|
||||
if (!sc_multimesh()) {
|
||||
instance_index += gl_InstanceIndex;
|
||||
}
|
||||
|
||||
@ -753,7 +743,7 @@ void main() {
|
||||
prev_tangent,
|
||||
prev_binormal,
|
||||
#endif
|
||||
instance_index, is_multimesh, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position);
|
||||
instance_index, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position);
|
||||
#else
|
||||
// Unused output.
|
||||
vec4 screen_position;
|
||||
@ -792,7 +782,7 @@ void main() {
|
||||
tangent,
|
||||
binormal,
|
||||
#endif
|
||||
instance_index, is_multimesh, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position);
|
||||
instance_index, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position);
|
||||
}
|
||||
|
||||
#[fragment]
|
||||
|
@ -59,6 +59,10 @@ uint sc_packed_0() {
|
||||
return draw_call.sc_packed_0;
|
||||
}
|
||||
|
||||
uint sc_packed_1() {
|
||||
return draw_call.sc_packed_1;
|
||||
}
|
||||
|
||||
uint uc_cull_mode() {
|
||||
return (draw_call.uc_packed_0 >> 0) & 3U;
|
||||
}
|
||||
@ -67,11 +71,16 @@ uint uc_cull_mode() {
|
||||
|
||||
// Pull the constants from the pipeline's specialization constants.
|
||||
layout(constant_id = 0) const uint pso_sc_packed_0 = 0;
|
||||
layout(constant_id = 1) const uint pso_sc_packed_1 = 0;
|
||||
|
||||
uint sc_packed_0() {
|
||||
return pso_sc_packed_0;
|
||||
}
|
||||
|
||||
uint sc_packed_1() {
|
||||
return pso_sc_packed_1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool sc_use_forward_gi() {
|
||||
@ -122,6 +131,22 @@ uint sc_directional_penumbra_shadow_samples() {
|
||||
return (sc_packed_0() >> 26) & 63U;
|
||||
}
|
||||
|
||||
bool sc_multimesh() {
|
||||
return ((sc_packed_1() >> 0) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_multimesh_format_2d() {
|
||||
return ((sc_packed_1() >> 1) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_multimesh_has_color() {
|
||||
return ((sc_packed_1() >> 2) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_multimesh_has_custom_data() {
|
||||
return ((sc_packed_1() >> 3) & 1U) != 0;
|
||||
}
|
||||
|
||||
float sc_luminance_multiplier() {
|
||||
// Not used in clustered renderer but we share some code with the mobile renderer that requires this.
|
||||
return 1.0;
|
||||
@ -144,10 +169,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler;
|
||||
#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9)
|
||||
#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10)
|
||||
#define INSTANCE_FLAGS_PARTICLES (1 << 11)
|
||||
#define INSTANCE_FLAGS_MULTIMESH (1 << 12)
|
||||
#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13)
|
||||
#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14)
|
||||
#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15)
|
||||
#define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16
|
||||
#define INSTANCE_FLAGS_FADE_SHIFT 24
|
||||
//3 bits of stride
|
||||
|
@ -178,6 +178,13 @@ vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec
|
||||
}
|
||||
#endif
|
||||
|
||||
uint multimesh_stride() {
|
||||
uint stride = sc_multimesh_format_2d() ? 2 : 3;
|
||||
stride += sc_multimesh_has_color() ? 1 : 0;
|
||||
stride += sc_multimesh_has_custom_data() ? 1 : 0;
|
||||
return stride;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec4 instance_custom = vec4(0.0);
|
||||
#if defined(COLOR_USED)
|
||||
@ -208,7 +215,7 @@ void main() {
|
||||
mat4 matrix;
|
||||
mat4 read_model_matrix = model_matrix;
|
||||
|
||||
if (sc_is_multimesh()) {
|
||||
if (sc_multimesh()) {
|
||||
//multimesh, instances are for it
|
||||
|
||||
#ifdef USE_PARTICLE_TRAILS
|
||||
@ -256,25 +263,10 @@ void main() {
|
||||
#endif
|
||||
|
||||
#else
|
||||
uint stride = 0;
|
||||
{
|
||||
//TODO implement a small lookup table for the stride
|
||||
if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
|
||||
stride += 2;
|
||||
} else {
|
||||
stride += 3;
|
||||
}
|
||||
if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
|
||||
stride += 1;
|
||||
}
|
||||
if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
|
||||
stride += 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint stride = multimesh_stride();
|
||||
uint offset = stride * gl_InstanceIndex;
|
||||
|
||||
if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
|
||||
if (sc_multimesh_format_2d()) {
|
||||
matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
|
||||
offset += 2;
|
||||
} else {
|
||||
@ -282,14 +274,14 @@ void main() {
|
||||
offset += 3;
|
||||
}
|
||||
|
||||
if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
|
||||
if (sc_multimesh_has_color()) {
|
||||
#ifdef COLOR_USED
|
||||
color_interp *= transforms.data[offset];
|
||||
#endif
|
||||
offset += 1;
|
||||
}
|
||||
|
||||
if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
|
||||
if (sc_multimesh_has_custom_data()) {
|
||||
instance_custom = transforms.data[offset];
|
||||
}
|
||||
|
||||
@ -404,7 +396,7 @@ void main() {
|
||||
// Then we combine the translations from the model matrix and the view matrix using emulated doubles.
|
||||
// We add the result to the vertex and ignore the final lost precision.
|
||||
vec3 model_origin = model_matrix[3].xyz;
|
||||
if (sc_is_multimesh()) {
|
||||
if (sc_multimesh()) {
|
||||
vertex = mat3(matrix) * vertex;
|
||||
model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision);
|
||||
}
|
||||
@ -461,50 +453,24 @@ void main() {
|
||||
diffuse_light_interp = vec4(0.0);
|
||||
specular_light_interp = vec4(0.0);
|
||||
|
||||
if (!sc_disable_omni_lights()) {
|
||||
uint light_indices = instances.data[draw_call.instance_index].omni_lights.x;
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
uint light_index = light_indices & 0xFF;
|
||||
if (i == 3) {
|
||||
light_indices = instances.data[draw_call.instance_index].omni_lights.y;
|
||||
} else {
|
||||
light_indices = light_indices >> 8;
|
||||
}
|
||||
|
||||
if (light_index == 0xFF) {
|
||||
break;
|
||||
}
|
||||
|
||||
light_process_omni_vertex(light_index, vertex, view, normal, roughness,
|
||||
diffuse_light_interp.rgb, specular_light_interp.rgb);
|
||||
}
|
||||
uvec2 omni_light_indices = instances.data[draw_call.instance_index].omni_lights;
|
||||
for (uint i = 0; i < sc_omni_lights(); i++) {
|
||||
uint light_index = (i > 3) ? ((omni_light_indices.y >> ((i - 4) * 8)) & 0xFF) : ((omni_light_indices.x >> (i * 8)) & 0xFF);
|
||||
light_process_omni_vertex(light_index, vertex, view, normal, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb);
|
||||
}
|
||||
|
||||
if (!sc_disable_spot_lights()) {
|
||||
uint light_indices = instances.data[draw_call.instance_index].spot_lights.x;
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
uint light_index = light_indices & 0xFF;
|
||||
if (i == 3) {
|
||||
light_indices = instances.data[draw_call.instance_index].spot_lights.y;
|
||||
} else {
|
||||
light_indices = light_indices >> 8;
|
||||
}
|
||||
|
||||
if (light_index == 0xFF) {
|
||||
break;
|
||||
}
|
||||
|
||||
light_process_spot_vertex(light_index, vertex, view, normal, roughness,
|
||||
diffuse_light_interp.rgb, specular_light_interp.rgb);
|
||||
}
|
||||
uvec2 spot_light_indices = instances.data[draw_call.instance_index].spot_lights;
|
||||
for (uint i = 0; i < sc_spot_lights(); i++) {
|
||||
uint light_index = (i > 3) ? ((spot_light_indices.y >> ((i - 4) * 8)) & 0xFF) : ((spot_light_indices.x >> (i * 8)) & 0xFF);
|
||||
light_process_spot_vertex(light_index, vertex, view, normal, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb);
|
||||
}
|
||||
|
||||
if (!sc_disable_directional_lights()) {
|
||||
if (sc_directional_lights() > 0) {
|
||||
// We process the first directional light separately as it may have shadows.
|
||||
vec3 directional_diffuse = vec3(0.0);
|
||||
vec3 directional_specular = vec3(0.0);
|
||||
|
||||
for (uint i = 0; i < scene_data.directional_light_count; i++) {
|
||||
for (uint i = 0; i < sc_directional_lights(); i++) {
|
||||
if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
|
||||
continue; // Not masked, skip.
|
||||
}
|
||||
@ -823,7 +789,7 @@ vec4 fog_process(vec3 vertex) {
|
||||
float sun_total = 0.0;
|
||||
vec3 view = normalize(vertex);
|
||||
|
||||
for (uint i = 0; i < scene_data_block.data.directional_light_count; i++) {
|
||||
for (uint i = 0; i < sc_directional_lights(); i++) {
|
||||
vec3 light_color = directional_lights.data[i].color * directional_lights.data[i].energy;
|
||||
float light_amount = pow(max(dot(view, directional_lights.data[i].direction), 0.0), 8.0);
|
||||
fog_color += light_color * light_amount * scene_data_block.data.fog_sun_scatter;
|
||||
@ -1110,97 +1076,83 @@ void main() {
|
||||
vec3 vertex_ddx = dFdx(vertex);
|
||||
vec3 vertex_ddy = dFdy(vertex);
|
||||
|
||||
if (!sc_disable_decals()) { //Decals
|
||||
// must implement
|
||||
uvec2 decal_indices = instances.data[draw_call.instance_index].decals;
|
||||
for (uint i = 0; i < sc_decals(); i++) {
|
||||
uint decal_index = (i > 3) ? ((decal_indices.y >> ((i - 4) * 8)) & 0xFF) : ((decal_indices.x >> (i * 8)) & 0xFF);
|
||||
if (!bool(decals.data[decal_index].mask & instances.data[draw_call.instance_index].layer_mask)) {
|
||||
continue; //not masked
|
||||
}
|
||||
|
||||
uint decal_indices = instances.data[draw_call.instance_index].decals.x;
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
uint decal_index = decal_indices & 0xFF;
|
||||
if (i == 3) {
|
||||
decal_indices = instances.data[draw_call.instance_index].decals.y;
|
||||
vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
|
||||
if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
|
||||
continue; //out of decal
|
||||
}
|
||||
|
||||
float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade);
|
||||
|
||||
if (decals.data[decal_index].normal_fade > 0.0) {
|
||||
fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5);
|
||||
}
|
||||
|
||||
//we need ddx/ddy for mipmaps, so simulate them
|
||||
vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz;
|
||||
vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz;
|
||||
|
||||
if (decals.data[decal_index].albedo_rect != vec4(0.0)) {
|
||||
//has albedo
|
||||
vec4 decal_albedo;
|
||||
if (sc_decal_use_mipmaps()) {
|
||||
decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw);
|
||||
} else {
|
||||
decal_indices = decal_indices >> 8;
|
||||
decal_albedo = textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, 0.0);
|
||||
}
|
||||
decal_albedo *= decals.data[decal_index].modulate;
|
||||
decal_albedo.a *= fade;
|
||||
albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);
|
||||
|
||||
if (decal_index == 0xFF) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bool(decals.data[decal_index].mask & instances.data[draw_call.instance_index].layer_mask)) {
|
||||
continue; //not masked
|
||||
}
|
||||
|
||||
vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
|
||||
if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
|
||||
continue; //out of decal
|
||||
}
|
||||
|
||||
float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade);
|
||||
|
||||
if (decals.data[decal_index].normal_fade > 0.0) {
|
||||
fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5);
|
||||
}
|
||||
|
||||
//we need ddx/ddy for mipmaps, so simulate them
|
||||
vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz;
|
||||
vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz;
|
||||
|
||||
if (decals.data[decal_index].albedo_rect != vec4(0.0)) {
|
||||
//has albedo
|
||||
vec4 decal_albedo;
|
||||
if (decals.data[decal_index].normal_rect != vec4(0.0)) {
|
||||
vec3 decal_normal;
|
||||
if (sc_decal_use_mipmaps()) {
|
||||
decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw);
|
||||
decal_normal = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
|
||||
} else {
|
||||
decal_albedo = textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, 0.0);
|
||||
decal_normal = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, 0.0).xyz;
|
||||
}
|
||||
decal_albedo *= decals.data[decal_index].modulate;
|
||||
decal_albedo.a *= fade;
|
||||
albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);
|
||||
decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software
|
||||
decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));
|
||||
//convert to view space, use xzy because y is up
|
||||
decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz;
|
||||
|
||||
if (decals.data[decal_index].normal_rect != vec4(0.0)) {
|
||||
vec3 decal_normal;
|
||||
if (sc_decal_use_mipmaps()) {
|
||||
decal_normal = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
|
||||
} else {
|
||||
decal_normal = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, 0.0).xyz;
|
||||
}
|
||||
decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software
|
||||
decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));
|
||||
//convert to view space, use xzy because y is up
|
||||
decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz;
|
||||
|
||||
normal = normalize(mix(normal, decal_normal, decal_albedo.a));
|
||||
}
|
||||
|
||||
if (decals.data[decal_index].orm_rect != vec4(0.0)) {
|
||||
vec3 decal_orm;
|
||||
if (sc_decal_use_mipmaps()) {
|
||||
decal_orm = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
|
||||
} else {
|
||||
decal_orm = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, 0.0).xyz;
|
||||
}
|
||||
ao = mix(ao, decal_orm.r, decal_albedo.a);
|
||||
roughness = mix(roughness, decal_orm.g, decal_albedo.a);
|
||||
metallic = mix(metallic, decal_orm.b, decal_albedo.a);
|
||||
}
|
||||
normal = normalize(mix(normal, decal_normal, decal_albedo.a));
|
||||
}
|
||||
|
||||
if (decals.data[decal_index].emission_rect != vec4(0.0)) {
|
||||
//emission is additive, so its independent from albedo
|
||||
if (decals.data[decal_index].orm_rect != vec4(0.0)) {
|
||||
vec3 decal_orm;
|
||||
if (sc_decal_use_mipmaps()) {
|
||||
emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade;
|
||||
decal_orm = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
|
||||
} else {
|
||||
emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade;
|
||||
decal_orm = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, 0.0).xyz;
|
||||
}
|
||||
ao = mix(ao, decal_orm.r, decal_albedo.a);
|
||||
roughness = mix(roughness, decal_orm.g, decal_albedo.a);
|
||||
metallic = mix(metallic, decal_orm.b, decal_albedo.a);
|
||||
}
|
||||
}
|
||||
} //Decals
|
||||
|
||||
if (decals.data[decal_index].emission_rect != vec4(0.0)) {
|
||||
//emission is additive, so its independent from albedo
|
||||
if (sc_decal_use_mipmaps()) {
|
||||
emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade;
|
||||
} else {
|
||||
emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //!MODE_RENDER_DEPTH
|
||||
|
||||
/////////////////////// LIGHTING //////////////////////////////
|
||||
|
||||
#ifdef NORMAL_USED
|
||||
if (scene_data.roughness_limiter_enabled) {
|
||||
if (sc_scene_roughness_limiter_enabled()) {
|
||||
//https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
|
||||
float roughness2 = roughness * roughness;
|
||||
vec3 dndu = dFdx(normal), dndv = dFdy(normal);
|
||||
@ -1225,7 +1177,7 @@ void main() {
|
||||
|
||||
#ifndef AMBIENT_LIGHT_DISABLED
|
||||
|
||||
if (scene_data.use_reflection_cubemap) {
|
||||
if (sc_scene_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;
|
||||
@ -1266,7 +1218,7 @@ void main() {
|
||||
if (scene_data.use_ambient_light) {
|
||||
ambient_light = scene_data.ambient_light_color_energy.rgb;
|
||||
|
||||
if (scene_data.use_ambient_cubemap) {
|
||||
if (sc_scene_use_ambient_cubemap()) {
|
||||
vec3 ambient_dir = scene_data.radiance_inverse_xform * 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;
|
||||
@ -1285,7 +1237,7 @@ void main() {
|
||||
#endif // CUSTOM_IRRADIANCE_USED
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
|
||||
if (scene_data.use_reflection_cubemap) {
|
||||
if (sc_scene_use_reflection_cubemap()) {
|
||||
vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map
|
||||
float NoV = max(dot(n, view), 0.0001);
|
||||
vec3 ref_vec = reflect(-view, n);
|
||||
@ -1393,12 +1345,10 @@ void main() {
|
||||
|
||||
// skipping ssao, do we remove ssao totally?
|
||||
|
||||
if (!sc_disable_reflection_probes()) { //Reflection probes
|
||||
if (sc_reflection_probes() > 0) {
|
||||
vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
uint reflection_indices = instances.data[draw_call.instance_index].reflection_probes.x;
|
||||
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
// https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
|
||||
vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
|
||||
@ -1411,18 +1361,9 @@ void main() {
|
||||
vec3 ref_vec = normalize(reflect(-view, bent_normal));
|
||||
ref_vec = mix(ref_vec, bent_normal, roughness * roughness);
|
||||
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
uint reflection_index = reflection_indices & 0xFF;
|
||||
if (i == 3) {
|
||||
reflection_indices = instances.data[draw_call.instance_index].reflection_probes.y;
|
||||
} else {
|
||||
reflection_indices = reflection_indices >> 8;
|
||||
}
|
||||
|
||||
if (reflection_index == 0xFF) {
|
||||
break;
|
||||
}
|
||||
|
||||
uvec2 reflection_indices = instances.data[draw_call.instance_index].reflection_probes;
|
||||
for (uint i = 0; i < sc_reflection_probes(); i++) {
|
||||
uint reflection_index = (i > 3) ? ((reflection_indices.y >> ((i - 4) * 8)) & 0xFF) : ((reflection_indices.x >> (i * 8)) & 0xFF);
|
||||
reflection_process(reflection_index, vertex, ref_vec, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
|
||||
}
|
||||
|
||||
@ -1487,7 +1428,7 @@ void main() {
|
||||
specular_light += specular_light_interp.rgb * f0;
|
||||
#endif
|
||||
|
||||
if (!sc_disable_directional_lights()) { //directional light
|
||||
if (sc_directional_lights() > 0) {
|
||||
#ifndef SHADOWS_DISABLED
|
||||
// Do shadow and lighting in two passes to reduce register pressure
|
||||
uint shadow0 = 0;
|
||||
@ -1497,7 +1438,7 @@ void main() {
|
||||
// Only process the first light's shadow for vertex lighting.
|
||||
for (uint i = 0; i < 1; i++) {
|
||||
#else
|
||||
for (uint i = 0; i < scene_data.directional_light_count; i++) {
|
||||
for (uint i = 0; i < sc_directional_lights(); i++) {
|
||||
#endif
|
||||
|
||||
if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
|
||||
@ -1612,7 +1553,7 @@ void main() {
|
||||
#endif // SHADOWS_DISABLED
|
||||
|
||||
#ifndef USE_VERTEX_LIGHTING
|
||||
for (uint i = 0; i < scene_data.directional_light_count; i++) {
|
||||
for (uint i = 0; i < sc_directional_lights(); i++) {
|
||||
if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
|
||||
continue; //not masked
|
||||
}
|
||||
@ -1678,95 +1619,72 @@ void main() {
|
||||
} //directional light
|
||||
|
||||
#ifndef USE_VERTEX_LIGHTING
|
||||
if (!sc_disable_omni_lights()) { //omni lights
|
||||
uint light_indices = instances.data[draw_call.instance_index].omni_lights.x;
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
uint light_index = light_indices & 0xFF;
|
||||
if (i == 3) {
|
||||
light_indices = instances.data[draw_call.instance_index].omni_lights.y;
|
||||
} else {
|
||||
light_indices = light_indices >> 8;
|
||||
}
|
||||
uvec2 omni_indices = instances.data[draw_call.instance_index].omni_lights;
|
||||
for (uint i = 0; i < sc_omni_lights(); i++) {
|
||||
uint light_index = (i > 3) ? ((omni_indices.y >> ((i - 4) * 8)) & 0xFF) : ((omni_indices.x >> (i * 8)) & 0xFF);
|
||||
|
||||
if (light_index == 0xFF) {
|
||||
break;
|
||||
}
|
||||
float shadow = light_process_omni_shadow(light_index, vertex, normal, scene_data.taa_frame_count);
|
||||
|
||||
float shadow = light_process_omni_shadow(light_index, vertex, normal, scene_data.taa_frame_count);
|
||||
shadow = blur_shadow(shadow);
|
||||
|
||||
shadow = blur_shadow(shadow);
|
||||
|
||||
// Fragment lighting
|
||||
light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha,
|
||||
// Fragment lighting
|
||||
light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha,
|
||||
#ifdef LIGHT_BACKLIGHT_USED
|
||||
backlight,
|
||||
backlight,
|
||||
#endif
|
||||
/*
|
||||
#ifdef LIGHT_TRANSMITTANCE_USED
|
||||
transmittance_color,
|
||||
transmittance_depth,
|
||||
transmittance_boost,
|
||||
transmittance_color,
|
||||
transmittance_depth,
|
||||
transmittance_boost,
|
||||
#endif
|
||||
*/
|
||||
#ifdef LIGHT_RIM_USED
|
||||
rim,
|
||||
rim_tint,
|
||||
rim,
|
||||
rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
tangent,
|
||||
binormal, anisotropy,
|
||||
tangent,
|
||||
binormal, anisotropy,
|
||||
#endif
|
||||
diffuse_light, specular_light);
|
||||
}
|
||||
} //omni lights
|
||||
diffuse_light, specular_light);
|
||||
}
|
||||
|
||||
if (!sc_disable_spot_lights()) { //spot lights
|
||||
uvec2 spot_indices = instances.data[draw_call.instance_index].spot_lights;
|
||||
for (uint i = 0; i < sc_spot_lights(); i++) {
|
||||
uint light_index = (i > 3) ? ((spot_indices.y >> ((i - 4) * 8)) & 0xFF) : ((spot_indices.x >> (i * 8)) & 0xFF);
|
||||
|
||||
uint light_indices = instances.data[draw_call.instance_index].spot_lights.x;
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
uint light_index = light_indices & 0xFF;
|
||||
if (i == 3) {
|
||||
light_indices = instances.data[draw_call.instance_index].spot_lights.y;
|
||||
} else {
|
||||
light_indices = light_indices >> 8;
|
||||
}
|
||||
float shadow = light_process_spot_shadow(light_index, vertex, normal, scene_data.taa_frame_count);
|
||||
|
||||
if (light_index == 0xFF) {
|
||||
break;
|
||||
}
|
||||
shadow = blur_shadow(shadow);
|
||||
|
||||
float shadow = light_process_spot_shadow(light_index, vertex, normal, scene_data.taa_frame_count);
|
||||
|
||||
shadow = blur_shadow(shadow);
|
||||
|
||||
light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha,
|
||||
light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha,
|
||||
#ifdef LIGHT_BACKLIGHT_USED
|
||||
backlight,
|
||||
backlight,
|
||||
#endif
|
||||
/*
|
||||
#ifdef LIGHT_TRANSMITTANCE_USED
|
||||
transmittance_color,
|
||||
transmittance_depth,
|
||||
transmittance_boost,
|
||||
transmittance_color,
|
||||
transmittance_depth,
|
||||
transmittance_boost,
|
||||
#endif
|
||||
*/
|
||||
#ifdef LIGHT_RIM_USED
|
||||
rim,
|
||||
rim_tint,
|
||||
rim,
|
||||
rim_tint,
|
||||
#endif
|
||||
#ifdef LIGHT_CLEARCOAT_USED
|
||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
||||
#endif
|
||||
#ifdef LIGHT_ANISOTROPY_USED
|
||||
tangent,
|
||||
binormal, anisotropy,
|
||||
tangent,
|
||||
binormal, anisotropy,
|
||||
#endif
|
||||
diffuse_light, specular_light);
|
||||
}
|
||||
} //spot lights
|
||||
diffuse_light, specular_light);
|
||||
}
|
||||
#endif // !VERTEX_LIGHTING
|
||||
|
||||
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
|
||||
|
@ -95,58 +95,82 @@ bool sc_projector_use_mipmaps() {
|
||||
return ((sc_packed_0() >> 4) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_disable_omni_lights() {
|
||||
bool sc_disable_fog() {
|
||||
return ((sc_packed_0() >> 5) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_disable_spot_lights() {
|
||||
bool sc_use_depth_fog() {
|
||||
return ((sc_packed_0() >> 6) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_disable_reflection_probes() {
|
||||
bool sc_use_lightmap_bicubic_filter() {
|
||||
return ((sc_packed_0() >> 7) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_disable_directional_lights() {
|
||||
bool sc_multimesh() {
|
||||
return ((sc_packed_0() >> 8) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_disable_decals() {
|
||||
bool sc_multimesh_format_2d() {
|
||||
return ((sc_packed_0() >> 9) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_disable_fog() {
|
||||
bool sc_multimesh_has_color() {
|
||||
return ((sc_packed_0() >> 10) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_use_depth_fog() {
|
||||
bool sc_multimesh_has_custom_data() {
|
||||
return ((sc_packed_0() >> 11) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_is_multimesh() {
|
||||
bool sc_scene_use_ambient_cubemap() {
|
||||
return ((sc_packed_0() >> 12) & 1U) != 0;
|
||||
}
|
||||
|
||||
bool sc_use_lightmap_bicubic_filter() {
|
||||
bool sc_scene_use_reflection_cubemap() {
|
||||
return ((sc_packed_0() >> 13) & 1U) != 0;
|
||||
}
|
||||
|
||||
uint sc_soft_shadow_samples() {
|
||||
return (sc_packed_0() >> 14) & 63U;
|
||||
bool sc_scene_roughness_limiter_enabled() {
|
||||
return ((sc_packed_0() >> 14) & 1U) != 0;
|
||||
}
|
||||
|
||||
uint sc_penumbra_shadow_samples() {
|
||||
uint sc_soft_shadow_samples() {
|
||||
return (sc_packed_0() >> 20) & 63U;
|
||||
}
|
||||
|
||||
uint sc_directional_soft_shadow_samples() {
|
||||
uint sc_penumbra_shadow_samples() {
|
||||
return (sc_packed_0() >> 26) & 63U;
|
||||
}
|
||||
|
||||
uint sc_directional_penumbra_shadow_samples() {
|
||||
uint sc_directional_soft_shadow_samples() {
|
||||
return (sc_packed_1() >> 0) & 63U;
|
||||
}
|
||||
|
||||
uint sc_directional_penumbra_shadow_samples() {
|
||||
return (sc_packed_1() >> 6) & 63U;
|
||||
}
|
||||
|
||||
uint sc_omni_lights() {
|
||||
return (sc_packed_1() >> 12) & 15U;
|
||||
}
|
||||
|
||||
uint sc_spot_lights() {
|
||||
return (sc_packed_1() >> 16) & 15U;
|
||||
}
|
||||
|
||||
uint sc_reflection_probes() {
|
||||
return (sc_packed_1() >> 20) & 15U;
|
||||
}
|
||||
|
||||
uint sc_directional_lights() {
|
||||
return (sc_packed_1() >> 24) & 15U;
|
||||
}
|
||||
|
||||
uint sc_decals() {
|
||||
return (sc_packed_1() >> 28) & 15U;
|
||||
}
|
||||
|
||||
float sc_luminance_multiplier() {
|
||||
return sc_packed_2();
|
||||
}
|
||||
@ -166,10 +190,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler;
|
||||
#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9)
|
||||
#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10)
|
||||
#define INSTANCE_FLAGS_PARTICLES (1 << 11)
|
||||
#define INSTANCE_FLAGS_MULTIMESH (1 << 12)
|
||||
#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13)
|
||||
#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14)
|
||||
#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15)
|
||||
#define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16
|
||||
//3 bits of stride
|
||||
#define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF
|
||||
|
Loading…
Reference in New Issue
Block a user