ref_vk/shaders/world_warp.frag
Yamagi 4b536019c3 Add the vkQuake2 Vulkan renderer ported to YQ2.
This was first developed in a feature branch in the main yquake2 repo.
It was merged into master in early 2021, but the experiences of the
following month showed that it is not ready for prime time. There're
glitches with 3rd party assets, restarts are still shaky, etc. Having
the code in a separate repo allows us to:

  * Release Vulkan independent if YQ2.
  * Give commit access to contributors interested in Vulkan.

This code is the same as in yquake/yquake2 ecdf912713eef55d6c5d5a772259b44e3fc232c4.
2021-05-26 10:31:01 +02:00

55 lines
1.7 KiB
GLSL

#version 450
#extension GL_ARB_separate_shader_objects : enable
// Underwater screen warp effect similar to what software renderer provides.
// Pixel size to simulate lower screen resolutions is used to restore world to full screen size.
layout(push_constant) uniform PushConstant
{
layout(offset = 68) float time;
layout(offset = 72) float scale;
layout(offset = 76) float scrWidth;
layout(offset = 80) float scrHeight;
layout(offset = 84) float offsetX;
layout(offset = 88) float offsetY;
layout(offset = 92) float pixelSize;
layout(offset = 96) float refdefX;
layout(offset = 100) float refdefY;
layout(offset = 104) float refdefWidth;
layout(offset = 108) float refdefHeight;
} pc;
layout(set = 0, binding = 0) uniform sampler2D sTexture;
layout(location = 0) out vec4 fragmentColor;
#define PI 3.1415
void main()
{
vec2 scrSize = vec2(pc.scrWidth, pc.scrHeight);
vec2 fragCoord = (gl_FragCoord.xy - vec2(pc.offsetX, pc.offsetY));
vec2 uv = fragCoord / scrSize;
float xMin = pc.refdefX;
float xMax = pc.refdefX + pc.refdefWidth;
float yMin = pc.refdefY;
float yMax = pc.refdefY + pc.refdefHeight;
if (pc.time > 0 && fragCoord.x > xMin && fragCoord.x < xMax && fragCoord.y > yMin && fragCoord.y < yMax)
{
float sx = pc.scale - abs(pc.scrWidth / 2.0 - fragCoord.x) * 2.0 / pc.scrWidth;
float sy = pc.scale - abs(pc.scrHeight / 2.0 - fragCoord.y) * 2.0 / pc.scrHeight;
float xShift = 2.0 * pc.time + uv.y * PI * 10;
float yShift = 2.0 * pc.time + uv.x * PI * 10;
vec2 distortion = vec2(sin(xShift) * sx, sin(yShift) * sy) * 0.00666;
uv += distortion;
}
uv /= pc.pixelSize;
uv = clamp(uv * scrSize, vec2(0.0, 0.0), scrSize - vec2(0.5, 0.5));
fragmentColor = textureLod(sTexture, uv, 0.0);
}