quakeforge/libs/video/renderer/vulkan/shader/bsp_sky.frag
Bill Currie ff6d6f6dd6 [vulkan] Rework shaders and pipelines for bindless textures
Smashing everything in the process :P (need to work on the C side).
However, while bindless is supposedly good for performance, the biggest
gain this will bring is portability: the texture counts are
automatically limited to what the hardware can handle, and the reliance
on push descriptors is removed (though they were nice and did help get
things up and running).
2021-12-24 06:45:13 +09:00

101 lines
2.6 KiB
GLSL

#version 450
layout (constant_id = 0) const int MaxTextures = 256;
layout (constant_id = 1) const bool doSkyBox = false;
layout (constant_id = 2) const bool doSkySheet = false;
layout (set = 0, binding = 1) uniform texture2DArray sheet_tex[MaxTextures];
layout (set = 0, binding = 1) uniform textureCube cube_tex[MaxTextures];
layout (set = 0, binding = 2) uniform sampler samp;
layout (push_constant) uniform PushConstants {
layout (offset = 64)
vec4 fog;
float time;
int sheet_ind;
int cube_ind;
};
layout (location = 0) in vec4 tl_st;
layout (location = 1) in vec3 direction;
layout (location = 0) out vec4 frag_color;
const float SCALE = 189.0 / 64.0;
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, texture2DArray tex)
{
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 (sampler2DArray(tex, samp), st1);
c2 = texture (sampler2DArray(tex, samp), st2);
c = vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
return c;
}
vec4
sky_box (vec3 dir, float time, textureCube tex)
{
// 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
dir = normalize(dir);
//return vec4(dir.xyz, 1) * 0.5 + vec4(0.5);
return texture (samplerCube (tex, samp), dir.xzy);
}
vec4
sky_color (vec3 dir, float time)
{
if (!doSkySheet) {
return sky_box (dir, time, cube_tex[cube_ind]);
} if (!doSkyBox) {
return sky_sheet (dir, time, sheet_tex[sheet_ind]);
} 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, sheet_tex[sheet_ind]);
vec4 c2 = sky_box (dir, time, cube_tex[cube_ind]);
return vec4 (mix (c2.rgb, c1.rgb, c1.a), max (c1.a, c2.a));
return vec4 (1, 0, 1, 1);
}
}
void
main (void)
{
vec4 c;
if (doSkyBox || doSkySheet) {
c = sky_color (direction, time);
} else {
c = vec4 (0, 0, 0, 1);
}
frag_color = c;//fogBlend (c);
}