summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd/shaders
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2021-11-24 09:14:19 +0200
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2021-11-24 09:16:16 +0200
commit5e0a034524c25e9b06869e323a8a6313223330b8 (patch)
treead9ca6403ab95ffbb5f8b1c76f9dc565a7b0481e /servers/rendering/renderer_rd/shaders
parent5efe80f3085c8c6451363fe4c743bf3d7fc20b6c (diff)
[macOS / iOS] Use storage buffers instead of unsupported images for the volumetric fog on MoltenVK.
Diffstat (limited to 'servers/rendering/renderer_rd/shaders')
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl38
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl35
2 files changed, 73 insertions, 0 deletions
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
index afc5d68776..181d3b272f 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
@@ -47,7 +47,13 @@ layout(push_constant, binding = 0, std430) uniform Params {
}
params;
+#ifdef MOLTENVK_USED
+layout(set = 1, binding = 1) volatile buffer emissive_only_map_buffer {
+ uint emissive_only_map[];
+};
+#else
layout(r32ui, set = 1, binding = 1) uniform volatile uimage3D emissive_only_map;
+#endif
layout(set = 1, binding = 2, std140) uniform SceneParams {
vec2 fog_frustum_size_begin;
@@ -71,8 +77,17 @@ layout(set = 1, binding = 2, std140) uniform SceneParams {
}
scene_params;
+#ifdef MOLTENVK_USED
+layout(set = 1, binding = 3) volatile buffer density_only_map_buffer {
+ uint density_only_map[];
+};
+layout(set = 1, binding = 4) volatile buffer light_only_map_buffer {
+ uint light_only_map[];
+};
+#else
layout(r32ui, set = 1, binding = 3) uniform volatile uimage3D density_only_map;
layout(r32ui, set = 1, binding = 4) uniform volatile uimage3D light_only_map;
+#endif
#ifdef MATERIAL_UNIFORMS_USED
layout(set = 2, binding = 0, std140) uniform MaterialUniforms{
@@ -115,6 +130,9 @@ void main() {
if (any(greaterThanEqual(pos, scene_params.fog_volume_size))) {
return; //do not compute
}
+#ifdef MOLTENVK_USED
+ uint lpos = pos.z * scene_params.fog_volume_size.x * scene_params.fog_volume_size.y + pos.y * scene_params.fog_volume_size.x + pos.x;
+#endif
vec3 posf = vec3(pos);
@@ -197,7 +215,11 @@ void main() {
density *= cull_mask;
if (abs(density) > 0.001) {
int final_density = int(density * DENSITY_SCALE);
+#ifdef MOLTENVK_USED
+ atomicAdd(density_only_map[lpos], uint(final_density));
+#else
imageAtomicAdd(density_only_map, pos, uint(final_density));
+#endif
#ifdef EMISSION_USED
{
@@ -207,7 +229,11 @@ void main() {
uvec3 emission_u = uvec3(emission.r * 511.0, emission.g * 511.0, emission.b * 255.0);
// R and G have 11 bits each and B has 10. Then pack them into a 32 bit uint
uint final_emission = emission_u.r << 21 | emission_u.g << 10 | emission_u.b;
+#ifdef MOLTENVK_USED
+ uint prev_emission = atomicAdd(emissive_only_map[lpos], final_emission);
+#else
uint prev_emission = imageAtomicAdd(emissive_only_map, pos, final_emission);
+#endif
// Adding can lead to colors overflowing, so validate
uvec3 prev_emission_u = uvec3(prev_emission >> 21, (prev_emission << 11) >> 21, prev_emission % 1024);
@@ -219,7 +245,11 @@ void main() {
if (any(overflowing)) {
uvec3 overflow_factor = mix(uvec3(0), uvec3(2047 << 21, 2047 << 10, 1023), overflowing);
uint force_max = overflow_factor.r | overflow_factor.g | overflow_factor.b;
+#ifdef MOLTENVK_USED
+ atomicOr(emissive_only_map[lpos], force_max);
+#else
imageAtomicOr(emissive_only_map, pos, force_max);
+#endif
}
}
#endif
@@ -230,7 +260,11 @@ void main() {
uvec3 scattering_u = uvec3(scattering.r * 2047.0, scattering.g * 2047.0, scattering.b * 1023.0);
// R and G have 11 bits each and B has 10. Then pack them into a 32 bit uint
uint final_scattering = scattering_u.r << 21 | scattering_u.g << 10 | scattering_u.b;
+#ifdef MOLTENVK_USED
+ uint prev_scattering = atomicAdd(light_only_map[lpos], final_scattering);
+#else
uint prev_scattering = imageAtomicAdd(light_only_map, pos, final_scattering);
+#endif
// Adding can lead to colors overflowing, so validate
uvec3 prev_scattering_u = uvec3(prev_scattering >> 21, (prev_scattering << 11) >> 21, prev_scattering % 1024);
@@ -242,7 +276,11 @@ void main() {
if (any(overflowing)) {
uvec3 overflow_factor = mix(uvec3(0), uvec3(2047 << 21, 2047 << 10, 1023), overflowing);
uint force_max = overflow_factor.r | overflow_factor.g | overflow_factor.b;
+#ifdef MOLTENVK_USED
+ atomicOr(light_only_map[lpos], force_max);
+#else
imageAtomicOr(light_only_map, pos, force_max);
+#endif
}
}
#endif // ALBEDO_USED
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
index 3d6fbb5653..747f88960c 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
@@ -190,9 +190,22 @@ params;
#ifndef MODE_COPY
layout(set = 0, binding = 15) uniform texture3D prev_density_texture;
+#ifdef MOLTENVK_USED
+layout(set = 0, binding = 16) buffer density_only_map_buffer {
+ uint density_only_map[];
+};
+layout(set = 0, binding = 17) buffer light_only_map_buffer {
+ uint light_only_map[];
+};
+layout(set = 0, binding = 18) buffer emissive_only_map_buffer {
+ uint emissive_only_map[];
+};
+#else
layout(r32ui, set = 0, binding = 16) uniform uimage3D density_only_map;
layout(r32ui, set = 0, binding = 17) uniform uimage3D light_only_map;
layout(r32ui, set = 0, binding = 18) uniform uimage3D emissive_only_map;
+#endif
+
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
layout(set = 0, binding = 19) uniform textureCubeArray sky_texture;
#else
@@ -272,6 +285,9 @@ void main() {
if (any(greaterThanEqual(pos, params.fog_volume_size))) {
return; //do not compute
}
+#ifdef MOLTENVK_USED
+ uint lpos = pos.z * params.fog_volume_size.x * params.fog_volume_size.y + pos.y * params.fog_volume_size.x + pos.x;
+#endif
vec3 posf = vec3(pos);
@@ -335,15 +351,28 @@ void main() {
vec3 total_light = vec3(0.0);
float total_density = params.base_density;
+#ifdef MOLTENVK_USED
+ uint local_density = density_only_map[lpos];
+#else
uint local_density = imageLoad(density_only_map, pos).x;
+#endif
+
total_density += float(int(local_density)) / DENSITY_SCALE;
total_density = max(0.0, total_density);
+#ifdef MOLTENVK_USED
+ uint scattering_u = light_only_map[lpos];
+#else
uint scattering_u = imageLoad(light_only_map, pos).x;
+#endif
vec3 scattering = vec3(scattering_u >> 21, (scattering_u << 11) >> 21, scattering_u % 1024) / vec3(2047.0, 2047.0, 1023.0);
scattering += params.base_scattering * params.base_density;
+#ifdef MOLTENVK_USED
+ uint emission_u = emissive_only_map[lpos];
+#else
uint emission_u = imageLoad(emissive_only_map, pos).x;
+#endif
vec3 emission = vec3(emission_u >> 21, (emission_u << 11) >> 21, emission_u % 1024) / vec3(511.0, 511.0, 255.0);
emission += params.base_emission * params.base_density;
@@ -673,10 +702,16 @@ void main() {
final_density = mix(final_density, reprojected_density, reproject_amount);
imageStore(density_map, pos, final_density);
+#ifdef MOLTENVK_USED
+ density_only_map[lpos] = 0;
+ light_only_map[lpos] = 0;
+ emissive_only_map[lpos] = 0;
+#else
imageStore(density_only_map, pos, uvec4(0));
imageStore(light_only_map, pos, uvec4(0));
imageStore(emissive_only_map, pos, uvec4(0));
#endif
+#endif
#ifdef MODE_FOG