pcsx2/bin/resources/shaders/opengl/tfx_vgs.glsl

242 lines
5.2 KiB
GLSL

//#version 420 // Keep it for text editor detection
#ifdef VERTEX_SHADER
layout(location = 0) in vec2 i_st;
layout(location = 2) in vec4 i_c;
layout(location = 3) in float i_q;
layout(location = 4) in uvec2 i_p;
layout(location = 5) in uint i_z;
layout(location = 6) in uvec2 i_uv;
layout(location = 7) in vec4 i_f;
#if !defined(BROKEN_DRIVER) && defined(GL_ARB_enhanced_layouts) && GL_ARB_enhanced_layouts
layout(location = 0)
#endif
out SHADER
{
vec4 t_float;
vec4 t_int;
#if VS_IIP != 0
vec4 c;
#else
flat vec4 c;
#endif
} VSout;
const float exp_min32 = exp2(-32.0f);
void texture_coord()
{
vec2 uv = vec2(i_uv) - TextureOffset;
vec2 st = i_st - TextureOffset;
// Float coordinate
VSout.t_float.xy = st;
VSout.t_float.w = i_q;
// Integer coordinate => normalized
VSout.t_int.xy = uv * TextureScale;
#if VS_INT_FST == 1
// Some games uses float coordinate for post-processing effect
VSout.t_int.zw = st / TextureScale;
#else
// Integer coordinate => integral
VSout.t_int.zw = uv;
#endif
}
void vs_main()
{
// Clamp to max depth, gs doesn't wrap
highp uint z = min(i_z, MaxDepth);
// pos -= 0.05 (1/320 pixel) helps avoiding rounding problems (integral part of pos is usually 5 digits, 0.05 is about as low as we can go)
// example: ceil(afterseveralvertextransformations(y = 133)) => 134 => line 133 stays empty
// input granularity is 1/16 pixel, anything smaller than that won't step drawing up/left by one pixel
// example: 133.0625 (133 + 1/16) should start from line 134, ceil(133.0625 - 0.05) still above 133
vec4 p;
p.xy = vec2(i_p) - vec2(0.05f, 0.05f);
p.xy = p.xy * VertexScale - VertexOffset;
p.w = 1.0f;
p.z = float(z) * exp_min32;
gl_Position = p;
texture_coord();
VSout.c = i_c;
VSout.t_float.z = i_f.x; // pack for with texture
#if VS_POINT_SIZE
gl_PointSize = float(VS_POINT_SIZE_VALUE);
#endif
}
#endif
#ifdef GEOMETRY_SHADER
#if !defined(BROKEN_DRIVER) && defined(GL_ARB_enhanced_layouts) && GL_ARB_enhanced_layouts
layout(location = 0)
#endif
in SHADER
{
vec4 t_float;
vec4 t_int;
#if GS_IIP != 0
vec4 c;
#else
flat vec4 c;
#endif
} GSin[];
#if !defined(BROKEN_DRIVER) && defined(GL_ARB_enhanced_layouts) && GL_ARB_enhanced_layouts
layout(location = 0)
#endif
out SHADER
{
vec4 t_float;
vec4 t_int;
#if GS_IIP != 0
vec4 c;
#else
flat vec4 c;
#endif
} GSout;
struct vertex
{
vec4 t_float;
vec4 t_int;
vec4 c;
};
void out_vertex(in vec4 position, in vertex v)
{
GSout.t_float = v.t_float;
GSout.t_int = v.t_int;
// Flat output
#if GS_POINT == 1
GSout.c = GSin[0].c;
#else
GSout.c = GSin[1].c;
#endif
gl_Position = position;
gl_PrimitiveID = gl_PrimitiveIDIn;
EmitVertex();
}
#if GS_POINT == 1
layout(points) in;
#else
layout(lines) in;
#endif
layout(triangle_strip, max_vertices = 4) out;
#if GS_POINT == 1
void gs_main()
{
// Transform a point to a NxN sprite
vertex point = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);
// Get new position
vec4 lt_p = gl_in[0].gl_Position;
vec4 rb_p = gl_in[0].gl_Position + vec4(PointSize.x, PointSize.y, 0.0f, 0.0f);
vec4 lb_p = rb_p;
vec4 rt_p = rb_p;
lb_p.x = lt_p.x;
rt_p.y = lt_p.y;
out_vertex(lt_p, point);
out_vertex(lb_p, point);
out_vertex(rt_p, point);
out_vertex(rb_p, point);
EndPrimitive();
}
#elif GS_LINE == 1
void gs_main()
{
// Transform a line to a thick line-sprite
vertex left = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);
vertex right = vertex(GSin[1].t_float, GSin[1].t_int, GSin[1].c);
vec4 lt_p = gl_in[0].gl_Position;
vec4 rt_p = gl_in[1].gl_Position;
// Potentially there is faster math
vec2 line_vector = normalize(rt_p.xy - lt_p.xy);
vec2 line_normal = vec2(line_vector.y, -line_vector.x);
vec2 line_width = (line_normal * PointSize) / 2;
lt_p.xy -= line_width;
rt_p.xy -= line_width;
vec4 lb_p = gl_in[0].gl_Position + vec4(line_width, 0.0f, 0.0f);
vec4 rb_p = gl_in[1].gl_Position + vec4(line_width, 0.0f, 0.0f);
out_vertex(lt_p, left);
out_vertex(lb_p, left);
out_vertex(rt_p, right);
out_vertex(rb_p, right);
EndPrimitive();
}
#else
void gs_main()
{
// left top => GSin[0];
// right bottom => GSin[1];
vertex rb = vertex(GSin[1].t_float, GSin[1].t_int, GSin[1].c);
vertex lt = vertex(GSin[0].t_float, GSin[0].t_int, GSin[0].c);
vec4 rb_p = gl_in[1].gl_Position;
vec4 lb_p = rb_p;
vec4 rt_p = rb_p;
vec4 lt_p = gl_in[0].gl_Position;
// flat depth
lt_p.z = rb_p.z;
// flat fog and texture perspective
lt.t_float.zw = rb.t_float.zw;
// flat color
lt.c = rb.c;
// Swap texture and position coordinate
vertex lb = rb;
lb.t_float.x = lt.t_float.x;
lb.t_int.x = lt.t_int.x;
lb.t_int.z = lt.t_int.z;
lb_p.x = lt_p.x;
vertex rt = rb;
rt_p.y = lt_p.y;
rt.t_float.y = lt.t_float.y;
rt.t_int.y = lt.t_int.y;
rt.t_int.w = lt.t_int.w;
out_vertex(lt_p, lt);
out_vertex(lb_p, lb);
out_vertex(rt_p, rt);
out_vertex(rb_p, rb);
EndPrimitive();
}
#endif
#endif