EEVEE Next: Add imageStore/LoadFast ops to Raytrace passes #121117

Merged
Clément Foucault merged 5 commits from Jason-Fielder/blender:im_store_fast_rt into main 2024-05-24 12:51:31 +02:00
8 changed files with 68 additions and 47 deletions

View File

@ -53,8 +53,8 @@ void main()
}
float roughness = closure_apparent_roughness_get(center_closure);
float variance = imageLoad(in_variance_img, texel_fullres).r;
vec3 in_radiance = imageLoad(in_radiance_img, texel_fullres).rgb;
float variance = imageLoadFast(in_variance_img, texel_fullres).r;
vec3 in_radiance = imageLoadFast(in_radiance_img, texel_fullres).rgb;
bool is_background = (center_depth == 0.0);
bool is_smooth = (roughness < 0.05);
@ -68,7 +68,7 @@ void main()
if (is_smooth || is_background || is_low_variance) {
/* Early out cases. */
imageStore(out_radiance_img, texel_fullres, vec4(in_radiance, 0.0));
imageStoreFast(out_radiance_img, texel_fullres, vec4(in_radiance, 0.0));
return;
}
@ -100,7 +100,7 @@ void main()
continue;
}
vec3 radiance = imageLoad(in_radiance_img, sample_texel).rgb;
vec3 radiance = imageLoadFast(in_radiance_img, sample_texel).rgb;
/* Do not gather unprocessed pixels. */
if (all(equal(radiance, FLT_11_11_10_MAX))) {
@ -129,5 +129,5 @@ void main()
vec3 out_radiance = accum_radiance * safe_rcp(accum_weight);
out_radiance = from_accumulation_space(out_radiance);
imageStore(out_radiance_img, texel_fullres, vec4(out_radiance, 0.0));
imageStoreFast(out_radiance_img, texel_fullres, vec4(out_radiance, 0.0));
}

View File

@ -79,9 +79,9 @@ void transmission_thickness_amend_closure(inout ClosureUndetermined cl,
/* Tag pixel radiance as invalid. */
void invalid_pixel_write(ivec2 texel)
{
imageStore(out_radiance_img, texel, vec4(FLT_11_11_10_MAX, 0.0));
imageStore(out_variance_img, texel, vec4(0.0));
imageStore(out_hit_depth_img, texel, vec4(0.0));
imageStoreFast(out_radiance_img, texel, vec4(FLT_11_11_10_MAX, 0.0));
imageStoreFast(out_variance_img, texel, vec4(0.0));
imageStoreFast(out_hit_depth_img, texel, vec4(0.0));
}
void main()
@ -123,7 +123,7 @@ void main()
ivec3 sample_tile = ivec3(tile_coord_neighbor, closure_index);
uint tile_mask = imageLoad(tile_mask_img, sample_tile).r;
uint tile_mask = imageLoadFast(tile_mask_img, sample_tile).r;
bool tile_is_unused = !flag_test(tile_mask, 1u << 0u);
if (tile_is_unused) {
ivec2 texel_fullres_neighbor = texel_fullres + ivec2(x, y) * int(tile_size);
@ -220,7 +220,7 @@ void main()
float scene_z = drw_depth_screen_to_view(texelFetch(depth_tx, texel_fullres, 0).r);
float hit_depth = drw_depth_view_to_screen(scene_z - closest_hit_time);
imageStore(out_radiance_img, texel_fullres, vec4(radiance_accum, 0.0));
imageStore(out_variance_img, texel_fullres, vec4(hit_variance));
imageStore(out_hit_depth_img, texel_fullres, vec4(hit_depth));
imageStoreFast(out_radiance_img, texel_fullres, vec4(radiance_accum, 0.0));
imageStoreFast(out_variance_img, texel_fullres, vec4(hit_variance));
imageStoreFast(out_hit_depth_img, texel_fullres, vec4(hit_depth));
}

View File

@ -167,13 +167,18 @@ void main()
ivec2 texel_fullres = ivec2(gl_LocalInvocationID.xy + tile_coord * tile_size);
vec2 uv = (vec2(texel_fullres) + 0.5) * uniform_buf.raytrace.full_resolution_inv;
float in_variance = imageLoad(in_variance_img, texel_fullres).r;
vec3 in_radiance = imageLoad(in_radiance_img, texel_fullres).rgb;
/* Check if texel is out of bounds, so we can utilise fast texture funcs and early-out if not. */
if (any(greaterThanEqual(texel_fullres, imageSize(in_radiance_img).xy))) {
return;
}
float in_variance = imageLoadFast(in_variance_img, texel_fullres).r;
vec3 in_radiance = imageLoadFast(in_radiance_img, texel_fullres).rgb;
if (all(equal(in_radiance, FLT_11_11_10_MAX))) {
/* Early out on pixels that were marked unprocessed by the previous pass. */
imageStore(out_radiance_img, texel_fullres, vec4(FLT_11_11_10_MAX, 0.0));
imageStore(out_variance_img, texel_fullres, vec4(0.0));
imageStoreFast(out_radiance_img, texel_fullres, vec4(FLT_11_11_10_MAX, 0.0));
imageStoreFast(out_variance_img, texel_fullres, vec4(0.0));
return;
}
@ -187,7 +192,7 @@ void main()
vec3 P = drw_point_screen_to_world(vec3(uv, scene_depth));
vec4 history_radiance = radiance_history_sample(P, local);
/* Reflection reprojection. */
float hit_depth = imageLoad(hit_depth_img, texel_fullres).r;
float hit_depth = imageLoadFast(hit_depth_img, texel_fullres).r;
vec3 P_hit = drw_point_screen_to_world(vec3(uv, hit_depth));
history_radiance += radiance_history_sample(P_hit, local);
/* Finalize accumulation. */
@ -203,7 +208,7 @@ void main()
vec3 out_radiance = mix(
colorspace_safe_color(in_radiance), colorspace_safe_color(history_radiance.rgb), mix_fac);
/* This is feedback next frame as radiance_history_tx. */
imageStore(out_radiance_img, texel_fullres, vec4(out_radiance, 0.0));
imageStoreFast(out_radiance_img, texel_fullres, vec4(out_radiance, 0.0));
/* Variance. */
@ -213,5 +218,5 @@ void main()
float mix_variance_fac = (history_variance.y == 0.0) ? 0.0 : 0.90;
float out_variance = mix(in_variance, history_variance.x, mix_variance_fac);
/* This is feedback next frame as variance_history_tx. */
imageStore(out_variance_img, texel_fullres, vec4(out_variance));
imageStoreFast(out_variance_img, texel_fullres, vec4(out_variance));
}

View File

@ -44,5 +44,5 @@ void main()
* Limit to the smallest non-0 value that the format can encode.
* Strangely it does not correspond to the IEEE spec. */
float inv_pdf = (samp.pdf == 0.0) ? 0.0 : max(6e-8, 1.0 / samp.pdf);
imageStore(out_ray_data_img, texel, vec4(samp.direction, inv_pdf));
imageStoreFast(out_ray_data_img, texel, vec4(samp.direction, inv_pdf));
}

View File

@ -67,15 +67,15 @@ void main()
for (int i = 0; i < GBUFFER_LAYER_MAX; i++) {
if (tile_contains_ray_tracing[i] > 0) {
imageStore(tile_raytrace_denoise_img, ivec3(denoise_tile_co, i), uvec4(1));
imageStore(tile_raytrace_tracing_img, ivec3(tracing_tile_co, i), uvec4(1));
imageStoreFast(tile_raytrace_denoise_img, ivec3(denoise_tile_co, i), uvec4(1));
imageStoreFast(tile_raytrace_tracing_img, ivec3(tracing_tile_co, i), uvec4(1));
}
}
if (tile_contains_horizon_scan > 0) {
ivec2 tracing_tile_co = denoise_tile_co / uniform_buf.raytrace.horizon_resolution_scale;
imageStore(tile_horizon_denoise_img, ivec3(denoise_tile_co, 0), uvec4(1));
imageStore(tile_horizon_tracing_img, ivec3(tracing_tile_co, 0), uvec4(1));
imageStoreFast(tile_horizon_denoise_img, ivec3(denoise_tile_co, 0), uvec4(1));
imageStoreFast(tile_horizon_tracing_img, ivec3(tracing_tile_co, 0), uvec4(1));
}
}
}

View File

@ -24,16 +24,21 @@ void main()
ivec2 texel_fullres = texel * uniform_buf.raytrace.resolution_scale +
uniform_buf.raytrace.resolution_bias;
/* Check if texel is out of bounds, so we can utilise fast texture funcs and early-out if not. */
if (any(greaterThanEqual(texel, imageSize(ray_time_img).xy))) {
return;
}
float depth = texelFetch(depth_tx, texel_fullres, 0).r;
vec2 uv = (vec2(texel_fullres) + 0.5) * uniform_buf.raytrace.full_resolution_inv;
vec4 ray_data = imageLoad(ray_data_img, texel);
float ray_pdf_inv = ray_data.w;
vec4 ray_data_im = imageLoadFast(ray_data_img, texel);
float ray_pdf_inv = ray_data_im.w;
if (ray_pdf_inv == 0.0) {
/* Invalid ray or pixels without ray. Do not trace. */
imageStore(ray_time_img, texel, vec4(0.0));
imageStore(ray_radiance_img, texel, vec4(0.0));
imageStoreFast(ray_time_img, texel, vec4(0.0));
imageStoreFast(ray_radiance_img, texel, vec4(0.0));
return;
}
@ -42,7 +47,7 @@ void main()
Ray ray;
ray.origin = P;
ray.direction = ray_data.xyz;
ray.direction = ray_data_im.xyz;
/* Only closure 0 can be a transmission closure. */
if (closure_index == 0) {
@ -72,6 +77,6 @@ void main()
radiance = colorspace_brightness_clamp_max(radiance, uniform_buf.clamp.surface_indirect);
imageStore(ray_time_img, texel, vec4(hit_time));
imageStore(ray_radiance_img, texel, vec4(radiance, 0.0));
imageStoreFast(ray_time_img, texel, vec4(hit_time));
imageStoreFast(ray_radiance_img, texel, vec4(radiance, 0.0));
}

View File

@ -23,13 +23,18 @@ void main()
uvec2 tile_coord = unpackUvec2x16(tiles_coord_buf[gl_WorkGroupID.x]);
ivec2 texel = ivec2(gl_LocalInvocationID.xy + tile_coord * tile_size);
vec4 ray_data = imageLoad(ray_data_img, texel);
float ray_pdf_inv = ray_data.w;
/* Check if texel is out of bounds, so we can utilise fast texture funcs and early-out if not. */
if (any(greaterThanEqual(texel, imageSize(ray_time_img).xy))) {
return;
}
vec4 ray_data_im = imageLoadFast(ray_data_img, texel);
float ray_pdf_inv = ray_data_im.w;
if (ray_pdf_inv == 0.0) {
/* Invalid ray or pixels without ray. Do not trace. */
imageStore(ray_time_img, texel, vec4(0.0));
imageStore(ray_radiance_img, texel, vec4(0.0));
imageStoreFast(ray_time_img, texel, vec4(0.0));
imageStoreFast(ray_radiance_img, texel, vec4(0.0));
return;
}
@ -52,7 +57,7 @@ void main()
vec3 P = drw_point_screen_to_world(vec3(uv, depth));
vec3 V = drw_world_incident_vector(P);
int planar_id = lightprobe_planar_select(P, V, ray_data.xyz);
int planar_id = lightprobe_planar_select(P, V, ray_data_im.xyz);
if (planar_id == -1) {
return;
}
@ -60,11 +65,11 @@ void main()
PlanarProbeData planar = probe_planar_buf[planar_id];
/* Tag the ray data so that screen trace will not try to evaluate it and override the result. */
imageStore(ray_data_img, texel, vec4(ray_data.xyz, -ray_data.w));
imageStoreFast(ray_data_img, texel, vec4(ray_data_im.xyz, -ray_data_im.w));
Ray ray;
ray.origin = P;
ray.direction = ray_data.xyz;
ray.direction = ray_data_im.xyz;
vec3 radiance = vec3(0.0);
float noise_offset = sampling_rng_1D_get(SAMPLING_RAYTRACE_W);
@ -102,6 +107,6 @@ void main()
radiance = colorspace_brightness_clamp_max(radiance, uniform_buf.clamp.surface_indirect);
imageStore(ray_time_img, texel, vec4(hit.time));
imageStore(ray_radiance_img, texel, vec4(radiance, 0.0));
imageStoreFast(ray_time_img, texel, vec4(hit.time));
imageStoreFast(ray_radiance_img, texel, vec4(radiance, 0.0));
}

View File

@ -22,8 +22,14 @@ void main()
uvec2 tile_coord = unpackUvec2x16(tiles_coord_buf[gl_WorkGroupID.x]);
ivec2 texel = ivec2(gl_LocalInvocationID.xy + tile_coord * tile_size);
vec4 ray_data = imageLoad(ray_data_img, texel);
float ray_pdf_inv = ray_data.w;
/* Check whether texel is out of bounds for all cases, so we can utilise fast
* texture funcs and early exit if not. */
if (any(greaterThanEqual(texel, imageSize(ray_data_img).xy)) || any(lessThan(texel, ivec2(0)))) {
return;
}
vec4 ray_data_im = imageLoadFast(ray_data_img, texel);
float ray_pdf_inv = ray_data_im.w;
if (ray_pdf_inv < 0.0) {
/* Ray destined to planar trace. */
@ -32,8 +38,8 @@ void main()
if (ray_pdf_inv == 0.0) {
/* Invalid ray or pixels without ray. Do not trace. */
imageStore(ray_time_img, texel, vec4(0.0));
imageStore(ray_radiance_img, texel, vec4(0.0));
imageStoreFast(ray_time_img, texel, vec4(0.0));
imageStoreFast(ray_radiance_img, texel, vec4(0.0));
return;
}
@ -57,7 +63,7 @@ void main()
vec3 V = drw_world_incident_vector(P);
Ray ray;
ray.origin = P;
ray.direction = ray_data.xyz;
ray.direction = ray_data_im.xyz;
/* Only closure 0 can be a transmission closure. */
if (closure_index == 0) {
@ -143,6 +149,6 @@ void main()
radiance = colorspace_brightness_clamp_max(radiance, uniform_buf.clamp.surface_indirect);
imageStore(ray_time_img, texel, vec4(hit.time));
imageStore(ray_radiance_img, texel, vec4(radiance, 0.0));
imageStoreFast(ray_time_img, texel, vec4(hit.time));
imageStoreFast(ray_radiance_img, texel, vec4(radiance, 0.0));
}