mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
[vulkan] Create shanders for brush models
The fragment shader is a bit of a mini mega-shader, but I do want to try out specializations.
This commit is contained in:
parent
dacda50130
commit
c7b2843c0e
6 changed files with 169 additions and 1 deletions
|
@ -31,6 +31,7 @@ typedef struct vulkan_matrices_s {
|
|||
float *projection_2d;
|
||||
float *projection_3d;
|
||||
float *view_3d;
|
||||
float *sky_3d;
|
||||
} vulkan_matrices_t;
|
||||
|
||||
typedef struct vulkan_framebufferset_s
|
||||
|
|
|
@ -261,6 +261,10 @@ twodv_src = libs/video/renderer/vulkan/twod.vert
|
|||
twodv_c = libs/video/renderer/vulkan/twod.vert.spvc
|
||||
twodf_src = libs/video/renderer/vulkan/twod.frag
|
||||
twodf_c = libs/video/renderer/vulkan/twod.frag.spvc
|
||||
quakebspv_src = libs/video/renderer/vulkan/quakebsp.vert
|
||||
quakebspv_c = libs/video/renderer/vulkan/quakebsp.vert.spvc
|
||||
quakebspf_src = libs/video/renderer/vulkan/quakebsp.frag
|
||||
quakebspf_c = libs/video/renderer/vulkan/quakebsp.frag.spvc
|
||||
passthrough_src = libs/video/renderer/vulkan/passthrough.vert
|
||||
passthrough_c = libs/video/renderer/vulkan/passthrough.vert.spvc
|
||||
pushcolor_src = libs/video/renderer/vulkan/pushcolor.frag
|
||||
|
@ -270,6 +274,10 @@ $(twodv_c): $(twodv_src)
|
|||
|
||||
$(twodf_c): $(twodf_src)
|
||||
|
||||
$(quakebspv_c): $(quakebspv_src)
|
||||
|
||||
$(quakebspf_c): $(quakebspf_src)
|
||||
|
||||
$(passthrough_c): $(passthrough_src)
|
||||
|
||||
$(pushcolor_c): $(pushcolor_src)
|
||||
|
@ -277,6 +285,8 @@ $(pushcolor_c): $(pushcolor_src)
|
|||
vkshader_c = \
|
||||
$(twodv_c) \
|
||||
$(twodf_c) \
|
||||
$(quakebspv_c) \
|
||||
$(quakebspf_c) \
|
||||
$(passthrough_c) \
|
||||
$(pushcolor_c)
|
||||
|
||||
|
|
122
libs/video/renderer/vulkan/quakebsp.frag
Normal file
122
libs/video/renderer/vulkan/quakebsp.frag
Normal file
|
@ -0,0 +1,122 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 1) uniform sampler2D Texture;
|
||||
layout (set = 0, binding = 2) uniform sampler2D Glowmap;
|
||||
layout (set = 0, binding = 3) uniform sampler2D Lightmap;
|
||||
layout (set = 0, binding = 4) uniform samplerCube SkyCube;
|
||||
layout (set = 0, binding = 5) uniform sampler2DArray SkySheet;
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
float time;
|
||||
vec4 fog;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 tl_st;
|
||||
layout (location = 1) in vec4 color;
|
||||
layout (location = 2) out vec3 direction;
|
||||
|
||||
layout (location = 0) out vec4 frag_color;
|
||||
|
||||
layout (constant_id = 0) const bool doWarp = false;
|
||||
layout (constant_id = 1) const bool doLight = true;
|
||||
layout (constant_id = 2) const bool doSkyCube = false;
|
||||
layout (constant_id = 3) const bool doSkySheet = false;
|
||||
|
||||
const float PI = 3.14159265;
|
||||
const float SPEED = 20.0;
|
||||
const float CYCLE = 128.0;
|
||||
const float FACTOR = PI * 2.0 / CYCLE;
|
||||
const vec2 BIAS = vec2 (1.0, 1.0);
|
||||
const float SCALE = 8.0;
|
||||
|
||||
vec2
|
||||
warp_st (vec2 st, float time)
|
||||
{
|
||||
vec2 angle = st.ts * CYCLE / 2.0;
|
||||
vec2 phase = vec2 (time, time) * SPEED;
|
||||
return st + (sin ((angle + phase) * FACTOR) + BIAS) / SCALE;
|
||||
}
|
||||
|
||||
vec4
|
||||
fogBlend (vec4 color)
|
||||
{
|
||||
float az = fog.a * gl_FragCoord.z / gl_FragCoord.w;
|
||||
vec3 fog_color = fog.rgb;
|
||||
float fog_factor = exp (-az * az);
|
||||
|
||||
return vec4 (mix (fog_color.rgb, color.rgb, fog_factor), color.a);
|
||||
}
|
||||
|
||||
vec4
|
||||
sky_sheet (vec3 dir, float time)
|
||||
{
|
||||
float len;
|
||||
vec2 flow = vec2 (1.0, 1.0);
|
||||
vec2 base;
|
||||
vec3 st1, st2;
|
||||
vec4 c1, c2, c;
|
||||
|
||||
dir.z *= 3.0;
|
||||
len = dot (dir, dir);
|
||||
len = SCALE * inversesqrt (len);
|
||||
base = dir.yx * vec2(1.0, -1.0) * len;
|
||||
|
||||
st1 = vec3 (base + flow * time / 8.0, 0);
|
||||
st2 = vec3 (base + flow * time / 16.0, 1);
|
||||
|
||||
c1 = texture (SkySheet, st1);
|
||||
c2 = texture (SkySheet, st2);
|
||||
|
||||
c = vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
vec4
|
||||
sky_cube (vec3 dir, float time)
|
||||
{
|
||||
// NOTE: quake's world is right-handed with Z up and X forward, but
|
||||
// Vulkan's cube maps are left-handed with Y up and Z forward. The
|
||||
// rotation to X foward is done by the Sky matrix so all that's left
|
||||
// to do here is swizzle the Y and Z coordinates
|
||||
return texture (SkyCube, dir.xzy);
|
||||
}
|
||||
|
||||
vec4
|
||||
sky_color (vec3 dir, float time)
|
||||
{
|
||||
if (!doSkySheet) {
|
||||
return sky_cube (dir, time);
|
||||
} if (!doSkyCube) {
|
||||
return sky_sheet (dir, time);
|
||||
} else {
|
||||
// can see through the sheet (may look funny when looking down)
|
||||
// maybe have 4 sheet layers instead of 2?
|
||||
vec4 c1 = sky_sheet (dir, time);
|
||||
vec4 c2 = sky_cube (dir, time);
|
||||
return vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
vec4 c;
|
||||
vec2 t_st = tl_st.xy;
|
||||
vec2 l_st = tl_st.zw;
|
||||
|
||||
if (doWarp) {
|
||||
t_st = warp_st (t_st, time);
|
||||
}
|
||||
if (doSkyCube || doSkySheet) {
|
||||
c = sky_color (direction, time);
|
||||
} else {
|
||||
c = texture (Texture, t_st) * color;
|
||||
}
|
||||
if (doLight) {
|
||||
c *= texture (Lightmap, l_st);
|
||||
}
|
||||
c += texture (Glowmap, t_st);
|
||||
|
||||
frag_color = fogBlend (c);
|
||||
}
|
28
libs/video/renderer/vulkan/quakebsp.vert
Normal file
28
libs/video/renderer/vulkan/quakebsp.vert
Normal file
|
@ -0,0 +1,28 @@
|
|||
#version 450
|
||||
|
||||
layout (set = 0, binding = 0) uniform Matrices {
|
||||
mat4 Projection;
|
||||
mat4 View;
|
||||
mat4 Sky;
|
||||
};
|
||||
|
||||
layout (push_constant) uniform PushConstants {
|
||||
mat4 Model;
|
||||
};
|
||||
|
||||
layout (location = 0) in vec4 vertex;
|
||||
layout (location = 1) in vec4 tl_uv;
|
||||
layout (location = 2) in vec4 vcolor;
|
||||
|
||||
layout (location = 0) out vec4 tl_st;
|
||||
layout (location = 1) out vec4 color;
|
||||
layout (location = 2) out vec3 direction;
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
gl_Position = Projection * (View * (Model * vertex));
|
||||
direction = (Sky * vertex).xyz;
|
||||
tl_st = tl_uv;
|
||||
color = vcolor;
|
||||
}
|
|
@ -59,6 +59,10 @@ static
|
|||
static
|
||||
#include "libs/video/renderer/vulkan/twod.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/quakebsp.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/quakebsp.frag.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/passthrough.vert.spvc"
|
||||
static
|
||||
#include "libs/video/renderer/vulkan/pushcolor.frag.spvc"
|
||||
|
@ -72,6 +76,8 @@ typedef struct shaderdata_s {
|
|||
static shaderdata_t builtin_shaders[] = {
|
||||
{ "twod.vert", twod_vert, sizeof (twod_vert) },
|
||||
{ "twod.frag", twod_frag, sizeof (twod_frag) },
|
||||
{ "quakebsp.vert", quakebsp_vert, sizeof (quakebsp_vert) },
|
||||
{ "quakebsp.frag", quakebsp_frag, sizeof (quakebsp_frag) },
|
||||
{ "passthrough.vert", passthrough_vert, sizeof (passthrough_vert) },
|
||||
{ "pushcolor.frag", pushcolor_frag, sizeof (pushcolor_frag) },
|
||||
{}
|
||||
|
|
|
@ -134,7 +134,7 @@ Vulkan_CreateMatrices (vulkan_ctx_t *ctx)
|
|||
__auto_type mat = &ctx->matrices;
|
||||
mat->buffer_2d = QFV_CreateBuffer (device, 1 * MAT_SIZE,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
mat->buffer_3d = QFV_CreateBuffer (device, 2 * MAT_SIZE,
|
||||
mat->buffer_3d = QFV_CreateBuffer (device, 3 * MAT_SIZE,
|
||||
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||
|
||||
size_t size = 0;
|
||||
|
@ -159,6 +159,7 @@ Vulkan_CreateMatrices (vulkan_ctx_t *ctx)
|
|||
mat->projection_2d = data;
|
||||
mat->projection_3d = mat->projection_2d + offset / sizeof (float);
|
||||
mat->view_3d = mat->projection_3d + 16;
|
||||
mat->sky_3d = mat->view_3d + 16;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue