23 #define RAY_GEN_DESCRIPTOR_SET_IDX 0
25 uniform accelerationStructureNV topLevelAS;
27 #define GLOBAL_TEXTURES_DESC_SET_IDX 2
30 #define VERTEX_BUFFER_DESC_SET_IDX 3
31 #define VERTEX_READONLY 1
34 #include "read_visbuf.glsl"
39 #define DESATURATE_ENVIRONMENT_MAP 1
41 #define RNG_PRIMARY_OFF_X 0
42 #define RNG_PRIMARY_OFF_Y 1
43 #define RNG_PRIMARY_APERTURE_X 2
44 #define RNG_PRIMARY_APERTURE_Y 3
46 #define RNG_NEE_LIGHT_SELECTION(bounce) (4 + 0 + 9 * bounce)
47 #define RNG_NEE_TRI_X(bounce) (4 + 1 + 9 * bounce)
48 #define RNG_NEE_TRI_Y(bounce) (4 + 2 + 9 * bounce)
49 #define RNG_NEE_LIGHT_TYPE(bounce) (4 + 3 + 9 * bounce)
50 #define RNG_BRDF_X(bounce) (4 + 4 + 9 * bounce)
51 #define RNG_BRDF_Y(bounce) (4 + 5 + 9 * bounce)
52 #define RNG_BRDF_FRESNEL(bounce) (4 + 6 + 9 * bounce)
53 #define RNG_SUNLIGHT_X(bounce) (4 + 7 + 9 * bounce)
54 #define RNG_SUNLIGHT_Y(bounce) (4 + 8 + 9 * bounce)
56 #define PRIMARY_RAY_CULL_MASK (AS_FLAG_EVERYTHING & ~(AS_FLAG_VIEWER_MODELS | AS_FLAG_CUSTOM_SKY))
57 #define REFLECTION_RAY_CULL_MASK (AS_FLAG_OPAQUE | AS_FLAG_PARTICLES | AS_FLAG_EXPLOSIONS | AS_FLAG_SKY)
58 #define BOUNCE_RAY_CULL_MASK (AS_FLAG_OPAQUE | AS_FLAG_SKY | AS_FLAG_CUSTOM_SKY)
59 #define SHADOW_RAY_CULL_MASK (AS_FLAG_OPAQUE)
62 #define NUM_RNG_PER_FRAME (RNG_NEE_STATIC_DYNAMIC(1) + 1)
64 #define BOUNCE_SPECULAR 1
66 #define MAX_OUTPUT_VALUE 1000
68 #define RT_PAYLOAD_SHADOW 0
69 #define RT_PAYLOAD_BRDF 1
83 direction = (global_ubo.environment_rotation_matrix * vec4(direction, 0)).xyz;
85 vec3 envmap = vec3(0);
88 envmap = textureLod(TEX_PHYSICAL_SKY, direction.xzy, 0).rgb;
93 envmap = min(envmap, vec3((1 - dot(direction, global_ubo.sun_direction_envmap)) * 200));
98 envmap = textureLod(TEX_ENVMAP, direction.xzy, 0).rgb;
99 #if DESATURATE_ENVIRONMENT_MAP
100 float avg = (envmap.x + envmap.y + envmap.z) / 3.0;
101 envmap =
mix(envmap, avg.xxx, 0.1) * 0.5;
115 if(global_ubo.pt_swap_checkerboard != 0)
116 is_even_checkerboard = !is_even_checkerboard;
118 if (is_even_checkerboard) {
119 pos.x =
int(gl_LaunchIDNV.x * 2) +
int(gl_LaunchIDNV.y & 1);
121 pos.x =
int(gl_LaunchIDNV.x * 2 + 1) -
int(gl_LaunchIDNV.y & 1);
124 pos.y =
int(gl_LaunchIDNV.y);
130 return ivec2(global_ubo.width, global_ubo.height);
163 ? get_instanced_triangle(prim)
164 : get_bsp_triangle(prim);
172 bary.x = 1.0 - bary.y - bary.z;
183 return min(texelFetch(TEX_BLUE_NOISE, ivec3(p), 0).r, 0.9999999999999);
253 rayFlags |=gl_RayFlagsCullBackFacingTrianglesNV;
255 ray_payload_brdf.transparency = uvec2(0);
256 ray_payload_brdf.hit_distance = 0;
257 ray_payload_brdf.max_transparent_distance = 0;
259 traceNV( topLevelAS, rayFlags, instance_mask,
267 float dist = length(l);
271 ray.
origin = p1 + l * tmin;
273 ray.
t_max = dist - tmin - 0.01;
282 const uint rayFlags = gl_RayFlagsOpaqueNV | gl_RayFlagsTerminateOnFirstHitNV;
284 ray_payload_shadow.missed = 0;
286 traceNV( topLevelAS, rayFlags, cull_mask,
290 return float(ray_payload_shadow.missed);
296 ray_payload_brdf.hit_distance = -1;
302 float extinction_distance = ray.
t_max - ray.
t_min;
303 vec3 throughput = vec3(1);
309 vec3 geo_normal = triangle.normals[0];
310 bool is_vertical = abs(geo_normal.z) < 0.1;
312 if((
is_water(triangle.material_id) ||
is_slime(triangle.material_id)) && !is_vertical)
314 vec3 position = ray.
origin + ray.
direction * ray_payload_brdf.hit_distance;
315 vec3 w = get_water_normal(triangle.material_id, geo_normal, triangle.tangent, position,
true);
317 float caustic = clamp((1 - pow(clamp(1 - length(w.xz), 0, 1), 2)) * 100, 0, 8);
318 caustic =
mix(1, caustic, clamp(ray_payload_brdf.hit_distance * 0.02, 0, 1));
319 throughput = vec3(caustic);
323 extinction_distance = ray_payload_brdf.hit_distance;
332 extinction_distance = max(0, ray.
t_max - ray_payload_brdf.hit_distance);
335 else if(
is_glass(triangle.material_id) ||
is_water(triangle.material_id) && is_vertical)
338 vec2 tex_coord = triangle.tex_coords * bary;
340 MaterialInfo minfo = get_material_info(triangle.material_id);
342 vec3 albedo = global_textureLod(minfo.diffuse_texture, tex_coord, 2).rgb;
352 return extinction(surface_medium, extinction_distance) * throughput;
357 vec3 n = vec3(rgb.xy * 2 - 1, rgb.z);
360 return len > 0 ? n / len : vec3(0);
367 float effect = global_ubo.pt_toksvig * clamp(mip_level, 0, 1);
368 float shininess = RoughnessSquareToSpecPower(roughness) * effect;
369 float ft = normalMapLen /
mix(shininess, 1.0f, normalMapLen);
371 return SpecPowerToRoughnessSquare(ft * shininess / effect);
381 int shadow_cull_mask,
385 bool enable_caustics,
386 float surface_specular,
387 float direct_specular_weight,
388 bool enable_polygonal,
389 bool enable_spherical,
398 vec3 pos_on_light_polygonal;
399 vec3 pos_on_light_spherical;
401 vec3 contrib_polygonal = vec3(0);
402 vec3 contrib_spherical = vec3(0);
404 float alpha = square(roughness);
405 float phong_exp = RoughnessSquareToSpecPower(alpha);
406 float phong_scale = min(100, 1 / (M_PI * square(alpha)));
407 float phong_weight = clamp(surface_specular * direct_specular_weight, 0, 0.9);
409 int polygonal_light_index = -1;
410 float polygonal_light_area = 0;
430 pos_on_light_polygonal,
432 polygonal_light_index,
433 polygonal_light_area,
437 bool is_polygonal =
true;
446 float max_solid_angle = (bounce == 0) ? 2 * M_PI : 0.02;
453 pos_on_light_spherical,
458 float spec_polygonal = phong(normal, normalize(pos_on_light_polygonal - position), view_direction, phong_exp) * phong_scale;
459 float spec_spherical = phong(normal, normalize(pos_on_light_spherical - position), view_direction, phong_exp) * phong_scale;
461 float l_polygonal = luminance(abs(contrib_polygonal)) *
mix(1, spec_polygonal, phong_weight);
462 float l_spherical = luminance(abs(contrib_spherical)) *
mix(1, spec_spherical, phong_weight);
463 float l_sum = l_polygonal + l_spherical;
465 bool null_light = (l_sum == 0);
467 float w = null_light ? 0.5 : l_polygonal / (l_polygonal + l_spherical);
470 is_polygonal = (rng2 < w);
471 vis = is_polygonal ? (1 / w) : (1 / (1 - w));
472 vec3 pos_on_light = null_light ? position : (is_polygonal ? pos_on_light_polygonal : pos_on_light_spherical);
473 vec3 contrib = is_polygonal ? contrib_polygonal : contrib_spherical;
475 Ray shadow_ray =
get_shadow_ray(position - view_direction * 0.001, pos_on_light, 0);
478 #ifdef ENABLE_SHADOW_CAUSTICS
501 if(global_ubo.pt_light_stats != 0
504 && polygonal_light_index >= 0
505 && polygonal_light_index < global_ubo.num_static_lights)
511 if(vis == 0) addr += 1;
520 diffuse = vis * contrib;
522 if(is_polygonal && direct_specular_weight > 0)
528 direct_specular_weight *= 1.0 - smoothstep(
529 global_ubo.pt_direct_area_threshold,
530 global_ubo.pt_direct_area_threshold * 2,
531 polygonal_light_area);
534 if(vis > 0 && direct_specular_weight > 0)
536 specular = diffuse * (GGX(view_direction, normalize(pos_on_light - position), normal, roughness, 0.0) * direct_specular_weight);
539 vec3
L = pos_on_light - position;
542 float NdotL = max(0, dot(normal,
L));
544 diffuse *= NdotL / M_PI;
557 bool enable_caustics,
560 int shadow_cull_mask)
565 if(global_ubo.sun_visible == 0)
568 bool visible = (cluster_idx == ~0u) || (get_sky_visibility(cluster_idx >> 5) & (1 << (cluster_idx & 31))) != 0;
575 disk.xy *= global_ubo.sun_tan_half_angle;
577 vec3 direction = normalize(global_ubo.sun_direction + global_ubo.sun_tangent * disk.x + global_ubo.sun_bitangent * disk.y);
579 float NdotL = dot(direction, normal);
580 float GNdotL = dot(direction, geo_normal);
582 if(NdotL <= 0 || GNdotL <= 0)
585 Ray shadow_ray =
get_shadow_ray(position - view_direction * 0.001, position + direction * 10000, 0);
592 #ifdef ENABLE_SUN_SHAPE
597 vec3 envmap_direction = (global_ubo.environment_rotation_matrix * vec4(direction, 0)).xyz;
599 vec3 envmap = textureLod(TEX_PHYSICAL_SKY, envmap_direction.xzy, 0).rgb;
601 diffuse = (global_ubo.sun_solid_angle * global_ubo.pt_env_scale) * envmap;
605 diffuse = sun_color_ubo.sun_color;
608 #ifdef ENABLE_SHADOW_CAUSTICS
615 if(global_ubo.pt_sun_specular > 0)
617 float NoH_offset = 0.5 * square(global_ubo.sun_tan_half_angle);
618 specular = diffuse * GGX(view_direction, global_ubo.sun_direction, normal, roughness, NoH_offset);
621 diffuse *= NdotL / M_PI;
626 if(any(isnan(
c)) || any(isinf(
c)))
635 if (minfo.emissive_texture != 0)
639 image3 = global_textureLod(minfo.emissive_texture, tex_coord, mip_level);
641 image3 = global_textureGrad(minfo.emissive_texture, tex_coord, tex_coord_x, tex_coord_y);
645 return corrected * minfo.emissive_scale;
666 return uv.xy + sin(fract(uv.yx * 0.5 + global_ubo.time * 20 / 128) * 2 * M_PI) * 0.125;
682 if(tonemap_buffer.adapted_luminance > 0)
683 c.rgb *= tonemap_buffer.adapted_luminance * 100;
690 if(global_ubo.flt_enable != 0)
692 uint u = texelFetch(TEX_ASVGF_GRAD_SMPL_POS_A, ipos /
GRAD_DWN, 0).r;
694 ivec2 grad_strata_pos = ivec2(
695 u >> (STRATUM_OFFSET_SHIFT * 0),
696 u >> (STRATUM_OFFSET_SHIFT * 1)) & STRATUM_OFFSET_MASK;
698 return (u > 0 && all(equal(grad_strata_pos, ipos %
GRAD_DWN)));
706 get_material(Triangle triangle, vec2 tex_coord, vec2 tex_coord_x, vec2 tex_coord_y,
float mip_level, vec3 geo_normal,
707 out vec3 albedo, out vec3 normal, out
float metallic, out
float specular, out
float roughness, out vec3 emissive)
711 tex_coord.x -= global_ubo.time * 0.5;
720 MaterialInfo minfo = get_material_info(triangle.material_id);
725 image1 = global_textureLod(minfo.diffuse_texture, tex_coord, mip_level);
727 image1 = global_textureGrad(minfo.diffuse_texture, tex_coord, tex_coord_x, tex_coord_y);
739 if (minfo.normals_texture != 0)
743 image2 = global_textureLod(minfo.normals_texture, tex_coord, mip_level);
745 image2 = global_textureGrad(minfo.normals_texture, tex_coord, tex_coord_x, tex_coord_y);
748 vec3 local_normal =
rgbToNormal(image2.rgb, normalMapLen);
750 if(dot(triangle.tangent, triangle.tangent) > 0)
752 vec3 tangent = triangle.tangent,
753 bitangent = cross(geo_normal, tangent);
756 bitangent = -bitangent;
758 normal = tangent * local_normal.x + bitangent * local_normal.y + geo_normal * local_normal.z;
760 float bump_scale = global_ubo.pt_bump_scale * minfo.bump_scale;
764 normal = normalize(
mix(geo_normal, normal, bump_scale));
767 metallic = clamp(image2.a * minfo.specular_scale, 0, 1);
769 if(minfo.roughness_override >= 0)
770 roughness = max(image1.a, minfo.roughness_override);
772 roughness = image1.a;
774 roughness = clamp(roughness, 0, 1);
776 float effective_mip = mip_level;
778 if (effective_mip < 0)
780 ivec2 texSize = global_textureSize(minfo.normals_texture, 0);
781 vec2 tx = tex_coord_x * texSize;
782 vec2 ty = tex_coord_y * texSize;
783 float d = max(dot(tx, tx), dot(ty, ty));
784 effective_mip = 0.5 * log2(d);
789 if (normalMapLen > 0 && global_ubo.pt_toksvig > 0 && effective_mip > 0 && !is_mirror)
795 if(global_ubo.pt_roughness_override >= 0) roughness = global_ubo.pt_roughness_override;
796 if(global_ubo.pt_metallic_override >= 0) metallic = global_ubo.pt_metallic_override;
798 specular =
mix(0.05, 1.0, metallic);
800 emissive =
sample_emissive_texture(triangle.material_id, minfo, tex_coord, tex_coord_x, tex_coord_y, mip_level);
807 const vec2 minUV = vec2(11.0 / 256.0, 14.0 / 256.0);
808 const vec2 maxUV = vec2(245.0 / 256.0, 148.0 / 256.0);
810 tex_coord = fract(tex_coord);
811 cameraUV = (tex_coord - minUV) / (maxUV - minUV);
816 return all(greaterThan(cameraUV, vec2(0))) && all(lessThan(cameraUV, vec2(1)));