vk: remove special SURF_DRAWSKY handling

1. Completely remove them from geometries
2. Draw skybox where the ray hasn't hit anything
3. In the same fashion sky is not shadowed when there's nothing hit by
   the shadow ray.

This allows completely removing the sky material flag.
Also supposedly fixes #474
This commit is contained in:
Ivan Avdeev 2023-09-21 12:53:17 -04:00
parent cd4014766b
commit dce0598962
13 changed files with 36 additions and 49 deletions

View File

@ -20,6 +20,7 @@ RAY_LIGHT_DIRECT_INPUTS(X)
layout(set=0, binding=20, rgba16f) uniform writeonly image2D out_indirect_diffuse;
layout(set=0, binding=21, rgba16f) uniform writeonly image2D out_indirect_specular;
layout(set=0, binding=27) uniform samplerCube skybox;
#include "ray_primary_common.glsl"
#include "ray_primary_hit.glsl"
@ -72,7 +73,6 @@ bool getHit(vec3 origin, vec3 direction, inout RayPayloadPrimary payload) {
// 2. Same as the above, but also with a completely independent TLAS. Why: no need to mask-check geometry for opaque-vs-alpha
const MiniGeometry geom = readCandidateMiniGeometry(rq);
const uint tex_base_color = getKusok(geom.kusok_index).material.tex_base_color;
// Should never happen: skybox is opaque if (tex_base_color == TEX_BASE_SKYBOX)
const vec4 texture_color = texture(textures[nonuniformEXT(tex_base_color)], geom.uv);
const float alpha_mask_threshold = .1f;
@ -149,8 +149,14 @@ void computeBounce(ivec2 pix, vec3 direction, out vec3 diffuse, out vec3 specula
payload.base_color_a = vec4(0.);
payload.emissive = vec4(0.);
const vec3 pos = imageLoad(position_t, pix).xyz + geometry_normal * ray_normal_fudge;
if (!getHit(pos, bounce_direction, payload))
if (!getHit(pos, bounce_direction, payload)) {
const vec3 skycolor = SRGBtoLINEAR(texture(skybox, bounce_direction).rgb);
if (brdf_type == DIFFUSE_TYPE) {
diffuse += skycolor;
} else
specular += skycolor;
return;
}
throughput *= payload.base_color_a.rgb;

View File

@ -117,7 +117,7 @@ bool shadowedSky(vec3 pos, vec3 dir) {
| gl_RayFlagsSkipClosestHitShaderEXT
;
const uint hit_type = traceShadowRay(pos, dir, dist, flags);
return payload_shadow.hit_type != SHADOW_SKY;
return payload_shadow.hit_type != SHADOW_MISS;
#elif defined(RAY_QUERY)
rayQueryEXT rq;
@ -125,28 +125,22 @@ bool shadowedSky(vec3 pos, vec3 dir) {
// Culling for shadows breaks more things (e.g. de_cbble slightly off the ground boxes) than it probably fixes. Keep it turned off.
//| gl_RayFlagsCullFrontFacingTrianglesEXT
| gl_RayFlagsOpaqueEXT
//| gl_RayFlagsTerminateOnFirstHitEXT
| gl_RayFlagsTerminateOnFirstHitEXT
//| gl_RayFlagsSkipClosestHitShaderEXT
;
const float L = 10000.; // TODO Why 10k?
rayQueryInitializeEXT(rq, tlas, flags, GEOMETRY_BIT_OPAQUE, pos, 0., dir, L);
// Find closest intersection, and then check whether that was a skybox
// Any intersection results in a shadow
while (rayQueryProceedEXT(rq)) {}
if (rayQueryGetIntersectionTypeEXT(rq, true) == gl_RayQueryCommittedIntersectionTriangleEXT) {
const uint instance_kusochki_offset = rayQueryGetIntersectionInstanceCustomIndexEXT(rq, true);
const uint geometry_index = rayQueryGetIntersectionGeometryIndexEXT(rq, true);
const uint kusok_index = instance_kusochki_offset + geometry_index;
const Kusok kusok = getKusok(kusok_index);
if (kusok.material.tex_base_color != TEX_BASE_SKYBOX)
return true;
return true;
}
// check for alpha-masked surfaces separately
const float hit_t = rayQueryGetIntersectionTEXT(rq, true);
return shadowTestAlphaMask(pos, dir, hit_t);
// TODO compare with doing it in the same loop as above
return shadowTestAlphaMask(pos, dir, L);
#else
#error RAY_TRACE or RAY_QUERY

View File

@ -23,7 +23,6 @@ struct RayPayloadOpaque {
#define SHADOW_MISS 0
#define SHADOW_HIT 1
#define SHADOW_SKY 2
struct RayPayloadShadow {
uint hit_type;

View File

@ -71,8 +71,6 @@ LIST_SPECIALIZATION_CONSTANTS(DECLARE_SPECIALIZATION_CONSTANT)
#define MATERIAL_MODE_BLEND_GLOW 5
#define MATERIAL_MODE_COUNT 6
#define TEX_BASE_SKYBOX 0xffffffffu
struct Material {
uint tex_base_color;

View File

@ -24,6 +24,8 @@ RAY_PRIMARY_OUTPUTS(X)
layout(set = 0, binding = 1) uniform accelerationStructureEXT tlas;
layout(set = 0, binding = 7) uniform samplerCube skybox;
#include "trace_simple_blending.glsl"
struct Ray {
@ -88,7 +90,6 @@ void main() {
// 2. Same as the above, but also with a completely independent TLAS. Why: no need to mask-check geometry for opaque-vs-alpha
const MiniGeometry geom = readCandidateMiniGeometry(rq);
const uint tex_base_color = getKusok(geom.kusok_index).material.tex_base_color;
// Should never happen: skybox is opaque if (tex_base_color == TEX_BASE_SKYBOX)
const vec4 texture_color = texture(textures[nonuniformEXT(tex_base_color)], geom.uv);
const float alpha_mask_threshold = .1f;
@ -104,6 +105,9 @@ void main() {
//debug_geometry_index = rayQueryGetIntersectionPrimitiveIndexEXT(rq, true);
primaryRayHit(rq, payload);
L = rayQueryGetIntersectionTEXT(rq, true);
} else {
payload.hit_t = payload.prev_pos_t = vec4(ray.origin + ray.direction * ray.dist, ray.dist);
payload.emissive.rgb = SRGBtoLINEAR(texture(skybox, ray.direction).rgb);
}
traceSimpleBlending(ray.origin, ray.direction, L, payload.emissive.rgb, payload.base_color_a.rgb);

View File

@ -29,10 +29,7 @@ void main() {
const Kusok kusok = getKusok(geom.kusok_index);
if (kusok.material.tex_base_color == TEX_BASE_SKYBOX) {
payload.emissive.rgb = SRGBtoLINEAR(texture(skybox, gl_WorldRayDirectionEXT).rgb);
return;
} else {
{
const vec4 color = getModelHeader(gl_InstanceID).color * kusok.material.base_color;
payload.base_color_a = sampleTexture(kusok.material.tex_base_color, geom.uv, geom.uv_lods) * color;
payload.material_rmxx.r = sampleTexture(kusok.material.tex_roughness, geom.uv, geom.uv_lods).r * kusok.material.roughness;

View File

@ -1,4 +1,14 @@
#version 460 core
#extension GL_EXT_ray_tracing: require
void main() {}
#include "ray_primary_common.glsl"
#include "color_spaces.glsl"
layout(set = 0, binding = 7) uniform samplerCube skybox;
layout(location = PAYLOAD_LOCATION_PRIMARY) rayPayloadEXT RayPayloadPrimary payload;
void main() {
// TODO payload.prev_pos_t = payload.hit_t = vec4(geom.pos, gl_HitTEXT);
payload.emissive.rgb = SRGBtoLINEAR(texture(skybox, gl_WorldRayDirectionEXT).rgb);
}

View File

@ -10,7 +10,6 @@
layout(set = 0, binding = 6) uniform sampler2D textures[MAX_TEXTURES];
layout(set = 0, binding = 2) uniform UBO { UniformBuffer ubo; } ubo;
layout(set = 0, binding = 7) uniform samplerCube skybox;
vec4 sampleTexture(uint tex_index, vec2 uv, vec4 uv_lods) {
#ifndef RAY_BOUNCE
@ -30,10 +29,7 @@ void primaryRayHit(rayQueryEXT rq, inout RayPayloadPrimary payload) {
const Kusok kusok = getKusok(geom.kusok_index);
const Material material = kusok.material;
if (kusok.material.tex_base_color == TEX_BASE_SKYBOX) {
payload.emissive.rgb = SRGBtoLINEAR(texture(skybox, rayDirection).rgb);
return;
} else {
{
payload.base_color_a = sampleTexture(material.tex_base_color, geom.uv, geom.uv_lods);
payload.material_rmxx.r = sampleTexture(material.tex_roughness, geom.uv, geom.uv_lods).r * material.roughness;
payload.material_rmxx.g = sampleTexture(material.tex_metalness, geom.uv, geom.uv_lods).r * material.metalness;

View File

@ -7,10 +7,5 @@
layout(location = PAYLOAD_LOCATION_SHADOW) rayPayloadInEXT RayPayloadShadow payload_shadow;
void main() {
const int instance_kusochki_offset = gl_InstanceCustomIndexEXT;
const int kusok_index = instance_kusochki_offset + gl_GeometryIndexEXT;
const Kusok kusok = getKusok(kusok_index);
const uint tex_base_color = kusok.material.tex_base_color;
payload_shadow.hit_type = (kusok.material.tex_base_color != TEX_BASE_SKYBOX) ? SHADOW_HIT : SHADOW_SKY ;
payload_shadow.hit_type = SHADOW_HIT;
}

View File

@ -3,7 +3,6 @@
#define SHADOW_MISS 0
#define SHADOW_HIT 1
#define SHADOW_SKY 2
struct RayPayloadShadow {
uint hit_type;

View File

@ -779,13 +779,13 @@ static model_sizes_t computeSizes( const model_t *mod ) {
case BrushSurface_Water:
sizes.water_surfaces++;
addWarpVertIndCounts(surf, &sizes.water_vertices, &sizes.water_indices);
case BrushSurface_Sky:
case BrushSurface_Hidden:
continue;
case BrushSurface_Animated:
sizes.animated_count++;
case BrushSurface_Regular:
case BrushSurface_Sky:
break;
}
@ -1059,11 +1059,11 @@ static qboolean fillBrushSurfaces(fill_geometries_args_t args) {
switch (type) {
case BrushSurface_Water:
case BrushSurface_Hidden:
case BrushSurface_Sky:
continue;
case BrushSurface_Animated:
args.bmodel->animated_indexes[animated_count++] = num_geometries;
case BrushSurface_Regular:
case BrushSurface_Sky:
break;
}
@ -1090,9 +1090,7 @@ static qboolean fillBrushSurfaces(fill_geometries_args_t args) {
model_geometry->index_offset = index_offset;
if(type == BrushSurface_Sky) {
model_geometry->material_type_deprecated = kXVkMaterialSky;
} else {
{
model_geometry->material_type_deprecated = kXVkMaterialRegular;
ASSERT(!FBitSet( surf->flags, SURF_DRAWTILED ));
VK_CreateSurfaceLightmap( surf, args.mod );

View File

@ -61,10 +61,6 @@ static void applyMaterialToKusok(vk_kusok_data_t* kusok, const vk_render_geometr
const qboolean HACK_chrome = geom->material_type_deprecated == kXVkMaterialChrome;
if (!mat->set && HACK_chrome)
kusok->material.tex_roughness = tglob.grayTexture;
// Purely static. Once a sky forever a sky.
if (geom->material_type_deprecated == kXVkMaterialSky)
kusok->material.tex_base_color = TEX_BASE_SKYBOX;
}
// TODO utilize uploadKusochki([1]) to avoid 2 copies of staging code

View File

@ -19,11 +19,6 @@ void VK_RenderSetupCamera( const struct ref_viewpass_s *rvp );
typedef enum {
kXVkMaterialRegular = 0,
// Set for SURF_DRAWSKY surfaces in vk_brush.c.
// Used: for setting TEX_BASE_SKYBOX for skybox texture sampling and environment shadows.
// Remove: pass it as a special texture/material index (e.g. -2).
kXVkMaterialSky,
// Set for chrome studio submodels.
// Used: ray tracing sets gray roughness texture to get smooth surface look.
// Remove: Have an explicit material for chrome surfaces.