Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Screen-space reflections won't show on skinned meshes unless FSR 2.2 is enabled #95388

Closed
Micharneau opened this issue Aug 11, 2024 · 7 comments · Fixed by #95438
Closed

Screen-space reflections won't show on skinned meshes unless FSR 2.2 is enabled #95388

Micharneau opened this issue Aug 11, 2024 · 7 comments · Fixed by #95438

Comments

@Micharneau
Copy link

Tested versions

  • Reproducible in: v4.3.rc3.mono.official [03afb92]
  • Not reproducible in: v4.2.stable.mono.official [46dc277]

System information

Godot v4.3.rc3.mono - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 970M (NVIDIA; 32.0.15.5599) - Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz (8 Threads)

Issue description

As the title implies, screen-space relfections will show on skinned meshes only if FSR 2 is enabled.

Skinned meshes will still cast reflections to other objects without FSR 2, only reflections on the skinned mesh itself are broken.

Other antialiasing methods, like TAA, FXAA or FSR 1, won't affect the issue whatsoever.

Steps to reproduce

  1. Import a skinned mesh into the project.
  2. Add a reflective material to it (Roughness < 0.5, ideally with metallic > 0 to show the reflections better)
  3. Enable Screen-space reflections (SSR) in the Environment settings.
  4. Enable and disable FSR 2.2 in the projects settings, and notice the change happening in reflections.

Minimal reproduction project (MRP)

ssr_skinning_MRP.zip

@Calinou
Copy link
Member

Calinou commented Aug 11, 2024

Other antialiasing methods, like TAA, FXAA or FSR 1, won't affect the issue whatsoever.

FSR 1.0 is not an antialiasing method; it only performs upscaling. It should be combined with another antialiasing method for best results (typically TAA).

@Micharneau
Copy link
Author

Micharneau commented Aug 11, 2024

FSR 1.0 is not an antialiasing method; it only performs upscaling. It should be combined with another antialiasing method for best results (typically TAA).

Whoops, my bad. The point I was trying to make is that only FSR 2 makes SSR appear on skinned meshes, and not FSR 1 nor TAA nor anything else. I guess I wrote "antialiasing method" because this was the first term I came up with.

Thanks for the correction!

@Calinou Calinou added this to the 4.3 milestone Aug 11, 2024
@akien-mga
Copy link
Member

I can confirm the issue with the MRP, and the regression seems to have been introduced in 4.3.dev2.

If someone wants to bisect the regression, that would be between 4.3.dev1 (9d1cbab) and 4.3.dev2 (3524346).

@akien-mga akien-mga moved this from Unassessed to Bad in 4.x Release Blockers Aug 12, 2024
@Calinou
Copy link
Member

Calinou commented Aug 12, 2024

I can confirm this on 4.3.rc 33fe10c (Linux, GeForce RTX 4090 with NVIDIA 555.58.02). I bisected the regression to 43cf21c. cc @clayjohn

This error is printed when SSR fails to render:

ERROR: Error compiling Compute  shader, variant #8 (
#define MODE_STORE
).
   at: _compile_variant (./servers/rendering/renderer_rd/shader_rd.cpp:293)
ERROR: Failed parse:
ERROR: 0:1041: '::' : not supported 
ERROR: 0:1041: '' : missing #endif 
ERROR: 0:1041: 'Math' : undeclared identifier 
ERROR: 0:1041: '=' :  cannot convert from ' temp float' to ' temp highp uint'
ERROR: 0:1041: '' : compilation terminated 
ERROR: 5 compilation errors.  No code generated.



   at: _compile_variant (./servers/rendering/renderer_rd/shader_rd.cpp:294)
ERROR: code:
   1 | 
   2 | #version 450
   3 | 
   4 | 
   5 | 
   6 | #define OCCLUSION_SIZE 8
   7 | 
   8 | #define MODE_STORE
   9 | 
  10 | #define RENDER_DRIVER_VULKAN
  11 | 
  12 | #ifdef MODE_JUMPFLOOD_OPTIMIZED
  13 | #define GROUP_SIZE 8
  14 | 
  15 | layout(local_size_x = GROUP_SIZE, local_size_y = GROUP_SIZE, local_size_z = GROUP_SIZE) in;
  16 | 
  17 | #elif defined(MODE_OCCLUSION) || defined(MODE_SCROLL)
  18 | 
  19 | layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
  20 | 
  21 | #else
  22 | 
  23 | layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
  24 | 
  25 | #endif
  26 | 
  27 | #if defined(MODE_INITIALIZE_JUMP_FLOOD) || defined(MODE_INITIALIZE_JUMP_FLOOD_HALF)
  28 | layout(r16ui, set = 0, binding = 1) uniform restrict readonly uimage3D src_color;
  29 | layout(rgba8ui, set = 0, binding = 2) uniform restrict writeonly uimage3D dst_positions;
  30 | #endif
  31 | 
  32 | #ifdef MODE_UPSCALE_JUMP_FLOOD
  33 | layout(r16ui, set = 0, binding = 1) uniform restrict readonly uimage3D src_color;
  34 | layout(rgba8ui, set = 0, binding = 2) uniform restrict readonly uimage3D src_positions_half;
  35 | layout(rgba8ui, set = 0, binding = 3) uniform restrict writeonly uimage3D dst_positions;
  36 | #endif
  37 | 
  38 | #if defined(MODE_JUMPFLOOD) || defined(MODE_JUMPFLOOD_OPTIMIZED)
  39 | layout(rgba8ui, set = 0, binding = 1) uniform restrict readonly uimage3D src_positions;
  40 | layout(rgba8ui, set = 0, binding = 2) uniform restrict writeonly uimage3D dst_positions;
  41 | #endif
  42 | 
  43 | #ifdef MODE_JUMPFLOOD_OPTIMIZED
  44 | 
  45 | shared uvec4 group_positions[(GROUP_SIZE + 2) * (GROUP_SIZE + 2) * (GROUP_SIZE + 2)]; 
  46 | 
  47 | void group_store(ivec3 p_pos, uvec4 p_value) {
  48 | 	uint offset = uint(p_pos.z * (GROUP_SIZE + 2) * (GROUP_SIZE + 2) + p_pos.y * (GROUP_SIZE + 2) + p_pos.x);
  49 | 	group_positions[offset] = p_value;
  50 | }
  51 | 
  52 | uvec4 group_load(ivec3 p_pos) {
  53 | 	uint offset = uint(p_pos.z * (GROUP_SIZE + 2) * (GROUP_SIZE + 2) + p_pos.y * (GROUP_SIZE + 2) + p_pos.x);
  54 | 	return group_positions[offset];
  55 | }
  56 | 
  57 | #endif
  58 | 
  59 | #ifdef MODE_OCCLUSION
  60 | 
  61 | layout(r16ui, set = 0, binding = 1) uniform restrict readonly uimage3D src_color;
  62 | layout(r8, set = 0, binding = 2) uniform restrict image3D dst_occlusion[8];
  63 | layout(r32ui, set = 0, binding = 3) uniform restrict readonly uimage3D src_facing;
  64 | 
  65 | const uvec2 group_size_offset[11] = uvec2[](uvec2(1, 0), uvec2(3, 1), uvec2(6, 4), uvec2(10, 10), uvec2(15, 20), uvec2(21, 35), uvec2(28, 56), uvec2(36, 84), uvec2(42, 120), uvec2(46, 162), uvec2(48, 208));
  66 | const uint group_pos[256] = uint[](0,
  67 | 		65536, 256, 1,
  68 | 		131072, 65792, 512, 65537, 257, 2,
  69 | 		196608, 131328, 66048, 768, 131073, 65793, 513, 65538, 258, 3,
  70 | 		262144, 196864, 131584, 66304, 1024, 196609, 131329, 66049, 769, 131074, 65794, 514, 65539, 259, 4,
  71 | 		327680, 262400, 197120, 131840, 66560, 1280, 262145, 196865, 131585, 66305, 1025, 196610, 131330, 66050, 770, 131075, 65795, 515, 65540, 260, 5,
  72 | 		393216, 327936, 262656, 197376, 132096, 66816, 1536, 327681, 262401, 197121, 131841, 66561, 1281, 262146, 196866, 131586, 66306, 1026, 196611, 131331, 66051, 771, 131076, 65796, 516, 65541, 261, 6,
  73 | 		458752, 393472, 328192, 262912, 197632, 132352, 67072, 1792, 393217, 327937, 262657, 197377, 132097, 66817, 1537, 327682, 262402, 197122, 131842, 66562, 1282, 262147, 196867, 131587, 66307, 1027, 196612, 131332, 66052, 772, 131077, 65797, 517, 65542, 262, 7,
  74 | 		459008, 393728, 328448, 263168, 197888, 132608, 67328, 458753, 393473, 328193, 262913, 197633, 132353, 67073, 1793, 393218, 327938, 262658, 197378, 132098, 66818, 1538, 327683, 262403, 197123, 131843, 66563, 1283, 262148, 196868, 131588, 66308, 1028, 196613, 131333, 66053, 773, 131078, 65798, 518, 65543, 263,
  75 | 		459264, 393984, 328704, 263424, 198144, 132864, 459009, 393729, 328449, 263169, 197889, 132609, 67329, 458754, 393474, 328194, 262914, 197634, 132354, 67074, 1794, 393219, 327939, 262659, 197379, 132099, 66819, 1539, 327684, 262404, 197124, 131844, 66564, 1284, 262149, 196869, 131589, 66309, 1029, 196614, 131334, 66054, 774, 131079, 65799, 519,
  76 | 		459520, 394240, 328960, 263680, 198400, 459265, 393985, 328705, 263425, 198145, 132865, 459010, 393730, 328450, 263170, 197890, 132610, 67330, 458755, 393475, 328195, 262915, 197635, 132355, 67075, 1795, 393220, 327940, 262660, 197380, 132100, 66820, 1540, 327685, 262405, 197125, 131845, 66565, 1285, 262150, 196870, 131590, 66310, 1030, 196615, 131335, 66055, 775);
  77 | 
  78 | shared uint occlusion_facing[((OCCLUSION_SIZE * 2) * (OCCLUSION_SIZE * 2) * (OCCLUSION_SIZE * 2)) / 4];
  79 | 
  80 | uint get_facing(ivec3 p_pos) {
  81 | 	uint ofs = uint(p_pos.z * OCCLUSION_SIZE * 2 * OCCLUSION_SIZE * 2 + p_pos.y * OCCLUSION_SIZE * 2 + p_pos.x);
  82 | 	uint v = occlusion_facing[ofs / 4];
  83 | 	return (v >> ((ofs % 4) * 8)) & 0xFF;
  84 | }
  85 | 
  86 | #endif
  87 | 
  88 | #ifdef MODE_STORE
  89 | 
  90 | layout(rgba8ui, set = 0, binding = 1) uniform restrict readonly uimage3D src_positions;
  91 | layout(r16ui, set = 0, binding = 2) uniform restrict readonly uimage3D src_albedo;
  92 | layout(r8, set = 0, binding = 3) uniform restrict readonly image3D src_occlusion[8];
  93 | layout(r32ui, set = 0, binding = 4) uniform restrict readonly uimage3D src_light;
  94 | layout(r32ui, set = 0, binding = 5) uniform restrict readonly uimage3D src_light_aniso;
  95 | layout(r32ui, set = 0, binding = 6) uniform restrict readonly uimage3D src_facing;
  96 | 
  97 | layout(r8, set = 0, binding = 7) uniform restrict writeonly image3D dst_sdf;
  98 | layout(r16ui, set = 0, binding = 8) uniform restrict writeonly uimage3D dst_occlusion;
  99 | 
 100 | layout(set = 0, binding = 10, std430) restrict buffer DispatchData {
 101 | 	uint x;
 102 | 	uint y;
 103 | 	uint z;
 104 | 	uint total_count;
 105 | }
 106 | dispatch_data;
 107 | 
 108 | struct ProcessVoxel {
 109 | 	uint position; 
 110 | 	uint albedo; 
 111 | 	uint light; 
 112 | 	uint light_aniso; 
 113 | 	
 114 | };
 115 | 
 116 | layout(set = 0, binding = 11, std430) restrict buffer writeonly ProcessVoxels {
 117 | 	ProcessVoxel data[];
 118 | }
 119 | dst_process_voxels;
 120 | 
 121 | shared ProcessVoxel store_positions[4 * 4 * 4];
 122 | shared uint store_position_count;
 123 | shared uint store_from_index;
 124 | #endif
 125 | 
 126 | #ifdef MODE_SCROLL
 127 | 
 128 | layout(r16ui, set = 0, binding = 1) uniform restrict writeonly uimage3D dst_albedo;
 129 | layout(r32ui, set = 0, binding = 2) uniform restrict writeonly uimage3D dst_facing;
 130 | layout(r32ui, set = 0, binding = 3) uniform restrict writeonly uimage3D dst_light;
 131 | layout(r32ui, set = 0, binding = 4) uniform restrict writeonly uimage3D dst_light_aniso;
 132 | 
 133 | layout(set = 0, binding = 5, std430) restrict buffer readonly DispatchData {
 134 | 	uint x;
 135 | 	uint y;
 136 | 	uint z;
 137 | 	uint total_count;
 138 | }
 139 | dispatch_data;
 140 | 
 141 | struct ProcessVoxel {
 142 | 	uint position; 
 143 | 	uint albedo; 
 144 | 	uint light; 
 145 | 	uint light_aniso; 
 146 | 	
 147 | };
 148 | 
 149 | layout(set = 0, binding = 6, std430) restrict buffer readonly ProcessVoxels {
 150 | 	ProcessVoxel data[];
 151 | }
 152 | src_process_voxels;
 153 | 
 154 | #endif
 155 | 
 156 | #ifdef MODE_SCROLL_OCCLUSION
 157 | 
 158 | layout(r8, set = 0, binding = 1) uniform restrict image3D dst_occlusion[8];
 159 | layout(r16ui, set = 0, binding = 2) uniform restrict readonly uimage3D src_occlusion;
 160 | 
 161 | #endif
 162 | 
 163 | layout(push_constant, std430) uniform Params {
 164 | 	ivec3 scroll;
 165 | 
 166 | 	int grid_size;
 167 | 
 168 | 	ivec3 probe_offset;
 169 | 	int step_size;
 170 | 
 171 | 	bool half_size;
 172 | 	uint occlusion_index;
 173 | 	int cascade;
 174 | 	uint pad;
 175 | }
 176 | params;
 177 | 
 178 | void main() {
 179 | #ifdef MODE_SCROLL
 180 | 
 181 | 	
 182 | 	int index = int(gl_GlobalInvocationID.x);
 183 | 	if (index >= dispatch_data.total_count) { 
 184 | 		return;
 185 | 	}
 186 | 
 187 | 	ivec3 read_pos = (ivec3(src_process_voxels.data[index].position) >> ivec3(0, 7, 14)) & ivec3(0x7F);
 188 | 	ivec3 write_pos = read_pos + params.scroll;
 189 | 
 190 | 	if (any(lessThan(write_pos, ivec3(0))) || any(greaterThanEqual(write_pos, ivec3(params.grid_size)))) {
 191 | 		return; 
 192 | 	}
 193 | 
 194 | 	uint albedo = ((src_process_voxels.data[index].albedo & 0x7FFF) << 1) | 1; 
 195 | 	imageStore(dst_albedo, write_pos, uvec4(albedo));
 196 | 
 197 | 	uint facing = (src_process_voxels.data[index].albedo >> 15) & 0x3F; 
 198 | 	imageStore(dst_facing, write_pos, uvec4(facing));
 199 | 
 200 | 	uint light = src_process_voxels.data[index].light & 0x3fffffff; 
 201 | 	imageStore(dst_light, write_pos, uvec4(light));
 202 | 
 203 | 	uint light_aniso = src_process_voxels.data[index].light_aniso & 0x3fffffff; 
 204 | 	imageStore(dst_light_aniso, write_pos, uvec4(light_aniso));
 205 | 
 206 | #endif
 207 | 
 208 | #ifdef MODE_SCROLL_OCCLUSION
 209 | 
 210 | 	ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);
 211 | 	if (any(greaterThanEqual(pos, ivec3(params.grid_size) - abs(params.scroll)))) { 
 212 | 		return;
 213 | 	}
 214 | 
 215 | 	ivec3 read_pos = pos + max(ivec3(0), -params.scroll);
 216 | 	ivec3 write_pos = pos + max(ivec3(0), params.scroll);
 217 | 
 218 | 	read_pos.z += params.cascade * params.grid_size;
 219 | 	uint occlusion = imageLoad(src_occlusion, read_pos).r;
 220 | 	read_pos.x += params.grid_size;
 221 | 	occlusion |= imageLoad(src_occlusion, read_pos).r << 16;
 222 | 
 223 | 	const uint occlusion_shift[8] = uint[](12, 8, 4, 0, 28, 24, 20, 16);
 224 | 
 225 | 	for (uint i = 0; i < 8; i++) {
 226 | 		float o = float((occlusion >> occlusion_shift[i]) & 0xF) / 15.0;
 227 | 		imageStore(dst_occlusion[i], write_pos, vec4(o));
 228 | 	}
 229 | 
 230 | #endif
 231 | 
 232 | #ifdef MODE_INITIALIZE_JUMP_FLOOD
 233 | 
 234 | 	ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);
 235 | 
 236 | 	uint c = imageLoad(src_color, pos).r;
 237 | 	uvec4 v;
 238 | 	if (bool(c & 0x1)) {
 239 | 		
 240 | 		v.xyz = uvec3(pos);
 241 | 		v.w = 255; 
 242 | 	} else {
 243 | 		v.xyz = uvec3(0);
 244 | 		v.w = 0; 
 245 | 	}
 246 | 
 247 | 	imageStore(dst_positions, pos, v);
 248 | #endif
 249 | 
 250 | #ifdef MODE_INITIALIZE_JUMP_FLOOD_HALF
 251 | 
 252 | 	ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);
 253 | 	ivec3 base_pos = pos * 2;
 254 | 
 255 | 	
 256 | 	
 257 | 	uvec4 closest[8];
 258 | 	int closest_count = 0;
 259 | 
 260 | 	for (uint i = 0; i < 8; i++) {
 261 | 		ivec3 src_pos = base_pos + ((ivec3(i) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1));
 262 | 		uint c = imageLoad(src_color, src_pos).r;
 263 | 		if (bool(c & 1)) {
 264 | 			uvec4 v = uvec4(uvec3(src_pos), 255);
 265 | 			closest[closest_count] = v;
 266 | 			closest_count++;
 267 | 		}
 268 | 	}
 269 | 
 270 | 	if (closest_count == 0) {
 271 | 		imageStore(dst_positions, pos, uvec4(0));
 272 | 	} else {
 273 | 		ivec3 indexv = (pos & ivec3(1, 1, 1)) * ivec3(1, 2, 4);
 274 | 		int index = (indexv.x | indexv.y | indexv.z) % closest_count;
 275 | 		imageStore(dst_positions, pos, closest[index]);
 276 | 	}
 277 | 
 278 | #endif
 279 | 
 280 | #ifdef MODE_JUMPFLOOD
 281 | 
 282 | 	
 283 | 	ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);
 284 | 
 285 | 	vec3 posf = vec3(pos);
 286 | 
 287 | 	if (params.half_size) {
 288 | 		posf = posf * 2.0 + 0.5;
 289 | 	}
 290 | 
 291 | 	uvec4 p = imageLoad(src_positions, pos);
 292 | 
 293 | 	if (!params.half_size && p == uvec4(uvec3(pos), 255)) {
 294 | 		imageStore(dst_positions, pos, p);
 295 | 		return; 
 296 | 	}
 297 | 
 298 | 	float p_dist;
 299 | 
 300 | 	if (p.w != 0) {
 301 | 		p_dist = distance(posf, vec3(p.xyz));
 302 | 	} else {
 303 | 		p_dist = 0.0; 
 304 | 	}
 305 | 
 306 | 	const uint offset_count = 26;
 307 | 	const ivec3 offsets[offset_count] = ivec3[](
 308 | 			ivec3(-1, -1, -1),
 309 | 			ivec3(-1, -1, 0),
 310 | 			ivec3(-1, -1, 1),
 311 | 			ivec3(-1, 0, -1),
 312 | 			ivec3(-1, 0, 0),
 313 | 			ivec3(-1, 0, 1),
 314 | 			ivec3(-1, 1, -1),
 315 | 			ivec3(-1, 1, 0),
 316 | 			ivec3(-1, 1, 1),
 317 | 			ivec3(0, -1, -1),
 318 | 			ivec3(0, -1, 0),
 319 | 			ivec3(0, -1, 1),
 320 | 			ivec3(0, 0, -1),
 321 | 			ivec3(0, 0, 1),
 322 | 			ivec3(0, 1, -1),
 323 | 			ivec3(0, 1, 0),
 324 | 			ivec3(0, 1, 1),
 325 | 			ivec3(1, -1, -1),
 326 | 			ivec3(1, -1, 0),
 327 | 			ivec3(1, -1, 1),
 328 | 			ivec3(1, 0, -1),
 329 | 			ivec3(1, 0, 0),
 330 | 			ivec3(1, 0, 1),
 331 | 			ivec3(1, 1, -1),
 332 | 			ivec3(1, 1, 0),
 333 | 			ivec3(1, 1, 1));
 334 | 
 335 | 	for (uint i = 0; i < offset_count; i++) {
 336 | 		ivec3 ofs = pos + offsets[i] * params.step_size;
 337 | 		if (any(lessThan(ofs, ivec3(0))) || any(greaterThanEqual(ofs, ivec3(params.grid_size)))) {
 338 | 			continue;
 339 | 		}
 340 | 		uvec4 q = imageLoad(src_positions, ofs);
 341 | 
 342 | 		if (q.w == 0) {
 343 | 			continue; 
 344 | 		}
 345 | 
 346 | 		float q_dist = distance(posf, vec3(q.xyz));
 347 | 		if (p.w == 0 || q_dist < p_dist) {
 348 | 			p = q; 
 349 | 			p_dist = q_dist;
 350 | 		}
 351 | 	}
 352 | 
 353 | 	imageStore(dst_positions, pos, p);
 354 | #endif
 355 | 
 356 | #ifdef MODE_JUMPFLOOD_OPTIMIZED
 357 | 	
 358 | 
 359 | 	ivec3 group_offset = ivec3(gl_WorkGroupID.xyz) % params.step_size;
 360 | 	ivec3 group_pos = group_offset + (ivec3(gl_WorkGroupID.xyz) / params.step_size) * ivec3(GROUP_SIZE * params.step_size);
 361 | 
 362 | 	
 363 | 
 364 | 	if (all(lessThan(ivec3(gl_LocalInvocationID.xyz), ivec3((GROUP_SIZE + 2) / 2)))) {
 365 | 		
 366 | 		ivec3 base_pos = ivec3(gl_LocalInvocationID.xyz) * 2;
 367 | 		for (uint i = 0; i < 8; i++) {
 368 | 			ivec3 load_pos = base_pos + ((ivec3(i) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1));
 369 | 			ivec3 load_global_pos = group_pos + (load_pos - ivec3(1)) * params.step_size;
 370 | 			uvec4 q;
 371 | 			if (all(greaterThanEqual(load_global_pos, ivec3(0))) && all(lessThan(load_global_pos, ivec3(params.grid_size)))) {
 372 | 				q = imageLoad(src_positions, load_global_pos);
 373 | 			} else {
 374 | 				q = uvec4(0); 
 375 | 			}
 376 | 
 377 | 			group_store(load_pos, q);
 378 | 		}
 379 | 	}
 380 | 
 381 | 	ivec3 global_pos = group_pos + ivec3(gl_LocalInvocationID.xyz) * params.step_size;
 382 | 
 383 | 	if (any(lessThan(global_pos, ivec3(0))) || any(greaterThanEqual(global_pos, ivec3(params.grid_size)))) {
 384 | 		return; 
 385 | 	}
 386 | 
 387 | 	
 388 | 	groupMemoryBarrier();
 389 | 	barrier();
 390 | 
 391 | 	ivec3 local_pos = ivec3(gl_LocalInvocationID.xyz) + ivec3(1);
 392 | 
 393 | 	const uint offset_count = 27;
 394 | 	const ivec3 offsets[offset_count] = ivec3[](
 395 | 			ivec3(-1, -1, -1),
 396 | 			ivec3(-1, -1, 0),
 397 | 			ivec3(-1, -1, 1),
 398 | 			ivec3(-1, 0, -1),
 399 | 			ivec3(-1, 0, 0),
 400 | 			ivec3(-1, 0, 1),
 401 | 			ivec3(-1, 1, -1),
 402 | 			ivec3(-1, 1, 0),
 403 | 			ivec3(-1, 1, 1),
 404 | 			ivec3(0, -1, -1),
 405 | 			ivec3(0, -1, 0),
 406 | 			ivec3(0, -1, 1),
 407 | 			ivec3(0, 0, -1),
 408 | 			ivec3(0, 0, 0),
 409 | 			ivec3(0, 0, 1),
 410 | 			ivec3(0, 1, -1),
 411 | 			ivec3(0, 1, 0),
 412 | 			ivec3(0, 1, 1),
 413 | 			ivec3(1, -1, -1),
 414 | 			ivec3(1, -1, 0),
 415 | 			ivec3(1, -1, 1),
 416 | 			ivec3(1, 0, -1),
 417 | 			ivec3(1, 0, 0),
 418 | 			ivec3(1, 0, 1),
 419 | 			ivec3(1, 1, -1),
 420 | 			ivec3(1, 1, 0),
 421 | 			ivec3(1, 1, 1));
 422 | 
 423 | 	
 424 | 	uvec4 closest = uvec4(0);
 425 | 	float closest_dist = 0.0;
 426 | 
 427 | 	vec3 posf = vec3(global_pos);
 428 | 
 429 | 	if (params.half_size) {
 430 | 		posf = posf * 2.0 + 0.5;
 431 | 	}
 432 | 
 433 | 	for (uint i = 0; i < offset_count; i++) {
 434 | 		uvec4 point = group_load(local_pos + offsets[i]);
 435 | 
 436 | 		if (point.w == 0) {
 437 | 			continue; 
 438 | 		}
 439 | 
 440 | 		float dist = distance(posf, vec3(point.xyz));
 441 | 		if (closest.w == 0 || dist < closest_dist) {
 442 | 			closest = point;
 443 | 			closest_dist = dist;
 444 | 		}
 445 | 	}
 446 | 
 447 | 	imageStore(dst_positions, global_pos, closest);
 448 | 
 449 | #endif
 450 | 
 451 | #ifdef MODE_UPSCALE_JUMP_FLOOD
 452 | 
 453 | 	ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);
 454 | 
 455 | 	uint c = imageLoad(src_color, pos).r;
 456 | 	uvec4 v;
 457 | 	if (bool(c & 1)) {
 458 | 		
 459 | 		v.xyz = uvec3(pos);
 460 | 		v.w = 255; 
 461 | 	} else {
 462 | 		v = imageLoad(src_positions_half, pos >> 1);
 463 | 		float d = length(vec3(ivec3(v.xyz) - pos));
 464 | 
 465 | 		ivec3 vbase = ivec3(v.xyz - (v.xyz & uvec3(1)));
 466 | 
 467 | 		
 468 | 		for (int i = 0; i < 8; i++) {
 469 | 			ivec3 bits = ((ivec3(i) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1));
 470 | 			ivec3 p = vbase + bits;
 471 | 
 472 | 			float d2 = length(vec3(p - pos));
 473 | 			if (d2 < d) { 
 474 | 				uint c2 = imageLoad(src_color, p).r;
 475 | 				if (bool(c2 & 1)) {
 476 | 					v.xyz = uvec3(p);
 477 | 					d = d2;
 478 | 				}
 479 | 			}
 480 | 		}
 481 | 
 482 | 		
 483 | 	}
 484 | 
 485 | 	imageStore(dst_positions, pos, v);
 486 | 
 487 | #endif
 488 | 
 489 | #ifdef MODE_OCCLUSION
 490 | 
 491 | 	uint invocation_idx = uint(gl_LocalInvocationID.x);
 492 | 	ivec3 region = ivec3(gl_WorkGroupID);
 493 | 
 494 | 	ivec3 region_offset = -ivec3(OCCLUSION_SIZE);
 495 | 	region_offset += region * OCCLUSION_SIZE * 2;
 496 | 	region_offset += params.probe_offset * OCCLUSION_SIZE;
 497 | 
 498 | 	if (params.scroll != ivec3(0)) {
 499 | 		
 500 | 		ivec3 region_offset_to = region_offset + ivec3(OCCLUSION_SIZE * 2);
 501 | 		uvec3 scroll_mask = uvec3(notEqual(params.scroll, ivec3(0))); 
 502 | 		ivec3 scroll_from = mix(ivec3(0), ivec3(params.grid_size) + params.scroll, lessThan(params.scroll, ivec3(0)));
 503 | 		ivec3 scroll_to = mix(ivec3(params.grid_size), params.scroll, greaterThan(params.scroll, ivec3(0)));
 504 | 
 505 | 		if ((uvec3(lessThanEqual(region_offset_to, scroll_from)) | uvec3(greaterThanEqual(region_offset, scroll_to))) * scroll_mask == scroll_mask) { 
 506 | 			return; 
 507 | 		}
 508 | 	}
 509 | 
 510 | #define OCC_HALF_SIZE (OCCLUSION_SIZE / 2)
 511 | 
 512 | 	ivec3 local_ofs = ivec3(uvec3(invocation_idx % OCC_HALF_SIZE, (invocation_idx % (OCC_HALF_SIZE * OCC_HALF_SIZE)) / OCC_HALF_SIZE, invocation_idx / (OCC_HALF_SIZE * OCC_HALF_SIZE))) * 4;
 513 | 
 514 | 	/*	for(int i=0;i<64;i++) {
 515 | 		ivec3 offset = region_offset + local_ofs + ((ivec3(i) >> ivec3(0,2,4)) & ivec3(3,3,3));
 516 | 		uint facig =
 517 | 		if (all(greaterThanEqual(offset,ivec3(0))) && all(lessThan(offset,ivec3(params.grid_size)))) {*/
 518 | 
 519 | 	for (int i = 0; i < 16; i++) { 
 520 | 
 521 | 		ivec3 offset = local_ofs + ((ivec3(i * 4) >> ivec3(0, 2, 4)) & ivec3(3, 3, 3));
 522 | 
 523 | 		uint facing_pack = 0;
 524 | 		for (int j = 0; j < 4; j++) {
 525 | 			ivec3 foffset = region_offset + offset + ivec3(j, 0, 0);
 526 | 			if (all(greaterThanEqual(foffset, ivec3(0))) && all(lessThan(foffset, ivec3(params.grid_size)))) {
 527 | 				uint f = imageLoad(src_facing, foffset).r;
 528 | 				facing_pack |= f << (j * 8);
 529 | 			}
 530 | 		}
 531 | 
 532 | 		occlusion_facing[(offset.z * (OCCLUSION_SIZE * 2 * OCCLUSION_SIZE * 2) + offset.y * (OCCLUSION_SIZE * 2) + offset.x) / 4] = facing_pack;
 533 | 	}
 534 | 
 535 | 	
 536 | 	groupMemoryBarrier();
 537 | 	barrier();
 538 | 
 539 | 	
 540 | 
 541 | #define OCC_STEPS (OCCLUSION_SIZE * 3 - 2)
 542 | #define OCC_HALF_STEPS (OCC_STEPS / 2)
 543 | 
 544 | 	for (int step = 0; step < OCC_STEPS; step++) {
 545 | 		bool shrink = step >= OCC_HALF_STEPS;
 546 | 		int occ_step = shrink ? OCC_HALF_STEPS - (step - OCC_HALF_STEPS) - 1 : step;
 547 | 
 548 | 		if (invocation_idx < group_size_offset[occ_step].x) {
 549 | 			uint pv = group_pos[group_size_offset[occ_step].y + invocation_idx];
 550 | 			ivec3 proc_abs = (ivec3(int(pv)) >> ivec3(0, 8, 16)) & ivec3(0xFF);
 551 | 
 552 | 			if (shrink) {
 553 | 				proc_abs = ivec3(OCCLUSION_SIZE) - proc_abs - ivec3(1);
 554 | 			}
 555 | 
 556 | 			for (int i = 0; i < 8; i++) {
 557 | 				ivec3 bits = ((ivec3(i) >> ivec3(0, 1, 2)) & ivec3(1, 1, 1));
 558 | 				ivec3 proc_sign = bits * 2 - 1;
 559 | 				ivec3 local_offset = ivec3(OCCLUSION_SIZE) + proc_abs * proc_sign - (ivec3(1) - bits);
 560 | 				ivec3 offset = local_offset + region_offset;
 561 | 				if (all(greaterThanEqual(offset, ivec3(0))) && all(lessThan(offset, ivec3(params.grid_size)))) {
 562 | 					float occ;
 563 | 
 564 | 					uint facing = get_facing(local_offset);
 565 | 
 566 | 					if (facing != 0) { 
 567 | 						occ = 0.0;
 568 | 					} else if (step == 0) {
 569 | #if 0
 570 | 						occ = 0.0;
 571 | 						if (get_facing(local_offset - ivec3(proc_sign.x,0,0))==0) {
 572 | 							occ+=1.0;
 573 | 						}
 574 | 						if (get_facing(local_offset - ivec3(0,proc_sign.y,0))==0) {
 575 | 							occ+=1.0;
 576 | 						}
 577 | 						if (get_facing(local_offset - ivec3(0,0,proc_sign.z))==0) {
 578 | 							occ+=1.0;
 579 | 						}
 580 | 						/*
 581 | 						if (get_facing(local_offset - proc_sign)==0) {
 582 | 							occ+=1.0;
 583 | 						}*/
 584 | 
 585 | 						occ/=3.0;
 586 | #endif
 587 | 						occ = 1.0;
 588 | 
 589 | 					} else {
 590 | 						ivec3 read_dir = -proc_sign;
 591 | 
 592 | 						ivec3 major_axis;
 593 | 						if (proc_abs.x < proc_abs.y) {
 594 | 							if (proc_abs.z < proc_abs.y) {
 595 | 								major_axis = ivec3(0, 1, 0);
 596 | 							} else {
 597 | 								major_axis = ivec3(0, 0, 1);
 598 | 							}
 599 | 						} else {
 600 | 							if (proc_abs.z < proc_abs.x) {
 601 | 								major_axis = ivec3(1, 0, 0);
 602 | 							} else {
 603 | 								major_axis = ivec3(0, 0, 1);
 604 | 							}
 605 | 						}
 606 | 
 607 | 						float avg = 0.0;
 608 | 						occ = 0.0;
 609 | 
 610 | 						ivec3 read_x = offset + ivec3(read_dir.x, 0, 0) + (proc_abs.x == 0 ? major_axis * read_dir : ivec3(0));
 611 | 						ivec3 read_y = offset + ivec3(0, read_dir.y, 0) + (proc_abs.y == 0 ? major_axis * read_dir : ivec3(0));
 612 | 						ivec3 read_z = offset + ivec3(0, 0, read_dir.z) + (proc_abs.z == 0 ? major_axis * read_dir : ivec3(0));
 613 | 
 614 | 						uint facing_x = get_facing(read_x - region_offset);
 615 | 						if (facing_x == 0) {
 616 | 							if (all(greaterThanEqual(read_x, ivec3(0))) && all(lessThan(read_x, ivec3(params.grid_size)))) {
 617 | 								occ += imageLoad(dst_occlusion[params.occlusion_index], read_x).r;
 618 | 								avg += 1.0;
 619 | 							}
 620 | 						} else {
 621 | 							if (proc_abs.x != 0) { 
 622 | 								avg += 1.0;
 623 | 							}
 624 | 						}
 625 | 
 626 | 						uint facing_y = get_facing(read_y - region_offset);
 627 | 						if (facing_y == 0) {
 628 | 							if (all(greaterThanEqual(read_y, ivec3(0))) && all(lessThan(read_y, ivec3(params.grid_size)))) {
 629 | 								occ += imageLoad(dst_occlusion[params.occlusion_index], read_y).r;
 630 | 								avg += 1.0;
 631 | 							}
 632 | 						} else {
 633 | 							if (proc_abs.y != 0) {
 634 | 								avg += 1.0;
 635 | 							}
 636 | 						}
 637 | 
 638 | 						uint facing_z = get_facing(read_z - region_offset);
 639 | 						if (facing_z == 0) {
 640 | 							if (all(greaterThanEqual(read_z, ivec3(0))) && all(lessThan(read_z, ivec3(params.grid_size)))) {
 641 | 								occ += imageLoad(dst_occlusion[params.occlusion_index], read_z).r;
 642 | 								avg += 1.0;
 643 | 							}
 644 | 						} else {
 645 | 							if (proc_abs.z != 0) {
 646 | 								avg += 1.0;
 647 | 							}
 648 | 						}
 649 | 
 650 | 						if (avg > 0.0) {
 651 | 							occ /= avg;
 652 | 						}
 653 | 					}
 654 | 
 655 | 					imageStore(dst_occlusion[params.occlusion_index], offset, vec4(occ));
 656 | 				}
 657 | 			}
 658 | 		}
 659 | 
 660 | 		groupMemoryBarrier();
 661 | 		barrier();
 662 | 	}
 663 | #if 1
 664 | 	
 665 | 
 666 | 	for (int i = 0; i < 64; i++) {
 667 | 		ivec3 local_offset = local_ofs + ((ivec3(i) >> ivec3(0, 2, 4)) & ivec3(3, 3, 3));
 668 | 		ivec3 offset = region_offset + local_offset;
 669 | 
 670 | 		if (all(greaterThanEqual(offset, ivec3(0))) && all(lessThan(offset, ivec3(params.grid_size)))) {
 671 | 			uint facing = get_facing(local_offset);
 672 | 
 673 | 			if (facing != 0) {
 674 | 				
 675 | 
 676 | 				ivec3 proc_pos = local_offset - ivec3(OCCLUSION_SIZE);
 677 | 				proc_pos += mix(ivec3(0), ivec3(1), greaterThanEqual(proc_pos, ivec3(0)));
 678 | 
 679 | 				float avg = 0.0;
 680 | 				float occ = 0.0;
 681 | 
 682 | 				ivec3 read_dir = -sign(proc_pos);
 683 | 				ivec3 read_dir_x = ivec3(read_dir.x, 0, 0);
 684 | 				ivec3 read_dir_y = ivec3(0, read_dir.y, 0);
 685 | 				ivec3 read_dir_z = ivec3(0, 0, read_dir.z);
 686 | 				
 687 | #if 0
 688 | 
 689 | 				uvec3 facing_pos_base = (uvec3(facing) >> uvec3(0,1,2)) & uvec3(1,1,1);
 690 | 				uvec3 facing_neg_base = (uvec3(facing) >> uvec3(3,4,5)) & uvec3(1,1,1);
 691 | 				uvec3 facing_pos=  facing_pos_base &((~facing_neg_base)&uvec3(1,1,1));
 692 | 				uvec3 facing_neg=  facing_neg_base &((~facing_pos_base)&uvec3(1,1,1));
 693 | #else
 694 | 				uvec3 facing_pos = (uvec3(facing) >> uvec3(0, 1, 2)) & uvec3(1, 1, 1);
 695 | 				uvec3 facing_neg = (uvec3(facing) >> uvec3(3, 4, 5)) & uvec3(1, 1, 1);
 696 | #endif
 697 | 				bvec3 read_valid = bvec3(mix(facing_neg, facing_pos, greaterThan(read_dir, ivec3(0))));
 698 | 
 699 | 				
 700 | 				if (read_valid.x) {
 701 | 					ivec3 read_offset = local_offset + read_dir_x;
 702 | 					uint f = get_facing(read_offset);
 703 | 					if (f == 0) {
 704 | 						read_offset += region_offset;
 705 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 706 | 							occ += imageLoad(dst_occlusion[params.occlusion_index], read_offset).r;
 707 | 							avg += 1.0;
 708 | 						}
 709 | 					}
 710 | 				}
 711 | 
 712 | 				if (read_valid.y) {
 713 | 					ivec3 read_offset = local_offset + read_dir_y;
 714 | 					uint f = get_facing(read_offset);
 715 | 					if (f == 0) {
 716 | 						read_offset += region_offset;
 717 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 718 | 							occ += imageLoad(dst_occlusion[params.occlusion_index], read_offset).r;
 719 | 							avg += 1.0;
 720 | 						}
 721 | 					}
 722 | 				}
 723 | 
 724 | 				if (read_valid.z) {
 725 | 					ivec3 read_offset = local_offset + read_dir_z;
 726 | 					uint f = get_facing(read_offset);
 727 | 					if (f == 0) {
 728 | 						read_offset += region_offset;
 729 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 730 | 							occ += imageLoad(dst_occlusion[params.occlusion_index], read_offset).r;
 731 | 							avg += 1.0;
 732 | 						}
 733 | 					}
 734 | 				}
 735 | 
 736 | 				
 737 | 
 738 | 				if (all(read_valid.yz)) {
 739 | 					ivec3 read_offset = local_offset + read_dir_y + read_dir_z;
 740 | 					uint f = get_facing(read_offset);
 741 | 					if (f == 0) {
 742 | 						read_offset += region_offset;
 743 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 744 | 							occ += imageLoad(dst_occlusion[params.occlusion_index], read_offset).r;
 745 | 							avg += 1.0;
 746 | 						}
 747 | 					}
 748 | 				}
 749 | 
 750 | 				if (all(read_valid.xz)) {
 751 | 					ivec3 read_offset = local_offset + read_dir_x + read_dir_z;
 752 | 					uint f = get_facing(read_offset);
 753 | 					if (f == 0) {
 754 | 						read_offset += region_offset;
 755 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 756 | 							occ += imageLoad(dst_occlusion[params.occlusion_index], read_offset).r;
 757 | 							avg += 1.0;
 758 | 						}
 759 | 					}
 760 | 				}
 761 | 
 762 | 				if (all(read_valid.xy)) {
 763 | 					ivec3 read_offset = local_offset + read_dir_x + read_dir_y;
 764 | 					uint f = get_facing(read_offset);
 765 | 					if (f == 0) {
 766 | 						read_offset += region_offset;
 767 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 768 | 							occ += imageLoad(dst_occlusion[params.occlusion_index], read_offset).r;
 769 | 							avg += 1.0;
 770 | 						}
 771 | 					}
 772 | 				}
 773 | 
 774 | 				
 775 | 
 776 | 				if (all(read_valid)) {
 777 | 					ivec3 read_offset = local_offset + read_dir;
 778 | 					uint f = get_facing(read_offset);
 779 | 					if (f == 0) {
 780 | 						read_offset += region_offset;
 781 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 782 | 							occ += imageLoad(dst_occlusion[params.occlusion_index], read_offset).r;
 783 | 							avg += 1.0;
 784 | 						}
 785 | 					}
 786 | 				}
 787 | 
 788 | 				if (avg > 0.0) {
 789 | 					occ /= avg;
 790 | 				}
 791 | 
 792 | 				imageStore(dst_occlusion[params.occlusion_index], offset, vec4(occ));
 793 | 			}
 794 | 		}
 795 | 	}
 796 | 
 797 | #endif
 798 | 
 799 | #if 1
 800 | 	groupMemoryBarrier();
 801 | 	barrier();
 802 | 
 803 | 	for (int i = 0; i < 64; i++) {
 804 | 		ivec3 local_offset = local_ofs + ((ivec3(i) >> ivec3(0, 2, 4)) & ivec3(3, 3, 3));
 805 | 		ivec3 offset = region_offset + local_offset;
 806 | 
 807 | 		if (all(greaterThanEqual(offset, ivec3(0))) && all(lessThan(offset, ivec3(params.grid_size)))) {
 808 | 			uint facing = get_facing(local_offset);
 809 | 
 810 | 			if (facing == 0) {
 811 | 				ivec3 proc_pos = local_offset - ivec3(OCCLUSION_SIZE);
 812 | 				proc_pos += mix(ivec3(0), ivec3(1), greaterThanEqual(proc_pos, ivec3(0)));
 813 | 
 814 | 				ivec3 proc_abs = abs(proc_pos);
 815 | 
 816 | 				ivec3 read_dir = sign(proc_pos); 
 817 | 				ivec3 read_dir_x = ivec3(read_dir.x, 0, 0);
 818 | 				ivec3 read_dir_y = ivec3(0, read_dir.y, 0);
 819 | 				ivec3 read_dir_z = ivec3(0, 0, read_dir.z);
 820 | 				
 821 | 				uvec3 read_mask = mix(uvec3(1, 2, 4), uvec3(8, 16, 32), greaterThan(read_dir, ivec3(0))); 
 822 | 				uvec3 block_mask = mix(uvec3(1, 2, 4), uvec3(8, 16, 32), lessThan(read_dir, ivec3(0))); 
 823 | 
 824 | 				block_mask = uvec3(0);
 825 | 
 826 | 				float visible = 0.0;
 827 | 				float occlude_total = 0.0;
 828 | 
 829 | 				if (proc_abs.x < OCCLUSION_SIZE) {
 830 | 					ivec3 read_offset = local_offset + read_dir_x;
 831 | 					uint x_mask = get_facing(read_offset);
 832 | 					if (x_mask != 0) {
 833 | 						read_offset += region_offset;
 834 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 835 | 							occlude_total += 1.0;
 836 | 							if (bool(x_mask & read_mask.x) && !bool(x_mask & block_mask.x)) {
 837 | 								visible += 1.0;
 838 | 							}
 839 | 						}
 840 | 					}
 841 | 				}
 842 | 
 843 | 				if (proc_abs.y < OCCLUSION_SIZE) {
 844 | 					ivec3 read_offset = local_offset + read_dir_y;
 845 | 					uint y_mask = get_facing(read_offset);
 846 | 					if (y_mask != 0) {
 847 | 						read_offset += region_offset;
 848 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 849 | 							occlude_total += 1.0;
 850 | 							if (bool(y_mask & read_mask.y) && !bool(y_mask & block_mask.y)) {
 851 | 								visible += 1.0;
 852 | 							}
 853 | 						}
 854 | 					}
 855 | 				}
 856 | 
 857 | 				if (proc_abs.z < OCCLUSION_SIZE) {
 858 | 					ivec3 read_offset = local_offset + read_dir_z;
 859 | 					uint z_mask = get_facing(read_offset);
 860 | 					if (z_mask != 0) {
 861 | 						read_offset += region_offset;
 862 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 863 | 							occlude_total += 1.0;
 864 | 							if (bool(z_mask & read_mask.z) && !bool(z_mask & block_mask.z)) {
 865 | 								visible += 1.0;
 866 | 							}
 867 | 						}
 868 | 					}
 869 | 				}
 870 | 
 871 | 				
 872 | 
 873 | 				read_mask = mix(uvec3(1, 2, 4), uvec3(8, 16, 32), lessThan(read_dir, ivec3(0))); 
 874 | 				block_mask = mix(uvec3(1, 2, 4), uvec3(8, 16, 32), greaterThan(read_dir, ivec3(0))); 
 875 | 				block_mask = uvec3(0);
 876 | 
 877 | 				if (proc_abs.x == 1) {
 878 | 					ivec3 read_offset = local_offset - read_dir_x;
 879 | 					uint x_mask = get_facing(read_offset);
 880 | 					if (x_mask != 0) {
 881 | 						read_offset += region_offset;
 882 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 883 | 							occlude_total += 1.0;
 884 | 							if (bool(x_mask & read_mask.x) && !bool(x_mask & block_mask.x)) {
 885 | 								visible += 1.0;
 886 | 							}
 887 | 						}
 888 | 					}
 889 | 				}
 890 | 
 891 | 				if (proc_abs.y == 1) {
 892 | 					ivec3 read_offset = local_offset - read_dir_y;
 893 | 					uint y_mask = get_facing(read_offset);
 894 | 					if (y_mask != 0) {
 895 | 						read_offset += region_offset;
 896 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 897 | 							occlude_total += 1.0;
 898 | 							if (bool(y_mask & read_mask.y) && !bool(y_mask & block_mask.y)) {
 899 | 								visible += 1.0;
 900 | 							}
 901 | 						}
 902 | 					}
 903 | 				}
 904 | 
 905 | 				if (proc_abs.z == 1) {
 906 | 					ivec3 read_offset = local_offset - read_dir_z;
 907 | 					uint z_mask = get_facing(read_offset);
 908 | 					if (z_mask != 0) {
 909 | 						read_offset += region_offset;
 910 | 						if (all(greaterThanEqual(read_offset, ivec3(0))) && all(lessThan(read_offset, ivec3(params.grid_size)))) {
 911 | 							occlude_total += 1.0;
 912 | 							if (bool(z_mask & read_mask.z) && !bool(z_mask & block_mask.z)) {
 913 | 								visible += 1.0;
 914 | 							}
 915 | 						}
 916 | 					}
 917 | 				}
 918 | 
 919 | 				if (occlude_total > 0.0) {
 920 | 					float occ = imageLoad(dst_occlusion[params.occlusion_index], offset).r;
 921 | 					occ *= visible / occlude_total;
 922 | 					imageStore(dst_occlusion[params.occlusion_index], offset, vec4(occ));
 923 | 				}
 924 | 			}
 925 | 		}
 926 | 	}
 927 | 
 928 | #endif
 929 | 
 930 | 	/*
 931 | 	for(int i=0;i<8;i++) {
 932 | 		ivec3 local_offset = local_pos + ((ivec3(i) >> ivec3(2,1,0)) & ivec3(1,1,1)) * OCCLUSION_SIZE;
 933 | 		ivec3 offset = local_offset - ivec3(OCCLUSION_SIZE); 
 934 | 		offset += region * OCCLUSION_SIZE * 2; 
 935 | 		offset += params.probe_offset * OCCLUSION_SIZE; 
 936 | 		if (all(greaterThanEqual(offset,ivec3(0))) && all(lessThan(offset,ivec3(params.grid_size)))) {
 937 | 			imageStore(dst_occlusion[params.occlusion_index],offset,vec4( occlusion_data[ to_linear(local_offset) ]  ));
 938 | 			
 939 | 		}
 940 | 	}
 941 | */
 942 | 
 943 | #endif
 944 | 
 945 | #ifdef MODE_STORE
 946 | 
 947 | 	ivec3 local = ivec3(gl_LocalInvocationID.xyz);
 948 | 	ivec3 pos = ivec3(gl_GlobalInvocationID.xyz);
 949 | 	
 950 | 	uvec4 p = imageLoad(src_positions, pos);
 951 | 
 952 | 	bool solid = false;
 953 | 	float d;
 954 | 	if (ivec3(p.xyz) == pos) {
 955 | 		
 956 | 		d = 0;
 957 | 		solid = true;
 958 | 	} else {
 959 | 		
 960 | 		d = 1.0 + length(vec3(p.xyz) - vec3(pos));
 961 | 	}
 962 | 
 963 | 	d /= 255.0;
 964 | 
 965 | 	imageStore(dst_sdf, pos, vec4(d));
 966 | 
 967 | 	
 968 | 
 969 | 	uint occlusion = 0;
 970 | 	const uint occlusion_shift[8] = uint[](12, 8, 4, 0, 28, 24, 20, 16);
 971 | 	for (int i = 0; i < 8; i++) {
 972 | 		float occ = imageLoad(src_occlusion[i], pos).r;
 973 | 		occlusion |= uint(clamp(occ * 15.0, 0.0, 15.0)) << occlusion_shift[i];
 974 | 	}
 975 | 	{
 976 | 		ivec3 occ_pos = pos;
 977 | 		occ_pos.z += params.cascade * params.grid_size;
 978 | 		imageStore(dst_occlusion, occ_pos, uvec4(occlusion & 0xFFFF));
 979 | 		occ_pos.x += params.grid_size;
 980 | 		imageStore(dst_occlusion, occ_pos, uvec4(occlusion >> 16));
 981 | 	}
 982 | 
 983 | 	
 984 | 
 985 | 	if (local == ivec3(0)) {
 986 | 		store_position_count = 0; 
 987 | 	}
 988 | 
 989 | 	groupMemoryBarrier();
 990 | 	barrier();
 991 | 
 992 | 	if (solid) {
 993 | 		uint index = atomicAdd(store_position_count, 1);
 994 | 		
 995 | 		store_positions[index].position = uint(pos.x | (pos.y << 7) | (pos.z << 14));
 996 | 
 997 | 		
 998 | 		uint bit_index = 0;
 999 | 		uint neighbour_bits = 0;
1000 | 		for (int i = -1; i <= 1; i++) {
1001 | 			for (int j = -1; j <= 1; j++) {
1002 | 				for (int k = -1; k <= 1; k++) {
1003 | 					if (i == 0 && j == 0 && k == 0) {
1004 | 						continue;
1005 | 					}
1006 | 					ivec3 npos = pos + ivec3(i, j, k);
1007 | 					if (all(greaterThanEqual(npos, ivec3(0))) && all(lessThan(npos, ivec3(params.grid_size)))) {
1008 | 						p = imageLoad(src_positions, npos);
1009 | 						if (ivec3(p.xyz) == pos) {
1010 | 							neighbour_bits |= (1 << bit_index);
1011 | 						}
1012 | 					}
1013 | 					bit_index++;
1014 | 				}
1015 | 			}
1016 | 		}
1017 | 
1018 | 		uint rgb = imageLoad(src_albedo, pos).r;
1019 | 		uint facing = imageLoad(src_facing, pos).r;
1020 | 
1021 | 		store_positions[index].albedo = rgb >> 1; 
1022 | 		store_positions[index].albedo |= (facing & 0x3F) << 15; 
1023 | 
1024 | 		store_positions[index].albedo |= neighbour_bits << 21; 
1025 | 		store_positions[index].position |= (neighbour_bits >> 11) << 21; 
1026 | 
1027 | 		store_positions[index].light = imageLoad(src_light, pos).r;
1028 | 		store_positions[index].light_aniso = imageLoad(src_light_aniso, pos).r;
1029 | 		
1030 | 		store_positions[index].light |= (neighbour_bits >> 22) << 30; 
1031 | 		store_positions[index].light_aniso |= (neighbour_bits >> 24) << 30; 
1032 | 	}
1033 | 
1034 | 	groupMemoryBarrier();
1035 | 	barrier();
1036 | 
1037 | 	
1038 | 
1039 | 	if (local == ivec3(0) && store_position_count > 0) {
1040 | 		store_from_index = atomicAdd(dispatch_data.total_count, store_position_count);
1041 | 		uint group_count = Math::division_round_up(store_from_index + store_position_count, 64);
1042 | 		atomicMax(dispatch_data.x, group_count);
1043 | 	}
1044 | 
1045 | 	groupMemoryBarrier();
1046 | 	barrier();
1047 | 
1048 | 	uint read_index = uint(local.z * 4 * 4 + local.y * 4 + local.x);
1049 | 	uint write_index = store_from_index + read_index;
1050 | 
1051 | 	if (read_index < store_position_count) {
1052 | 		dst_process_voxels.data[write_index] = store_positions[read_index];
1053 | 	}
1054 | 
1055 | 	if (pos == ivec3(0)) {
1056 | 		
1057 | 		dispatch_data.y = 1;
1058 | 		dispatch_data.z = 1;
1059 | 	}
1060 | #endif
1061 | }
1062 | 
1063 | 
   at: _compile_variant (./servers/rendering/renderer_rd/shader_rd.cpp:297)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)
ERROR: Parameter "shader" is null.
   at: compute_pipeline_create (./servers/rendering/rendering_device.cpp:3536)

@clayjohn
Copy link
Member

@Calinou That error comes from #80390 and was fixed by 7abaac6. Its shouldn't have an impact on this issue.

I'll look into how the normal reconstruction is breaking things. Its very weird that it would cause an issue. But should be easy to fix

@clayjohn
Copy link
Member

Testing a fix now. I think we are using the raw roughness in a place where we should use the transformed roughness.

float roughness_fade = smoothstep(0.4, 0.7, 1.0 - normal_roughness.w);

@clayjohn
Copy link
Member

Moving to 4.4 since we are so close to the release of 4.3. The fix can easily be cherry picked for 4.3.1, so it will only be a short delay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants