2020-01-01 20:41:04 +00:00
|
|
|
uniforms
|
|
|
|
{
|
|
|
|
mat4 world;
|
|
|
|
mat4 view;
|
|
|
|
mat4 projection;
|
|
|
|
mat4 modelnormal;
|
|
|
|
vec4 campos;
|
|
|
|
|
|
|
|
vec4 highlightcolor;
|
|
|
|
vec4 stencilColor;
|
|
|
|
float desaturation;
|
|
|
|
|
|
|
|
vec4 fogsettings;
|
|
|
|
vec4 fogcolor;
|
2020-01-03 01:22:33 +00:00
|
|
|
vec4 sectorfogcolor;
|
2020-01-01 20:41:04 +00:00
|
|
|
vec4 vertexColor;
|
|
|
|
|
|
|
|
sampler2D texture1;
|
|
|
|
|
|
|
|
// dynamic light related
|
2020-01-03 01:22:33 +00:00
|
|
|
vec4 lightPosAndRadius[64];
|
|
|
|
vec4 lightOrientation[64]; // this is a vector that points in light's direction
|
|
|
|
vec2 light2Radius[64]; // this is used with spotlights
|
|
|
|
vec4 lightColor[64];
|
2020-01-03 01:55:34 +00:00
|
|
|
float ignoreNormals;
|
2020-01-03 01:22:33 +00:00
|
|
|
float lightsEnabled;
|
|
|
|
|
2020-01-04 21:15:13 +00:00
|
|
|
// Slope handle length
|
|
|
|
float slopeHandleLength;
|
|
|
|
|
2020-01-01 20:41:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
functions
|
|
|
|
{
|
|
|
|
// This adds fog color to current pixel color
|
|
|
|
vec4 getFogColor(vec3 PosW, vec4 color)
|
|
|
|
{
|
|
|
|
float fogdist = max(16.0, distance(PosW, campos.xyz));
|
|
|
|
float fogfactor = exp2(campos.w * fogdist);
|
|
|
|
|
2020-01-03 01:22:33 +00:00
|
|
|
color.rgb = mix(sectorfogcolor.rgb, color.rgb, fogfactor);
|
2020-01-01 20:41:04 +00:00
|
|
|
return color;
|
|
|
|
}
|
|
|
|
|
|
|
|
vec4 desaturate(vec4 texel)
|
|
|
|
{
|
|
|
|
float gray = (texel.r * 0.3 + texel.g * 0.56 + texel.b * 0.14);
|
|
|
|
return vec4(mix(texel.rgb, vec3(gray), desaturation), texel.a);
|
|
|
|
}
|
2020-01-03 01:22:33 +00:00
|
|
|
|
|
|
|
vec3 getOneDynLightContribution(vec3 PosW, vec3 Normal, vec3 light, vec4 lColor, vec4 lPosAndRadius, vec4 lOrientation, vec2 l2Radius)
|
|
|
|
{
|
|
|
|
|
|
|
|
//is face facing away from light source?
|
|
|
|
// update 01.02.2017: offset the equation by 3px back to try to emulate GZDoom's broken visibility check.
|
|
|
|
float diffuseContribution = dot(Normal, normalize(lPosAndRadius.xyz - PosW + Normal * 3.0));
|
2020-01-03 01:55:34 +00:00
|
|
|
if (diffuseContribution < 0.0 && (ignoreNormals == 0 || (lColor.a > 0.979 && lColor.a < 0.981))) // attenuated light and facing away
|
2020-01-03 01:22:33 +00:00
|
|
|
return light;
|
|
|
|
|
|
|
|
diffuseContribution = max(diffuseContribution, 0.0); // to make sure
|
|
|
|
|
|
|
|
//is pixel in light range?
|
|
|
|
float dist = distance(PosW, lPosAndRadius.xyz);
|
|
|
|
|
|
|
|
if (dist > lPosAndRadius.w)
|
|
|
|
return light;
|
|
|
|
|
|
|
|
float power = 1.0;
|
|
|
|
power *= max(lPosAndRadius.w - dist, 0.0) / lPosAndRadius.w;
|
|
|
|
|
|
|
|
if (lOrientation.w > 0.5)
|
|
|
|
{
|
|
|
|
vec3 lightDirection = normalize(lPosAndRadius.xyz - PosW);
|
|
|
|
float cosDir = dot(lightDirection, lOrientation.xyz);
|
|
|
|
float df = smoothstep(l2Radius.y, l2Radius.x, cosDir);
|
|
|
|
power *= df;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lColor.a > 0.979 && lColor.a < 0.981) // attenuated light 98%
|
|
|
|
power *= diffuseContribution;
|
|
|
|
|
|
|
|
// for w/e reason GZDoom also does this
|
|
|
|
power *= lColor.a;
|
|
|
|
|
|
|
|
if (lColor.a >= 1)
|
|
|
|
return light.rgb - lColor.rgb * power;
|
|
|
|
|
|
|
|
return light.rgb + lColor.rgb * power;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
vec4 getDynLightContribution(vec4 tcolor, vec4 baselight, vec3 PosW, vec3 Normal)
|
|
|
|
{
|
|
|
|
vec3 light = vec3(0, 0, 0);
|
|
|
|
vec3 addlight = vec3(0, 0, 0);
|
|
|
|
|
|
|
|
if (lightsEnabled != 0)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < 64; i++)
|
|
|
|
{
|
|
|
|
if (lightColor[i].a == 0)
|
|
|
|
break;
|
|
|
|
if (lightColor[i].a < 0.4) // additive
|
|
|
|
addlight = getOneDynLightContribution(PosW, Normal, addlight, lightColor[i], lightPosAndRadius[i], lightOrientation[i], light2Radius[i]);
|
|
|
|
else light = getOneDynLightContribution(PosW, Normal, light, lightColor[i], lightPosAndRadius[i], lightOrientation[i], light2Radius[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return vec4(tcolor.rgb*(baselight.rgb+light)+addlight, tcolor.a*baselight.a);
|
|
|
|
}
|
2020-01-01 20:41:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_main
|
|
|
|
{
|
|
|
|
in
|
|
|
|
{
|
|
|
|
vec3 Position;
|
|
|
|
vec4 Color;
|
|
|
|
vec2 TextureCoordinate;
|
|
|
|
vec3 Normal;
|
|
|
|
}
|
2020-01-03 01:22:33 +00:00
|
|
|
|
2020-01-01 20:41:04 +00:00
|
|
|
v2f
|
|
|
|
{
|
|
|
|
vec4 Color;
|
|
|
|
vec2 UV;
|
2020-01-03 01:22:33 +00:00
|
|
|
vec3 PosW;
|
|
|
|
vec3 Normal;
|
2020-01-01 20:41:04 +00:00
|
|
|
vec4 viewpos;
|
|
|
|
}
|
2020-01-03 01:22:33 +00:00
|
|
|
|
2020-01-01 20:41:04 +00:00
|
|
|
out
|
|
|
|
{
|
|
|
|
vec4 FragColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
vertex
|
|
|
|
{
|
2020-01-03 01:22:33 +00:00
|
|
|
v2f.viewpos = view * world * vec4(in.Position, 1.0);
|
|
|
|
gl_Position = projection * v2f.viewpos;
|
|
|
|
v2f.PosW = (world * vec4(in.Position, 1.0)).xyz;
|
|
|
|
v2f.Color = in.Color;
|
|
|
|
v2f.UV = in.TextureCoordinate;
|
|
|
|
v2f.Normal = normalize((modelnormal * vec4(in.Normal, 1.0)).xyz);
|
2020-01-01 20:41:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fragment
|
|
|
|
{
|
|
|
|
vec4 tcolor = texture(texture1, v2f.UV);
|
|
|
|
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
2020-01-03 01:22:33 +00:00
|
|
|
tcolor = getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal);
|
|
|
|
out.FragColor = desaturate(tcolor);
|
2020-01-01 20:41:04 +00:00
|
|
|
|
|
|
|
#if defined(ALPHA_TEST)
|
|
|
|
if (out.FragColor.a < 0.5) discard;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_fullbright extends world3d_main
|
|
|
|
{
|
|
|
|
fragment
|
|
|
|
{
|
|
|
|
vec4 tcolor = texture(texture1, v2f.UV);
|
|
|
|
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
|
|
|
tcolor.a *= v2f.Color.a;
|
|
|
|
out.FragColor = tcolor;
|
|
|
|
|
|
|
|
#if defined(ALPHA_TEST)
|
|
|
|
if (out.FragColor.a < 0.5) discard;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_main_highlight extends world3d_main
|
|
|
|
{
|
|
|
|
fragment
|
|
|
|
{
|
|
|
|
vec4 tcolor = texture(texture1, v2f.UV);
|
|
|
|
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
2020-01-03 01:22:33 +00:00
|
|
|
tcolor = getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal);
|
2020-01-01 20:41:04 +00:00
|
|
|
if (tcolor.a == 0.0)
|
|
|
|
{
|
|
|
|
out.FragColor = tcolor;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Blend texture color and vertex color
|
2020-01-03 01:22:33 +00:00
|
|
|
vec4 ncolor = desaturate(tcolor);
|
2020-01-01 20:41:04 +00:00
|
|
|
|
|
|
|
out.FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4 * highlightcolor.a), max(v2f.Color.a + 0.25, 0.5));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(ALPHA_TEST)
|
|
|
|
if (out.FragColor.a < 0.5) discard;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_fullbright_highlight extends world3d_fullbright
|
|
|
|
{
|
|
|
|
fragment
|
|
|
|
{
|
|
|
|
vec4 tcolor = texture(texture1, v2f.UV);
|
|
|
|
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
|
|
|
if(tcolor.a == 0.0)
|
|
|
|
{
|
|
|
|
out.FragColor = tcolor;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Blend texture color and vertex color
|
|
|
|
vec4 ncolor = tcolor * v2f.Color;
|
|
|
|
|
|
|
|
out.FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (tcolor.rgb - 0.4 * highlightcolor.a), max(v2f.Color.a + 0.25, 0.5));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(ALPHA_TEST)
|
|
|
|
if (out.FragColor.a < 0.5) discard;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_vertex_color extends world3d_main
|
|
|
|
{
|
|
|
|
fragment
|
|
|
|
{
|
|
|
|
out.FragColor = v2f.Color;
|
|
|
|
|
|
|
|
#if defined(ALPHA_TEST)
|
|
|
|
if (out.FragColor.a < 0.5) discard;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_main_vertexcolor extends world3d_main
|
|
|
|
{
|
|
|
|
vertex
|
|
|
|
{
|
|
|
|
v2f.viewpos = view * world * vec4(in.Position, 1.0);
|
|
|
|
gl_Position = projection * v2f.viewpos;
|
|
|
|
v2f.Color = vertexColor;
|
|
|
|
v2f.UV = in.TextureCoordinate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_constant_color extends world3d_main_vertexcolor
|
|
|
|
{
|
|
|
|
fragment
|
|
|
|
{
|
|
|
|
out.FragColor = vertexColor;
|
|
|
|
|
|
|
|
#if defined(ALPHA_TEST)
|
|
|
|
if (out.FragColor.a < 0.5) discard;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (fogsettings.x >= 0.0f) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// world3d_main_highlight with vertex program from world3d_vertexcolor
|
|
|
|
// to-do: rewrite into a function
|
|
|
|
shader world3d_highlight_vertexcolor extends world3d_main_highlight
|
|
|
|
{
|
|
|
|
vertex
|
|
|
|
{
|
|
|
|
v2f.viewpos = view * world * vec4(in.Position, 1.0);
|
|
|
|
gl_Position = projection * v2f.viewpos;
|
|
|
|
v2f.Color = vertexColor;
|
|
|
|
v2f.UV = in.TextureCoordinate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-03 01:22:33 +00:00
|
|
|
shader world3d_main_fog extends world3d_main
|
2020-01-01 20:41:04 +00:00
|
|
|
{
|
|
|
|
fragment
|
|
|
|
{
|
|
|
|
vec4 tcolor = texture(texture1, v2f.UV);
|
|
|
|
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
2020-01-03 01:22:33 +00:00
|
|
|
tcolor = getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal);
|
2020-01-01 20:41:04 +00:00
|
|
|
if (tcolor.a == 0.0)
|
|
|
|
{
|
|
|
|
out.FragColor = tcolor;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-01-03 01:22:33 +00:00
|
|
|
out.FragColor = desaturate(getFogColor(v2f.PosW, tcolor));
|
2020-01-01 20:41:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(ALPHA_TEST)
|
|
|
|
if (out.FragColor.a < 0.5) discard;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_main_highlight_fog extends world3d_main_fog
|
|
|
|
{
|
|
|
|
fragment
|
|
|
|
{
|
|
|
|
vec4 tcolor = texture(texture1, v2f.UV);
|
|
|
|
tcolor = mix(tcolor, vec4(stencilColor.rgb, tcolor.a), stencilColor.a);
|
2020-01-14 09:09:33 +00:00
|
|
|
tcolor = vec4(getDynLightContribution(tcolor, v2f.Color, v2f.PosW, v2f.Normal).rgb, tcolor.a);
|
2020-01-01 20:41:04 +00:00
|
|
|
if (tcolor.a == 0.0)
|
|
|
|
{
|
|
|
|
out.FragColor = tcolor;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Blend texture color and vertex color
|
2020-01-03 01:22:33 +00:00
|
|
|
vec4 ncolor = desaturate(getFogColor(v2f.PosW, tcolor));
|
2020-01-01 20:41:04 +00:00
|
|
|
|
|
|
|
out.FragColor = vec4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4 * highlightcolor.a), max(ncolor.a + 0.25, 0.5));
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(ALPHA_TEST)
|
|
|
|
if (out.FragColor.a < 0.5) discard;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (fogsettings.x >= 0.0) out.FragColor = mix(out.FragColor, fogcolor, clamp((-v2f.viewpos.z - fogsettings.x) / (fogsettings.y - fogsettings.x), 0.0, 1.0));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// world3d_fog, but with vertex shader from customvertexcolor_fog
|
|
|
|
// to-do: rewrite into a function
|
|
|
|
shader world3d_main_fog_vertexcolor extends world3d_main_fog
|
|
|
|
{
|
|
|
|
vertex
|
|
|
|
{
|
|
|
|
v2f.viewpos = view * world * vec4(in.Position, 1.0);
|
|
|
|
gl_Position = projection * v2f.viewpos;
|
|
|
|
v2f.PosW = (world * vec4(in.Position, 1.0)).xyz;
|
|
|
|
v2f.Color = vertexColor;
|
|
|
|
v2f.UV = in.TextureCoordinate;
|
|
|
|
v2f.Normal = normalize((modelnormal * vec4(in.Normal, 1.0)).xyz);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shader world3d_main_highlight_fog_vertexcolor extends world3d_main_highlight_fog
|
|
|
|
{
|
|
|
|
vertex
|
|
|
|
{
|
|
|
|
v2f.viewpos = view * world * vec4(in.Position, 1.0);
|
|
|
|
gl_Position = projection * v2f.viewpos;
|
|
|
|
v2f.PosW = (world * vec4(in.Position, 1.0)).xyz;
|
|
|
|
v2f.Color = vertexColor;
|
|
|
|
v2f.UV = in.TextureCoordinate;
|
|
|
|
v2f.Normal = normalize((modelnormal * vec4(in.Normal, 1.0)).xyz);
|
|
|
|
}
|
2020-01-04 21:15:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Slope handle shader
|
|
|
|
shader world3d_slope_handle extends world3d_vertex_color
|
|
|
|
{
|
|
|
|
vertex
|
|
|
|
{
|
2020-02-16 19:51:16 +00:00
|
|
|
v2f.viewpos = view * world * vec4(in.Position.x * slopeHandleLength, in.Position.y, in.Position.z, 1.0);
|
2020-01-04 21:15:13 +00:00
|
|
|
gl_Position = projection * v2f.viewpos;
|
|
|
|
v2f.Color = in.Color * vertexColor;
|
|
|
|
v2f.UV = in.TextureCoordinate;
|
|
|
|
}
|
2020-01-01 20:41:04 +00:00
|
|
|
}
|