rallyunlimited-engine/code/renderervk/shaders/gen_frag.tmpl
2024-02-02 19:46:17 +03:00

323 lines
8.7 KiB
Cheetah

#version 450
#ifdef USE_TX2
#define USE_TX1
#endif
#ifdef USE_CL2
#define USE_CL1
#endif
#ifdef USE_FOG
layout(set = 1, binding = 0) uniform UBO {
// VERTEX
vec4 eyePos;
vec4 lightPos;
// VERTEX-FOG
vec4 fogDistanceVector;
vec4 fogDepthVector;
vec4 fogEyeT;
// FRAGMENT
vec4 lightColor;
vec4 fogColor;
// linear dynamic light
vec4 lightVector;
};
#endif
layout(set = 2, binding = 0) uniform sampler2D texture0;
#ifdef USE_TX1
layout(set = 3, binding = 0) uniform sampler2D texture1;
#endif
#ifdef USE_TX2
layout(set = 4, binding = 0) uniform sampler2D texture2;
#endif
#ifdef USE_FOG
layout(set = 5, binding = 0) uniform sampler2D fog_texture;
#endif
#ifdef USE_CL0_IDENT
// use fixed color from spec.constant.8
#else
layout(location = 0) in vec4 frag_color0;
#endif
#ifdef USE_CL1
layout(location = 5) in vec4 frag_color1;
#endif
#ifdef USE_CL2
layout(location = 6) in vec4 frag_color2;
#endif
layout(location = 1) centroid in vec2 frag_tex_coord0;
#ifdef USE_TX1
layout(location = 2) centroid in vec2 frag_tex_coord1;
#endif
#ifdef USE_TX2
layout(location = 3) centroid in vec2 frag_tex_coord2;
#endif
#ifdef USE_FOG
layout(location = 4) in vec2 fog_tex_coord;
#endif
#ifdef USE_DF
layout(depth_less) out float gl_FragDepth;
#else
layout(location = 0) out vec4 out_color;
#endif
#ifdef USE_ATEST
layout (constant_id = 0) const int alpha_test_func = 0;
layout (constant_id = 1) const float alpha_test_value = 0.0;
#ifdef USE_DF
layout (constant_id = 2) const float depth_fragment = 0.85;
#endif
#endif
layout (constant_id = 3) const int alpha_to_coverage = 0;
//layout (constant_id = 4) const int color_mode = 0;
//layout (constant_id = 5) const int abs_light = 0;
#if defined (USE_TX1) || defined(USE_TX2)
layout (constant_id = 6) const int tex_mode = 0; // modulate, add (identity), add(non-identity) etc
#endif
layout (constant_id = 7) const int discard_mode = 0;
#ifdef USE_CL0_IDENT
layout (constant_id = 8) const float identity_color = 1.0;
#endif
#ifdef USE_ATEST
float CorrectAlpha(float threshold, float alpha, vec2 tc)
{
ivec2 ts = textureSize(texture0, 0);
float dx = max(abs(dFdx(tc.x * float(ts.x))), 0.001);
float dy = max(abs(dFdy(tc.y * float(ts.y))), 0.001);
float dxy = max(dx, dy); // apply the smallest boost
float scale = max(1.0 / dxy, 1.0);
float ac = threshold + (alpha - threshold) * scale;
return ac;
}
#endif
void main() {
#ifdef USE_FOG
vec4 fog = texture(fog_texture, fog_tex_coord);
#endif
#ifdef USE_CL0_IDENT
vec4 color0 = texture(texture0, frag_tex_coord0) * vec4( identity_color );
#else
vec4 color0 = texture(texture0, frag_tex_coord0) * frag_color0;
#endif
vec4 base;
#if defined (USE_TX2)
#ifdef USE_CL2
// soecial blend modes for non-identity colors
if ( tex_mode == 1 || tex_mode == 2 )
{
// add
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
vec4 color2 = texture(texture2, frag_tex_coord2) * frag_color2;
base = vec4( color0.rgb + color1.rgb + color2.rgb, color0.a * color1.a * color2.a );
}
else if ( tex_mode == 3 )
{
// modulate by alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
vec4 color2 = texture(texture2, frag_tex_coord2) * frag_color2;
color0 *= color0.a;
color1 *= color1.a;
color2 *= color2.a;
base = vec4( color0.rgb + color1.rgb + color2.rgb, color0.a * color1.a * color2.a );
}
else if ( tex_mode == 4 )
{
// modulate by 1.0-alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
vec4 color2 = texture(texture2, frag_tex_coord2) * frag_color2;
color0 *= 1.0-color0.a;
color1 *= 1.0-color1.a;
color2 *= 1.0-color2.a;
base = vec4( color0.rgb + color1.rgb + color2.rgb, color0.a * color1.a * color2.a );
}
else if ( tex_mode == 5 )
{
// mix by src alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
vec4 color2 = texture(texture2, frag_tex_coord2) * frag_color2;
//base = mix( color0, color1, color1.a );
//base = mix( base, color2, color2.a );
base = mix( mix( color0, color1, color1.a ), color2, color2.a );
}
else if ( tex_mode == 6 )
{
// mix by 1-src alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
vec4 color2 = texture(texture2, frag_tex_coord2) * frag_color2;
//base = mix( color1, color0, color1.a );
//base = mix( color2, base, color2.a );
base = mix( color2, mix( color1, color0, color1.a ), color2.a );
}
else if ( tex_mode == 7 ) // 0 + 2x GLS_DSTBLEND_SRC_ALPHA | GLS_SRCBLEND_DST_COLOR
{
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
vec4 color2 = texture(texture2, frag_tex_coord2) * frag_color2;
base = (color2 + color2.a) * (color1 + color1.a) * color0;
}
else
{
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
vec4 color2 = texture(texture2, frag_tex_coord2) * frag_color2;
base = color0 * color1 * color2;
}
#else
// triple-texture blending
if ( tex_mode == 1 )
{
// add (identity)
vec4 color1 = texture(texture1, frag_tex_coord1);
vec4 color2 = texture(texture2, frag_tex_coord2);
base = vec4(color0.rgb + color1.rgb + color2.rgb, color0.a * color1.a * color2.a);
}
else if ( tex_mode == 2 )
{
// add
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color0;
vec4 color2 = texture(texture2, frag_tex_coord2) * frag_color0;
base = vec4(color0.rgb + color1.rgb + color2.rgb, color0.a * color1.a * color2.a);
}
else
{
// default case, modulate
vec4 color1 = texture(texture1, frag_tex_coord1);
vec4 color2 = texture(texture2, frag_tex_coord2);
base = color0 * color1 * color2;
}
#endif // !USE_TX2
#elif defined(USE_TX1)
#ifdef USE_CL1
// soecial blend modes for non-identity colors
if ( tex_mode == 1 || tex_mode == 2 )
{
// add
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
base = vec4( color0.rgb + color1.rgb, color0.a * color1.a );
}
else if ( tex_mode == 3 ) // 2x GLS_DSTBLEND_ONE | GLS_SRCBLEND_SRC_ALPHA
{
// modulate by alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
color0 *= color0.a;
color1 *= color1.a;
base = vec4( color0.rgb + color1.rgb, color0.a * color1.a );
}
else if ( tex_mode == 4 ) // 2x GLS_DSTBLEND_ONE | GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA
{
// modulate by 1.0-alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
color0 *= 1.0-color0.a;
color1 *= 1.0-color1.a;
base = vec4( color0.rgb + color1.rgb, color0.a * color1.a );
}
else if ( tex_mode == 5 ) // 0 + GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_SRCBLEND_SRC_ALPHA
{
// mix by src alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
base = mix( color0, color1, color1.a );
}
else if ( tex_mode == 6 ) // 0 + GLS_DSTBLEND_SRC_ALPHA | GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA
{
// mix by 1-src alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
base = mix( color1, color0, color1.a );
}
else if ( tex_mode == 7 ) // 0 + GLS_DSTBLEND_SRC_ALPHA | GLS_SRCBLEND_DST_COLOR
{
// modulate color1 by color0
// moduleta color0 by color1.alpha
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
base = (color1 + color1.a) * color0;
}
else
{
// default case, modulate
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color1;
base = color0 * color1;
}
#else
// double-texture blending
if ( tex_mode == 1 )
{
// add (identity)
vec4 color1 = texture(texture1, frag_tex_coord1);
base = vec4(color0.rgb + color1.rgb, color0.a * color1.a);
}
else if ( tex_mode == 2 )
{
// add
vec4 color1 = texture(texture1, frag_tex_coord1) * frag_color0;
base = vec4(color0.rgb + color1.rgb, color0.a * color1.a);
}
else // default case
{
// modulate
vec4 color1 = texture(texture1, frag_tex_coord1);
base = color0 * color1;
}
#endif // !USE_CL1
#endif // !USE_TX1
#ifdef USE_ATEST
if (alpha_to_coverage != 0) {
if (alpha_test_func == 1) {
base.a = base.a > 0.0 ? 1.0 : 0.0;
} else if (alpha_test_func == 2) {
base.a = CorrectAlpha(alpha_test_value, 1.0 - base.a, frag_tex_coord0);
} else if (alpha_test_func == 3) {
base.a = CorrectAlpha(alpha_test_value, base.a, frag_tex_coord0);
}
} else
// specialization: alpha-test function
if (alpha_test_func == 1) {
if (color0.a == alpha_test_value) discard;
} else if (alpha_test_func == 2) {
if (color0.a >= alpha_test_value) discard;
} else if (alpha_test_func == 3) {
if (color0.a < alpha_test_value) discard;
}
#endif
#if !defined(USE_TX1) && !defined(USE_TX2)
base = color0;
#endif
#ifdef USE_FOG
base = mix( base, fog * fogColor, fog.a );
#endif
if ( discard_mode == 1 ) {
if ( base.a == 0.0 ) {
discard;
}
} else if ( discard_mode == 2 ) {
if ( dot( base.rgb, base.rgb ) == 0.0 ) {
discard;
}
}
#ifdef USE_DF
if ( base.a < depth_fragment )
discard;
gl_FragDepth = gl_FragCoord.z;
#else
out_color = base;
#endif
}