vk: bring back SURF_DRAWSKY geometries

Needed to hide invisible geometry on e.g. c5a1. Breaks de_dust2 roofs
(#474). That will need to be addressed some other way.

Still uses special value for base_color texture to signal SKY SURFACE.
A supposedly better way to do this would be to have them have a special
material.
This commit is contained in:
Ivan Avdeev 2023-09-22 10:15:34 -04:00
parent 638bd163af
commit 9ac7340974
11 changed files with 42 additions and 36 deletions

View File

@ -20,7 +20,6 @@ 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"
@ -73,6 +72,7 @@ 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,14 +149,8 @@ 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)) {
const vec3 skycolor = SRGBtoLINEAR(texture(skybox, bounce_direction).rgb);
if (brdf_type == DIFFUSE_TYPE) {
diffuse += skycolor;
} else
specular += skycolor;
if (!getHit(pos, bounce_direction, payload))
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_MISS;
return payload_shadow.hit_type != SHADOW_SKY;
#elif defined(RAY_QUERY)
rayQueryEXT rq;
@ -125,22 +125,28 @@ 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);
// Any intersection results in a shadow
// Find closest intersection, and then check whether that was a skybox
while (rayQueryProceedEXT(rq)) {}
if (rayQueryGetIntersectionTypeEXT(rq, true) == gl_RayQueryCommittedIntersectionTriangleEXT) {
return true;
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;
}
// check for alpha-masked surfaces separately
// TODO compare with doing it in the same loop as above
return shadowTestAlphaMask(pos, dir, L);
const float hit_t = rayQueryGetIntersectionTEXT(rq, true);
return shadowTestAlphaMask(pos, dir, hit_t);
#else
#error RAY_TRACE or RAY_QUERY

View File

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

View File

@ -71,6 +71,8 @@ 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,8 +24,6 @@ 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 {
@ -78,6 +76,7 @@ void main() {
;
rayQueryInitializeEXT(rq, tlas, flags, GEOMETRY_BIT_OPAQUE | GEOMETRY_BIT_ALPHA_TEST | GEOMETRY_BIT_REFRACTIVE, ray.origin, 0., ray.direction, ray.dist);
while (rayQueryProceedEXT(rq)) {
// FIXME this is a no-op. It doesn't do what I though it did. Should check for SBT index for alpha-test material instead.
if (0 != (rayQueryGetRayFlagsEXT(rq) & gl_RayFlagsOpaqueEXT))
continue;
@ -90,6 +89,7 @@ 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;
@ -105,9 +105,6 @@ 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,7 +29,10 @@ 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,14 +1,4 @@
#version 460 core
#extension GL_EXT_ray_tracing: require
#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);
}
void main() {}

View File

@ -10,6 +10,7 @@
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
@ -29,7 +30,10 @@ 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,5 +7,10 @@
layout(location = PAYLOAD_LOCATION_SHADOW) rayPayloadInEXT RayPayloadShadow payload_shadow;
void main() {
payload_shadow.hit_type = SHADOW_HIT;
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 ;
}

View File

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

View File

@ -778,13 +778,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;
}
@ -1058,11 +1058,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;
}
@ -1089,7 +1089,10 @@ static qboolean fillBrushSurfaces(fill_geometries_args_t args) {
model_geometry->index_offset = index_offset;
{
if ( type == BrushSurface_Sky ) {
#define TEX_BASE_SKYBOX 0xffffffffu // FIXME ray_interop.h
model_geometry->material.tex_base_color = TEX_BASE_SKYBOX;
} else {
ASSERT(!FBitSet( surf->flags, SURF_DRAWTILED ));
VK_CreateSurfaceLightmap( surf, args.mod );
}