Add a supersampling option to LightmapGI
This provides increased lightmap quality with less noise, smoother shadows and better small-scale shadow detail. The downside is that this significantly increases bake times and memory usage while baking lightmaps, so this option is disabled by default. Co-authored-by: Hugo Locurcio <hugo.locurcio@hugo.pro> Co-authored-by: landervr <31851431+CpnWaffle@users.noreply.github.com>
This commit is contained in:
@ -820,7 +820,7 @@ void main() {
|
||||
// Empty texel, try again.
|
||||
neighbor_position.xyz = texelFetch(sampler2DArray(source_position, linear_sampler), ivec3(atlas_pos + ivec2(-1, 0), params.atlas_slice), 0).xyz;
|
||||
}
|
||||
float texel_size_world_space = distance(position, neighbor_position.xyz);
|
||||
float texel_size_world_space = distance(position, neighbor_position.xyz) * bake_params.supersampling_factor;
|
||||
|
||||
vec3 light_for_texture = vec3(0.0);
|
||||
vec3 light_for_bounces = vec3(0.0);
|
||||
@ -1059,43 +1059,35 @@ void main() {
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MODE_DILATE)
|
||||
#ifdef MODE_DILATE
|
||||
|
||||
vec4 c = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0);
|
||||
//sides first, as they are closer
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, 0), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(0, 1), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, 0), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(0, -1), params.atlas_slice), 0);
|
||||
//endpoints second
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, -1), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, 1), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, -1), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, 1), params.atlas_slice), 0);
|
||||
const int max_radius = int(4.0 * bake_params.supersampling_factor);
|
||||
const ivec2 directions[8] = ivec2[8](ivec2(-1, 0), ivec2(0, 1), ivec2(1, 0), ivec2(0, -1), ivec2(-1, -1), ivec2(-1, 1), ivec2(1, -1), ivec2(1, 1));
|
||||
|
||||
//far sides third
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, 0), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(0, 2), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, 0), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(0, -2), params.atlas_slice), 0);
|
||||
vec4 texel_color = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0);
|
||||
|
||||
//far-mid endpoints
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, -1), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, 1), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, -1), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, 1), params.atlas_slice), 0);
|
||||
for (int radius = 1; radius <= max_radius; radius++) {
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
const ivec2 sample_pos = atlas_pos + directions[i] * radius;
|
||||
// Texture bounds check for robustness.
|
||||
if (any(lessThan(sample_pos, ivec2(0))) ||
|
||||
any(greaterThanEqual(sample_pos, textureSize(source_light, 0).xy))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, -2), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, 2), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, -2), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, 2), params.atlas_slice), 0);
|
||||
//far endpoints
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, -2), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, 2), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, -2), params.atlas_slice), 0);
|
||||
c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, 2), params.atlas_slice), 0);
|
||||
vec4 neighbor_color = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(sample_pos, params.atlas_slice), 0);
|
||||
if (neighbor_color.a > 0.5) {
|
||||
texel_color = neighbor_color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice), c);
|
||||
if (texel_color.a > 0.5) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice), texel_color);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user