[vulkan] Implement direction shadow lighting

Finally, even suns cast shadows :)
This commit is contained in:
Bill Currie 2023-08-14 02:33:19 +09:00
parent 5abe467f7d
commit 70b60456a8
12 changed files with 45 additions and 23 deletions

View File

@ -697,6 +697,7 @@ properties = {
lighting_attach, lighting_shadow);
pushConstants = {
fragment = {
CascadeDepths = vec4;
queue = uint;
};
};

View File

@ -34,5 +34,5 @@ main (void)
frag_color = c;
frag_emission = e;
frag_normal = vec4(normalize(normal), 1);
frag_position = position;
frag_position = vec4 (position.xyz, gl_FragCoord.z);
}

View File

@ -43,5 +43,5 @@ main (void)
frag_color = c;//fogBlend (c);
frag_emission = e;
frag_normal = vec4 (normal, 0);
frag_position = position;
frag_position = vec4 (position.xyz, gl_FragCoord.z);
}

View File

@ -44,5 +44,5 @@ main (void)
frag_color = c;
frag_emission = vec4(0,0,0,1);//e;
frag_normal = vec4(normal,1);//vec4(tbn * n, 1);
frag_position = position;
frag_position = vec4 (position.xyz, gl_FragCoord.z);
}

View File

@ -33,3 +33,8 @@ layout (set = 1, binding = 3) buffer Style {
layout (set = 1, binding = 4) buffer LightEntIds {
uint light_entids[];
};
layout (push_constant) uniform PushConstants {
vec4 CascadeDepths;
uint queue;
};

View File

@ -5,9 +5,18 @@
layout (set = 3, binding = 0) uniform sampler2DArrayShadow shadow_map[32];
float
shadow (uint map_id, uint layer, uint mat_id, vec3 pos, vec3 lpos)
shadow (uint map_id, uint layer, uint mat_id, vec4 pos, vec3 lpos)
{
return 1;
float fd = pos.w;
uint ind = fd > CascadeDepths[1]
? fd > CascadeDepths[0] ? 0 : 1
: fd > CascadeDepths[2] ? 2 : 3;
vec4 p = shadow_mats[mat_id + ind] * vec4 (pos.xyz, 1);
p = p / p.w;
float depth = p.z;
vec2 uv = (p.xy + vec2(1)) / 2;
return texture (shadow_map[map_id], vec4 (uv, layer + ind, depth));
}
#include "lighting_main.finc"

View File

@ -5,9 +5,9 @@
layout (set = 3, binding = 0) uniform samplerCubeArrayShadow shadow_map[32];
float
shadow (uint map_id, uint layer, uint mat_id, vec3 pos, vec3 lpos)
shadow (uint map_id, uint layer, uint mat_id, vec4 pos, vec3 lpos)
{
vec3 dir = pos - lpos;
vec3 dir = pos.xyz - lpos;
vec3 adir = abs(dir);
adir = max (adir.yzx, adir.zxy);
uint ind = dir.x <= -adir.x ? 5
@ -16,7 +16,7 @@ shadow (uint map_id, uint layer, uint mat_id, vec3 pos, vec3 lpos)
: dir.y >= adir.y ? 1
: dir.z <= -adir.z ? 3
: dir.z >= adir.z ? 2 : 0;
vec4 p = shadow_mats[mat_id + ind] * vec4 (pos, 1);
vec4 p = shadow_mats[mat_id + ind] * vec4 (pos.xyz, 1);
p = p / p.w;
float depth = p.z;
// convert from the quake frame to the cubemap frame

View File

@ -5,10 +5,6 @@ layout (input_attachment_index = 3, set = 2, binding = 3) uniform subpassInput p
layout (location = 0) out vec4 frag_color;
layout (push_constant) uniform PushConstants {
uint queue;
};
float
spot_cone (LightData light, vec3 incoming)
{
@ -31,7 +27,7 @@ main (void)
vec3 c = subpassLoad (color).rgb;
vec3 e = subpassLoad (emission).rgb;
vec3 n = subpassLoad (normal).rgb;
vec3 p = subpassLoad (position).rgb;
vec4 p = subpassLoad (position);
vec3 light = vec3 (0);
uint start = bitfieldExtract (queue, 0, 16);
@ -40,7 +36,7 @@ main (void)
for (uint i = start; i < end; i++) {
uint id = lightIds[i];
LightData l = lights[id];
vec3 dir = l.position.xyz - l.position.w * p;
vec3 dir = l.position.xyz - l.position.w * p.xyz;
float r2 = dot (dir, dir);
vec4 a = l.attenuation;

View File

@ -3,7 +3,7 @@
#include "lighting.h"
float
shadow (uint mapid, uint layer, uint mat_id, vec3 pos, vec3 lpos)
shadow (uint mapid, uint layer, uint mat_id, vec4 pos, vec3 lpos)
{
return 1;
}

View File

@ -5,9 +5,9 @@
layout (set = 3, binding = 0) uniform sampler2DArrayShadow shadow_map[32];
float
shadow (uint map_id, uint layer, uint mat_id, vec3 pos, vec3 lpos)
shadow (uint map_id, uint layer, uint mat_id, vec4 pos, vec3 lpos)
{
vec4 p = shadow_mats[mat_id] * vec4 (pos, 1);
vec4 p = shadow_mats[mat_id] * vec4 (pos.xyz, 1);
p = p / p.w;
float depth = p.z;
vec2 uv = (p.xy + vec2(1)) / 2;

View File

@ -33,5 +33,5 @@ main (void)
frag_color = vec4(0,0,0,1);
frag_emission = pix;
frag_normal = vec4(normal, 1);
frag_position = position;
frag_position = vec4 (position.xyz, gl_FragCoord.z);
}

View File

@ -169,8 +169,14 @@ lighting_setup_shadow (const exprval_t **params, exprval_t *result,
auto pass = Vulkan_Bsp_GetPass (ctx, QFV_bspShadow);
auto brush = pass->brush;
lctx->world_mins = loadvec3f (brush->submodels[0].mins);
lctx->world_maxs = loadvec3f (brush->submodels[0].maxs);
if (brush->submodels) {
lctx->world_mins = loadvec3f (brush->submodels[0].mins);
lctx->world_maxs = loadvec3f (brush->submodels[0].maxs);
} else {
// FIXME better bounds
lctx->world_mins = (vec4f_t) { -512, -512, -512, 0 };
lctx->world_maxs = (vec4f_t) { 512, 512, 512, 0 };
}
set_t leafs = SET_STATIC_INIT (brush->modleafs, alloca);
set_empty (&leafs);
@ -760,10 +766,15 @@ lighting_draw_lights (const exprval_t **params, exprval_t *result,
return;
}
qfv_push_constants_t push_constants[] = {
{ VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof (queue), &queue },
//FIXME dup of z_range (sort of)
vec4f_t depths = {
r_nearclip / 32, r_nearclip / 256, r_nearclip / 1024, 0,
};
QFV_PushConstants (device, cmd, layout, 1, push_constants);
qfv_push_constants_t push_constants[] = {
{ VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof (depths), &depths },
{ VK_SHADER_STAGE_FRAGMENT_BIT, sizeof(depths), sizeof(queue), &queue },
};
QFV_PushConstants (device, cmd, layout, 2, push_constants);
dfunc->vkCmdDraw (cmd, 3, 1, 0, 0);
}