mirror of
https://github.com/Q3Rally-Team/rallyunlimited-engine.git
synced 2024-11-24 21:21:47 +00:00
323 lines
8.7 KiB
Cheetah
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
|
|
}
|