Fix Subsurface Scattering

* Works again
* Transmittance also works again
* Removed the curve patamter, exp() function is good enough.
This commit is contained in:
reduz 2021-07-05 14:48:23 -03:00
parent 8cd1b59ea7
commit 7f6027927a
13 changed files with 310 additions and 369 deletions

View File

@ -347,8 +347,6 @@
</member> </member>
<member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color" default="Color(1, 1, 1, 1)"> <member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color" default="Color(1, 1, 1, 1)">
</member> </member>
<member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve" default="1.0">
</member>
<member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth" default="0.1"> <member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth" default="0.1">
</member> </member>
<member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature" default="false"> <member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">

View File

@ -345,7 +345,6 @@ void BaseMaterial3D::init_shaders() {
shader_names->refraction_texture_channel = "refraction_texture_channel"; shader_names->refraction_texture_channel = "refraction_texture_channel";
shader_names->transmittance_color = "transmittance_color"; shader_names->transmittance_color = "transmittance_color";
shader_names->transmittance_curve = "transmittance_curve";
shader_names->transmittance_depth = "transmittance_depth"; shader_names->transmittance_depth = "transmittance_depth";
shader_names->transmittance_boost = "transmittance_boost"; shader_names->transmittance_boost = "transmittance_boost";
@ -692,7 +691,6 @@ void BaseMaterial3D::_update_shader() {
code += "uniform vec4 transmittance_color : hint_color;\n"; code += "uniform vec4 transmittance_color : hint_color;\n";
code += "uniform float transmittance_depth;\n"; code += "uniform float transmittance_depth;\n";
code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n"; code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n";
code += "uniform float transmittance_curve;\n";
code += "uniform float transmittance_boost;\n"; code += "uniform float transmittance_boost;\n";
} }
@ -1194,7 +1192,6 @@ void BaseMaterial3D::_update_shader() {
code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n"; code += "\tSSS_TRANSMITTANCE_COLOR=transmittance_color*trans_color_tex;\n";
code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n"; code += "\tSSS_TRANSMITTANCE_DEPTH=transmittance_depth;\n";
code += "\tSSS_TRANSMITTANCE_CURVE=transmittance_curve;\n";
code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n"; code += "\tSSS_TRANSMITTANCE_BOOST=transmittance_boost;\n";
} }
@ -1438,15 +1435,6 @@ float BaseMaterial3D::get_transmittance_depth() const {
return transmittance_depth; return transmittance_depth;
} }
void BaseMaterial3D::set_transmittance_curve(float p_curve) {
transmittance_curve = p_curve;
RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_curve, p_curve);
}
float BaseMaterial3D::get_transmittance_curve() const {
return transmittance_curve;
}
void BaseMaterial3D::set_transmittance_boost(float p_boost) { void BaseMaterial3D::set_transmittance_boost(float p_boost) {
transmittance_boost = p_boost; transmittance_boost = p_boost;
RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost); RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost);
@ -1765,7 +1753,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
property.usage = PROPERTY_USAGE_NONE; property.usage = PROPERTY_USAGE_NONE;
} }
if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture" || property.name == "subsurf_scatter_transmittance_curve")) { if (flags[FLAG_SUBSURFACE_MODE_SKIN] && (property.name == "subsurf_scatter_transmittance_color" || property.name == "subsurf_scatter_transmittance_texture")) {
property.usage = PROPERTY_USAGE_NONE; property.usage = PROPERTY_USAGE_NONE;
} }
@ -2269,9 +2257,6 @@ void BaseMaterial3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_transmittance_depth", "depth"), &BaseMaterial3D::set_transmittance_depth); ClassDB::bind_method(D_METHOD("set_transmittance_depth", "depth"), &BaseMaterial3D::set_transmittance_depth);
ClassDB::bind_method(D_METHOD("get_transmittance_depth"), &BaseMaterial3D::get_transmittance_depth); ClassDB::bind_method(D_METHOD("get_transmittance_depth"), &BaseMaterial3D::get_transmittance_depth);
ClassDB::bind_method(D_METHOD("set_transmittance_curve", "curve"), &BaseMaterial3D::set_transmittance_curve);
ClassDB::bind_method(D_METHOD("get_transmittance_curve"), &BaseMaterial3D::get_transmittance_curve);
ClassDB::bind_method(D_METHOD("set_transmittance_boost", "boost"), &BaseMaterial3D::set_transmittance_boost); ClassDB::bind_method(D_METHOD("set_transmittance_boost", "boost"), &BaseMaterial3D::set_transmittance_boost);
ClassDB::bind_method(D_METHOD("get_transmittance_boost"), &BaseMaterial3D::get_transmittance_boost); ClassDB::bind_method(D_METHOD("get_transmittance_boost"), &BaseMaterial3D::get_transmittance_boost);
@ -2506,7 +2491,6 @@ void BaseMaterial3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color"), "set_transmittance_color", "get_transmittance_color"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "subsurf_scatter_transmittance_color"), "set_transmittance_color", "get_transmittance_color");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_TRANSMITTANCE); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "subsurf_scatter_transmittance_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_SUBSURFACE_TRANSMITTANCE);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth", PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater"), "set_transmittance_depth", "get_transmittance_depth"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_depth", PROPERTY_HINT_RANGE, "0.001,8,0.001,or_greater"), "set_transmittance_depth", "get_transmittance_depth");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_curve", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_transmittance_curve", "get_transmittance_curve");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_transmittance_boost", "get_transmittance_boost"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "subsurf_scatter_transmittance_boost", PROPERTY_HINT_RANGE, "0.00,1.0,0.01"), "set_transmittance_boost", "get_transmittance_boost");
ADD_GROUP("Back Lighting", "backlight_"); ADD_GROUP("Back Lighting", "backlight_");
@ -2723,7 +2707,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
set_backlight(Color(0, 0, 0)); set_backlight(Color(0, 0, 0));
set_transmittance_color(Color(1, 1, 1, 1)); set_transmittance_color(Color(1, 1, 1, 1));
set_transmittance_depth(0.1); set_transmittance_depth(0.1);
set_transmittance_curve(1.0);
set_transmittance_boost(0.0); set_transmittance_boost(0.0);
set_refraction(0.05); set_refraction(0.05);
set_point_size(1); set_point_size(1);

View File

@ -389,7 +389,6 @@ private:
StringName heightmap_scale; StringName heightmap_scale;
StringName subsurface_scattering_strength; StringName subsurface_scattering_strength;
StringName transmittance_color; StringName transmittance_color;
StringName transmittance_curve;
StringName transmittance_depth; StringName transmittance_depth;
StringName transmittance_boost; StringName transmittance_boost;
StringName backlight; StringName backlight;
@ -458,7 +457,6 @@ private:
float transmittance_amount; float transmittance_amount;
Color transmittance_color; Color transmittance_color;
float transmittance_depth; float transmittance_depth;
float transmittance_curve;
float transmittance_boost; float transmittance_boost;
Color backlight; Color backlight;
@ -602,9 +600,6 @@ public:
void set_transmittance_depth(float p_depth); void set_transmittance_depth(float p_depth);
float get_transmittance_depth() const; float get_transmittance_depth() const;
void set_transmittance_curve(float p_curve);
float get_transmittance_curve() const;
void set_transmittance_boost(float p_boost); void set_transmittance_boost(float p_boost);
float get_transmittance_boost() const; float get_transmittance_boost() const;

View File

@ -1377,6 +1377,24 @@ void EffectsRD::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RI
RD::get_singleton()->compute_list_end(p_barrier); RD::get_singleton()->compute_list_end(p_barrier);
} }
void EffectsRD::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
ResolvePushConstant push_constant;
push_constant.screen_size[0] = p_screen_size.x;
push_constant.screen_size[1] = p_screen_size.y;
push_constant.samples = p_samples;
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[RESOLVE_MODE_DEPTH]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_depth), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_depth), 1);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
RD::get_singleton()->compute_list_end(p_barrier);
}
void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) { void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
Sort::PushConstant push_constant; Sort::PushConstant push_constant;
push_constant.total_elements = p_size; push_constant.total_elements = p_size;
@ -1879,6 +1897,7 @@ EffectsRD::EffectsRD() {
Vector<String> resolve_modes; Vector<String> resolve_modes;
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n"); resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n"); resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
resolve_modes.push_back("\n#define MODE_RESOLVE_DEPTH\n");
resolve.shader.initialize(resolve_modes); resolve.shader.initialize(resolve_modes);

View File

@ -581,6 +581,7 @@ class EffectsRD {
enum ResolveMode { enum ResolveMode {
RESOLVE_MODE_GI, RESOLVE_MODE_GI,
RESOLVE_MODE_GI_VOXEL_GI, RESOLVE_MODE_GI_VOXEL_GI,
RESOLVE_MODE_DEPTH,
RESOLVE_MODE_MAX RESOLVE_MODE_MAX
}; };
@ -746,6 +747,7 @@ public:
void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality);
void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL); void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
void sort_buffer(RID p_uniform_set, int p_size); void sort_buffer(RID p_uniform_set, int p_size);

View File

@ -1150,6 +1150,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
} }
RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment); RendererSceneEnvironmentRD *env = get_environment(p_render_data->environment);
static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 };
//first of all, make a new render pass //first of all, make a new render pass
//fill up ubo //fill up ubo
@ -1390,10 +1391,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (needs_pre_resolve) { if (needs_pre_resolve) {
RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE); RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE);
} }
static int texture_samples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8, 16 }; storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_samples[render_buffer->msaa]);
} else if (finish_depth) { } else if (finish_depth) {
RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth); storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
} }
RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_command_end_label();
} }
@ -1497,7 +1497,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
} }
if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) { if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth); storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
} }
if (using_separate_specular) { if (using_separate_specular) {

View File

@ -320,8 +320,6 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
} else { } else {
//specular write //specular write
blend_state = blend_state_opaque_specular; blend_state = blend_state_opaque_specular;
depth_stencil.enable_depth_test = false;
depth_stencil.enable_depth_write = false;
} }
} }
@ -631,7 +629,6 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.renames["SSS_STRENGTH"] = "sss_strength"; actions.renames["SSS_STRENGTH"] = "sss_strength";
actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color"; actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth"; actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost"; actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
actions.renames["BACKLIGHT"] = "backlight"; actions.renames["BACKLIGHT"] = "backlight";
actions.renames["AO"] = "ao"; actions.renames["AO"] = "ao";

View File

@ -621,7 +621,6 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
actions.renames["SSS_STRENGTH"] = "sss_strength"; actions.renames["SSS_STRENGTH"] = "sss_strength";
actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color"; actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth"; actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost"; actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
actions.renames["BACKLIGHT"] = "backlight"; actions.renames["BACKLIGHT"] = "backlight";
actions.renames["AO"] = "ao"; actions.renames["AO"] = "ao";

View File

@ -6,6 +6,11 @@
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#ifdef MODE_RESOLVE_DEPTH
layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_depth;
#endif
#ifdef MODE_RESOLVE_GI #ifdef MODE_RESOLVE_GI
layout(set = 0, binding = 0) uniform sampler2DMS source_depth; layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
layout(set = 0, binding = 1) uniform sampler2DMS source_normal_roughness; layout(set = 0, binding = 1) uniform sampler2DMS source_normal_roughness;
@ -34,6 +39,17 @@ void main() {
return; return;
} }
#ifdef MODE_RESOLVE_DEPTH
float depth_avg = 0.0;
for (int i = 0; i < params.sample_count; i++) {
depth_avg += texelFetch(source_depth, pos, i).r;
}
depth_avg /= float(params.sample_count);
imageStore(dest_depth, pos, vec4(depth_avg));
#endif
#ifdef MODE_RESOLVE_GI #ifdef MODE_RESOLVE_GI
float best_depth = 1e20; float best_depth = 1e20;

View File

@ -547,9 +547,8 @@ void main() {
vec3 view = -normalize(vertex_interp); vec3 view = -normalize(vertex_interp);
vec3 albedo = vec3(1.0); vec3 albedo = vec3(1.0);
vec3 backlight = vec3(0.0); vec3 backlight = vec3(0.0);
vec4 transmittance_color = vec4(0.0); vec4 transmittance_color = vec4(0.0, 0.0, 0.0, 1.0);
float transmittance_depth = 0.0; float transmittance_depth = 0.0;
float transmittance_curve = 1.0;
float transmittance_boost = 0.0; float transmittance_boost = 0.0;
float metallic = 0.0; float metallic = 0.0;
float specular = 0.5; float specular = 0.5;
@ -634,12 +633,8 @@ void main() {
} }
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
#ifdef SSS_MODE_SKIN
transmittance_color.a = sss_strength;
#else
transmittance_color.a *= sss_strength; transmittance_color.a *= sss_strength;
#endif #endif
#endif
#ifndef USE_SHADOW_TO_OPACITY #ifndef USE_SHADOW_TO_OPACITY
@ -1423,57 +1418,18 @@ void main() {
BIAS_FUNC(v, 0) BIAS_FUNC(v, 0)
pssm_coord = (directional_lights.data[i].shadow_matrix1 * v); pssm_coord = (directional_lights.data[i].shadow_matrix1 * v);
#ifdef LIGHT_TRANSMITTANCE_USED
{
vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x;
float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x;
transmittance_z = z - shadow_z;
}
#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
vec4 v = vec4(vertex, 1.0); vec4 v = vec4(vertex, 1.0);
BIAS_FUNC(v, 1) BIAS_FUNC(v, 1)
pssm_coord = (directional_lights.data[i].shadow_matrix2 * v); pssm_coord = (directional_lights.data[i].shadow_matrix2 * v);
#ifdef LIGHT_TRANSMITTANCE_USED
{
vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y;
float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y;
transmittance_z = z - shadow_z;
}
#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
vec4 v = vec4(vertex, 1.0); vec4 v = vec4(vertex, 1.0);
BIAS_FUNC(v, 2) BIAS_FUNC(v, 2)
pssm_coord = (directional_lights.data[i].shadow_matrix3 * v); pssm_coord = (directional_lights.data[i].shadow_matrix3 * v);
#ifdef LIGHT_TRANSMITTANCE_USED
{
vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z;
float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z;
transmittance_z = z - shadow_z;
}
#endif
} else { } else {
vec4 v = vec4(vertex, 1.0); vec4 v = vec4(vertex, 1.0);
@ -1481,19 +1437,6 @@ void main() {
BIAS_FUNC(v, 3) BIAS_FUNC(v, 3)
pssm_coord = (directional_lights.data[i].shadow_matrix4 * v); pssm_coord = (directional_lights.data[i].shadow_matrix4 * v);
#ifdef LIGHT_TRANSMITTANCE_USED
{
vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w;
float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w;
transmittance_z = z - shadow_z;
}
#endif
} }
pssm_coord /= pssm_coord.w; pssm_coord /= pssm_coord.w;
@ -1562,8 +1505,8 @@ void main() {
trans_coord /= trans_coord.w; trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.x; shadow_z *= directional_lights.data[i].shadow_z_range.x;
float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.x; float z = trans_coord.z * directional_lights.data[i].shadow_z_range.x;
transmittance_z = z - shadow_z; transmittance_z = z - shadow_z;
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) { } else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
@ -1572,8 +1515,8 @@ void main() {
trans_coord /= trans_coord.w; trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.y; shadow_z *= directional_lights.data[i].shadow_z_range.y;
float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.y; float z = trans_coord.z * directional_lights.data[i].shadow_z_range.y;
transmittance_z = z - shadow_z; transmittance_z = z - shadow_z;
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) { } else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
@ -1582,8 +1525,8 @@ void main() {
trans_coord /= trans_coord.w; trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.z; shadow_z *= directional_lights.data[i].shadow_z_range.z;
float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.z; float z = trans_coord.z * directional_lights.data[i].shadow_z_range.z;
transmittance_z = z - shadow_z; transmittance_z = z - shadow_z;
@ -1593,221 +1536,219 @@ void main() {
trans_coord /= trans_coord.w; trans_coord /= trans_coord.w;
float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r; float shadow_z = textureLod(sampler2D(directional_shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), trans_coord.xy, 0.0).r;
shadow_z *= directional_lights.data[i].shadow_transmittance_z_scale.w; shadow_z *= directional_lights.data[i].shadow_z_range.w;
float z = trans_coord.z * directional_lights.data[i].shadow_transmittance_z_scale.w; float z = trans_coord.z * directional_lights.data[i].shadow_z_range.w;
transmittance_z = z - shadow_z; transmittance_z = z - shadow_z;
} }
}
#endif #endif
float shadow = 1.0; float shadow = 1.0;
if (i < 4) { if (i < 4) {
shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0; shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0;
} else { } else {
shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0; shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0;
}
blur_shadow(shadow);
light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color,
transmittance_depth,
transmittance_boost,
transmittance_z,
#endif
#ifdef LIGHT_RIM_USED
rim, rim_tint, albedo,
#endif
#ifdef LIGHT_CLEARCOAT_USED
clearcoat, clearcoat_gloss,
#endif
#ifdef LIGHT_ANISOTROPY_USED
binormal, tangent, anisotropy,
#endif
#ifdef USE_SOFT_SHADOW
directional_lights.data[i].size,
#endif
#ifdef USE_SHADOW_TO_OPACITY
alpha,
#endif
diffuse_light,
specular_light);
}
}
{ //omni lights
uint cluster_omni_offset = cluster_offset;
uint item_min;
uint item_max;
uint item_from;
uint item_to;
cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS
item_from = subgroupBroadcastFirst(subgroupMin(item_from));
item_to = subgroupBroadcastFirst(subgroupMax(item_to));
#endif
for (uint i = item_from; i < item_to; i++) {
uint mask = cluster_buffer.data[cluster_omni_offset + i];
mask &= cluster_get_range_clip_mask(i, item_min, item_max);
#ifdef USE_SUBGROUPS
uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
#else
uint merged_mask = mask;
#endif
while (merged_mask != 0) {
uint bit = findMSB(merged_mask);
merged_mask &= ~(1 << bit);
#ifdef USE_SUBGROUPS
if (((1 << bit) & mask) == 0) { //do not process if not originally here
continue;
}
#endif
uint light_index = 32 * i + bit;
if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
continue; //not masked
} }
blur_shadow(shadow); if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
continue; // Statically baked light and object uses lightmap, skip
}
light_compute(normal, directional_lights.data[i].direction, normalize(view), directional_lights.data[i].color * directional_lights.data[i].energy, shadow, f0, orms, 1.0, float shadow = light_process_omni_shadow(light_index, vertex, view);
shadow = blur_shadow(shadow);
light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
#ifdef LIGHT_BACKLIGHT_USED #ifdef LIGHT_BACKLIGHT_USED
backlight, backlight,
#endif #endif
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color, transmittance_color,
transmittance_depth, transmittance_depth,
transmittance_curve,
transmittance_boost, transmittance_boost,
transmittance_z,
#endif #endif
#ifdef LIGHT_RIM_USED #ifdef LIGHT_RIM_USED
rim, rim_tint, albedo, rim,
rim_tint,
albedo,
#endif #endif
#ifdef LIGHT_CLEARCOAT_USED #ifdef LIGHT_CLEARCOAT_USED
clearcoat, clearcoat_gloss, clearcoat, clearcoat_gloss,
#endif #endif
#ifdef LIGHT_ANISOTROPY_USED #ifdef LIGHT_ANISOTROPY_USED
binormal, tangent, anisotropy, tangent, binormal, anisotropy,
#endif
#ifdef USE_SOFT_SHADOW
directional_lights.data[i].size,
#endif #endif
#ifdef USE_SHADOW_TO_OPACITY #ifdef USE_SHADOW_TO_OPACITY
alpha, alpha,
#endif #endif
diffuse_light, diffuse_light, specular_light);
specular_light);
} }
} }
}
{ //omni lights { //spot lights
uint cluster_omni_offset = cluster_offset; uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size;
uint item_min; uint item_min;
uint item_max; uint item_max;
uint item_from; uint item_from;
uint item_to; uint item_to;
cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to); cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS #ifdef USE_SUBGROUPS
item_from = subgroupBroadcastFirst(subgroupMin(item_from)); item_from = subgroupBroadcastFirst(subgroupMin(item_from));
item_to = subgroupBroadcastFirst(subgroupMax(item_to)); item_to = subgroupBroadcastFirst(subgroupMax(item_to));
#endif #endif
for (uint i = item_from; i < item_to; i++) { for (uint i = item_from; i < item_to; i++) {
uint mask = cluster_buffer.data[cluster_omni_offset + i]; uint mask = cluster_buffer.data[cluster_spot_offset + i];
mask &= cluster_get_range_clip_mask(i, item_min, item_max); mask &= cluster_get_range_clip_mask(i, item_min, item_max);
#ifdef USE_SUBGROUPS #ifdef USE_SUBGROUPS
uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask)); uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
#else #else
uint merged_mask = mask; uint merged_mask = mask;
#endif #endif
while (merged_mask != 0) { while (merged_mask != 0) {
uint bit = findMSB(merged_mask); uint bit = findMSB(merged_mask);
merged_mask &= ~(1 << bit); merged_mask &= ~(1 << bit);
#ifdef USE_SUBGROUPS #ifdef USE_SUBGROUPS
if (((1 << bit) & mask) == 0) { //do not process if not originally here if (((1 << bit) & mask) == 0) { //do not process if not originally here
continue; continue;
} }
#endif #endif
uint light_index = 32 * i + bit;
if (!bool(omni_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) { uint light_index = 32 * i + bit;
continue; //not masked
}
if (omni_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
continue; // Statically baked light and object uses lightmap, skip continue; //not masked
} }
float shadow = light_process_omni_shadow(light_index, vertex, view); if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
continue; // Statically baked light and object uses lightmap, skip
}
shadow = blur_shadow(shadow); float shadow = light_process_spot_shadow(light_index, vertex, view);
light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, shadow = blur_shadow(shadow);
light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
#ifdef LIGHT_BACKLIGHT_USED #ifdef LIGHT_BACKLIGHT_USED
backlight, backlight,
#endif #endif
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color, transmittance_color,
transmittance_depth, transmittance_depth,
transmittance_curve, transmittance_boost,
transmittance_boost,
#endif #endif
#ifdef LIGHT_RIM_USED #ifdef LIGHT_RIM_USED
rim, rim,
rim_tint, rim_tint,
albedo, albedo,
#endif #endif
#ifdef LIGHT_CLEARCOAT_USED #ifdef LIGHT_CLEARCOAT_USED
clearcoat, clearcoat_gloss, clearcoat, clearcoat_gloss,
#endif #endif
#ifdef LIGHT_ANISOTROPY_USED #ifdef LIGHT_ANISOTROPY_USED
tangent, binormal, anisotropy, tangent, binormal, anisotropy,
#endif #endif
#ifdef USE_SHADOW_TO_OPACITY #ifdef USE_SHADOW_TO_OPACITY
alpha, alpha,
#endif #endif
diffuse_light, specular_light); diffuse_light, specular_light);
}
}
}
{ //spot lights
uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size;
uint item_min;
uint item_max;
uint item_from;
uint item_to;
cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
#ifdef USE_SUBGROUPS
item_from = subgroupBroadcastFirst(subgroupMin(item_from));
item_to = subgroupBroadcastFirst(subgroupMax(item_to));
#endif
for (uint i = item_from; i < item_to; i++) {
uint mask = cluster_buffer.data[cluster_spot_offset + i];
mask &= cluster_get_range_clip_mask(i, item_min, item_max);
#ifdef USE_SUBGROUPS
uint merged_mask = subgroupBroadcastFirst(subgroupOr(mask));
#else
uint merged_mask = mask;
#endif
while (merged_mask != 0) {
uint bit = findMSB(merged_mask);
merged_mask &= ~(1 << bit);
#ifdef USE_SUBGROUPS
if (((1 << bit) & mask) == 0) { //do not process if not originally here
continue;
}
#endif
uint light_index = 32 * i + bit;
if (!bool(spot_lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
continue; //not masked
}
if (spot_lights.data[light_index].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
continue; // Statically baked light and object uses lightmap, skip
}
float shadow = light_process_spot_shadow(light_index, vertex, view);
shadow = blur_shadow(shadow);
light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow,
#ifdef LIGHT_BACKLIGHT_USED
backlight,
#endif
#ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color,
transmittance_depth,
transmittance_curve,
transmittance_boost,
#endif
#ifdef LIGHT_RIM_USED
rim,
rim_tint,
albedo,
#endif
#ifdef LIGHT_CLEARCOAT_USED
clearcoat, clearcoat_gloss,
#endif
#ifdef LIGHT_ANISOTROPY_USED
tangent, binormal, anisotropy,
#endif
#ifdef USE_SHADOW_TO_OPACITY
alpha,
#endif
diffuse_light, specular_light);
}
} }
} }
}
#ifdef USE_SHADOW_TO_OPACITY #ifdef USE_SHADOW_TO_OPACITY
alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
#if defined(ALPHA_SCISSOR_USED) #if defined(ALPHA_SCISSOR_USED)
if (alpha < alpha_scissor) { if (alpha < alpha_scissor) {
discard; discard;
} }
#endif // ALPHA_SCISSOR_USED #endif // ALPHA_SCISSOR_USED
#ifdef USE_OPAQUE_PREPASS #ifdef USE_OPAQUE_PREPASS
if (alpha < opaque_prepass_threshold) { if (alpha < opaque_prepass_threshold) {
discard; discard;
} }
#endif // USE_OPAQUE_PREPASS #endif // USE_OPAQUE_PREPASS
@ -1819,126 +1760,126 @@ void main() {
#ifdef MODE_RENDER_SDF #ifdef MODE_RENDER_SDF
{ {
vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz; vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size)); ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size));
uint albedo16 = 0x1; //solid flag uint albedo16 = 0x1; //solid flag
albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11; albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;
albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6; albedo16 |= clamp(uint(albedo.g * 31.0), 0, 31) << 6;
albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1; albedo16 |= clamp(uint(albedo.b * 31.0), 0, 31) << 1;
imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16)); imageStore(albedo_volume_grid, grid_pos, uvec4(albedo16));
uint facing_bits = 0; uint facing_bits = 0;
const vec3 aniso_dir[6] = vec3[]( const vec3 aniso_dir[6] = vec3[](
vec3(1, 0, 0), vec3(1, 0, 0),
vec3(0, 1, 0), vec3(0, 1, 0),
vec3(0, 0, 1), vec3(0, 0, 1),
vec3(-1, 0, 0), vec3(-1, 0, 0),
vec3(0, -1, 0), vec3(0, -1, 0),
vec3(0, 0, -1)); vec3(0, 0, -1));
vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp); vec3 cam_normal = mat3(scene_data.camera_matrix) * normalize(normal_interp);
float closest_dist = -1e20; float closest_dist = -1e20;
for (uint i = 0; i < 6; i++) { for (uint i = 0; i < 6; i++) {
float d = dot(cam_normal, aniso_dir[i]); float d = dot(cam_normal, aniso_dir[i]);
if (d > closest_dist) { if (d > closest_dist) {
closest_dist = d; closest_dist = d;
facing_bits = (1 << i); facing_bits = (1 << i);
}
}
imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
if (length(emission) > 0.001) {
float lumas[6];
vec3 light_total = vec3(0);
for (int i = 0; i < 6; i++) {
float strength = max(0.0, dot(cam_normal, aniso_dir[i]));
vec3 light = emission * strength;
light_total += light;
lumas[i] = max(light.r, max(light.g, light.b));
}
float luma_total = max(light_total.r, max(light_total.g, light_total.b));
uint light_aniso = 0;
for (int i = 0; i < 6; i++) {
light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5);
}
//compress to RGBE9995 to save space
const float pow2to9 = 512.0f;
const float B = 15.0f;
const float N = 9.0f;
const float LN2 = 0.6931471805599453094172321215;
float cRed = clamp(light_total.r, 0.0, 65408.0);
float cGreen = clamp(light_total.g, 0.0, 65408.0);
float cBlue = clamp(light_total.b, 0.0, 65408.0);
float cMax = max(cRed, max(cGreen, cBlue));
float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B;
float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f);
float exps = expp + 1.0f;
if (0.0 <= sMax && sMax < pow2to9) {
exps = expp;
}
float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
//store as 8985 to have 2 extra neighbour bits
uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
} }
} }
imageAtomicOr(geom_facing_grid, grid_pos, facing_bits); //store facing bits
if (length(emission) > 0.001) {
float lumas[6];
vec3 light_total = vec3(0);
for (int i = 0; i < 6; i++) {
float strength = max(0.0, dot(cam_normal, aniso_dir[i]));
vec3 light = emission * strength;
light_total += light;
lumas[i] = max(light.r, max(light.g, light.b));
}
float luma_total = max(light_total.r, max(light_total.g, light_total.b));
uint light_aniso = 0;
for (int i = 0; i < 6; i++) {
light_aniso |= min(31, uint((lumas[i] / luma_total) * 31.0)) << (i * 5);
}
//compress to RGBE9995 to save space
const float pow2to9 = 512.0f;
const float B = 15.0f;
const float N = 9.0f;
const float LN2 = 0.6931471805599453094172321215;
float cRed = clamp(light_total.r, 0.0, 65408.0);
float cGreen = clamp(light_total.g, 0.0, 65408.0);
float cBlue = clamp(light_total.b, 0.0, 65408.0);
float cMax = max(cRed, max(cGreen, cBlue));
float expp = max(-B - 1.0f, floor(log(cMax) / LN2)) + 1.0f + B;
float sMax = floor((cMax / pow(2.0f, expp - B - N)) + 0.5f);
float exps = expp + 1.0f;
if (0.0 <= sMax && sMax < pow2to9) {
exps = expp;
}
float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
//store as 8985 to have 2 extra neighbour bits
uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25);
imageStore(emission_grid, grid_pos, uvec4(light_rgbe));
imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso));
}
}
#endif #endif
#ifdef MODE_RENDER_MATERIAL #ifdef MODE_RENDER_MATERIAL
albedo_output_buffer.rgb = albedo; albedo_output_buffer.rgb = albedo;
albedo_output_buffer.a = alpha; albedo_output_buffer.a = alpha;
normal_output_buffer.rgb = normal * 0.5 + 0.5; normal_output_buffer.rgb = normal * 0.5 + 0.5;
normal_output_buffer.a = 0.0; normal_output_buffer.a = 0.0;
depth_output_buffer.r = -vertex.z; depth_output_buffer.r = -vertex.z;
orm_output_buffer.r = ao; orm_output_buffer.r = ao;
orm_output_buffer.g = roughness; orm_output_buffer.g = roughness;
orm_output_buffer.b = metallic; orm_output_buffer.b = metallic;
orm_output_buffer.a = sss_strength; orm_output_buffer.a = sss_strength;
emission_output_buffer.rgb = emission; emission_output_buffer.rgb = emission;
emission_output_buffer.a = 0.0; emission_output_buffer.a = 0.0;
#endif #endif
#ifdef MODE_RENDER_NORMAL_ROUGHNESS #ifdef MODE_RENDER_NORMAL_ROUGHNESS
normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness); normal_roughness_output_buffer = vec4(normal * 0.5 + 0.5, roughness);
#ifdef MODE_RENDER_VOXEL_GI #ifdef MODE_RENDER_VOXEL_GI
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances
uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
uint index2 = instances.data[instance_index].gi_offset >> 16; uint index2 = instances.data[instance_index].gi_offset >> 16;
voxel_gi_buffer.x = index1 & 0xFF; voxel_gi_buffer.x = index1 & 0xFF;
voxel_gi_buffer.y = index2 & 0xFF; voxel_gi_buffer.y = index2 & 0xFF;
} else { } else {
voxel_gi_buffer.x = 0xFF; voxel_gi_buffer.x = 0xFF;
voxel_gi_buffer.y = 0xFF; voxel_gi_buffer.y = 0xFF;
} }
#endif #endif
#endif //MODE_RENDER_NORMAL_ROUGHNESS #endif //MODE_RENDER_NORMAL_ROUGHNESS
@ -1996,4 +1937,4 @@ void main() {
#endif //MODE_MULTIPLE_RENDER_TARGETS #endif //MODE_MULTIPLE_RENDER_TARGETS
#endif //MODE_RENDER_DEPTH #endif //MODE_RENDER_DEPTH
} }

View File

@ -80,7 +80,6 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
vec4 transmittance_color, vec4 transmittance_color,
float transmittance_depth, float transmittance_depth,
float transmittance_curve,
float transmittance_boost, float transmittance_boost,
float transmittance_z, float transmittance_z,
#endif #endif
@ -189,9 +188,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
#ifdef SSS_MODE_SKIN
{ {
#ifdef SSS_MODE_SKIN
float scale = 8.25 / transmittance_depth; float scale = 8.25 / transmittance_depth;
float d = scale * abs(transmittance_z); float d = scale * abs(transmittance_z);
float dd = -d * d; float dd = -d * d;
@ -203,19 +201,15 @@ void light_compute(vec3 N, vec3 L, vec3 V, vec3 light_color, float attenuation,
vec3(0.078, 0.0, 0.0) * exp(dd / 7.41); vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
diffuse_light += profile * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI); diffuse_light += profile * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI);
}
#else #else
if (transmittance_depth > 0.0) { float scale = 8.25 / transmittance_depth;
float fade = clamp(abs(transmittance_z / transmittance_depth), 0.0, 1.0); float d = scale * abs(transmittance_z);
float dd = -d * d;
fade = pow(max(0.0, 1.0 - fade), transmittance_curve); diffuse_light += exp(dd) * transmittance_color.rgb * transmittance_color.a * light_color * clamp(transmittance_boost - NdotL, 0.0, 1.0) * (1.0 / M_PI);
fade *= clamp(transmittance_boost - NdotL, 0.0, 1.0); #endif
diffuse_light += transmittance_color.rgb * light_color * (1.0 / M_PI) * transmittance_color.a * fade;
} }
#else
#endif //SSS_MODE_SKIN
#endif //LIGHT_TRANSMITTANCE_USED #endif //LIGHT_TRANSMITTANCE_USED
} }
@ -577,7 +571,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
vec4 transmittance_color, vec4 transmittance_color,
float transmittance_depth, float transmittance_depth,
float transmittance_curve,
float transmittance_boost, float transmittance_boost,
#endif #endif
#ifdef LIGHT_RIM_USED #ifdef LIGHT_RIM_USED
@ -617,20 +610,22 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
//redo shadowmapping, but shrink the model a bit to avoid arctifacts //redo shadowmapping, but shrink the model a bit to avoid arctifacts
vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0)); vec4 splane = (omni_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * omni_lights.data[idx].transmittance_bias, 1.0));
shadow_len = length(splane.xyz); float shadow_len = length(splane.xyz);
splane = normalize(splane.xyz); splane.xyz = normalize(splane.xyz);
if (splane.z >= 0.0) { if (splane.z >= 0.0) {
splane.z += 1.0; splane.z += 1.0;
clamp_rect.y += clamp_rect.w;
} else { } else {
splane.z = 1.0 - splane.z; splane.z = 1.0 - splane.z;
} }
splane.xy /= splane.z; splane.xy /= splane.z;
splane.xy = splane.xy * 0.5 + 0.5; splane.xy = splane.xy * 0.5 + 0.5;
splane.z = shadow_len * omni_lights.data[idx].inv_radius; splane.z = shadow_len * omni_lights.data[idx].inv_radius;
splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw; splane.xy = clamp_rect.xy + splane.xy * clamp_rect.zw;
// splane.xy = clamp(splane.xy,clamp_rect.xy + scene_data.shadow_atlas_pixel_size,clamp_rect.xy + clamp_rect.zw - scene_data.shadow_atlas_pixel_size );
splane.w = 1.0; //needed? i think it should be 1 already splane.w = 1.0; //needed? i think it should be 1 already
float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
@ -704,7 +699,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color, transmittance_color,
transmittance_depth, transmittance_depth,
transmittance_curve,
transmittance_boost, transmittance_boost,
transmittance_z, transmittance_z,
#endif #endif
@ -829,7 +823,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
vec4 transmittance_color, vec4 transmittance_color,
float transmittance_depth, float transmittance_depth,
float transmittance_curve,
float transmittance_boost, float transmittance_boost,
#endif #endif
#ifdef LIGHT_RIM_USED #ifdef LIGHT_RIM_USED
@ -876,13 +869,17 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
float transmittance_z = transmittance_depth; float transmittance_z = transmittance_depth;
transmittance_color.a *= light_attenuation; transmittance_color.a *= light_attenuation;
{ {
splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0)); vec4 splane = (spot_lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * spot_lights.data[idx].transmittance_bias, 1.0));
splane /= splane.w; splane /= splane.w;
splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy; splane.xy = splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy;
float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r; float shadow_z = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), splane.xy, 0.0).r;
//reconstruct depth
shadow_z /= spot_lights.data[idx].inv_radius; shadow_z = shadow_z * 2.0 - 1.0;
float z_far = 1.0 / spot_lights.data[idx].inv_radius;
float z_near = 0.01;
shadow_z = 2.0 * z_near * z_far / (z_far + z_near - shadow_z * (z_far - z_near));
//distance to light plane //distance to light plane
float z = dot(spot_dir, -light_rel_vec); float z = dot(spot_dir, -light_rel_vec);
transmittance_z = z - shadow_z; transmittance_z = z - shadow_z;
@ -898,7 +895,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color, transmittance_color,
transmittance_depth, transmittance_depth,
transmittance_curve,
transmittance_boost, transmittance_boost,
transmittance_z, transmittance_z,
#endif #endif

View File

@ -543,7 +543,6 @@ void main() {
vec3 backlight = vec3(0.0); vec3 backlight = vec3(0.0);
vec4 transmittance_color = vec4(0.0); vec4 transmittance_color = vec4(0.0);
float transmittance_depth = 0.0; float transmittance_depth = 0.0;
float transmittance_curve = 1.0;
float transmittance_boost = 0.0; float transmittance_boost = 0.0;
float metallic = 0.0; float metallic = 0.0;
float specular = 0.5; float specular = 0.5;
@ -1293,7 +1292,6 @@ void main() {
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color, transmittance_color,
transmittance_depth, transmittance_depth,
transmittance_curve,
transmittance_boost, transmittance_boost,
transmittance_z, transmittance_z,
#endif #endif
@ -1344,7 +1342,6 @@ void main() {
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color, transmittance_color,
transmittance_depth, transmittance_depth,
transmittance_curve,
transmittance_boost, transmittance_boost,
#endif #endif
*/ */
@ -1393,7 +1390,6 @@ void main() {
#ifdef LIGHT_TRANSMITTANCE_USED #ifdef LIGHT_TRANSMITTANCE_USED
transmittance_color, transmittance_color,
transmittance_depth, transmittance_depth,
transmittance_curve,
transmittance_boost, transmittance_boost,
#endif #endif
*/ */

View File

@ -122,7 +122,6 @@ ShaderTypes::ShaderTypes() {
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_STRENGTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_COLOR"] = ShaderLanguage::TYPE_VEC4; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_DEPTH"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_DEPTH"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_CURVE"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_BOOST"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["SSS_TRANSMITTANCE_BOOST"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BACKLIGHT"] = ShaderLanguage::TYPE_VEC3; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["BACKLIGHT"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT; shader_modes[RS::SHADER_SPATIAL].functions["fragment"].built_ins["AO"] = ShaderLanguage::TYPE_FLOAT;