gzdoom/wadsrc/static/shaders_gles/glsl/main.vp
2022-11-13 21:19:54 +01:00

219 lines
5.9 KiB
Text

attribute vec4 aPosition;
attribute vec2 aTexCoord;
attribute vec4 aColor;
varying vec4 vTexCoord;
varying vec4 vColor;
#ifndef SIMPLE // we do not need these for simple shaders
attribute vec4 aVertex2;
attribute vec4 aNormal;
attribute vec4 aNormal2;
#if __VERSION__ >= 300
attribute vec4 aBoneWeight;
attribute uvec4 aBoneSelector;
#endif
varying vec4 pixelpos;
varying vec3 glowdist;
varying vec3 gradientdist;
varying vec4 vWorldNormal;
varying vec4 vEyeNormal;
#endif
#ifdef NO_CLIPDISTANCE_SUPPORT
varying vec4 ClipDistanceA;
varying vec4 ClipDistanceB;
#endif
struct BonesResult
{
vec3 Normal;
vec4 Position;
};
BonesResult ApplyBones();
void main()
{
float ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3, ClipDistance4;
vec2 parmTexCoord;
vec4 parmPosition;
BonesResult bones = ApplyBones();
parmTexCoord = aTexCoord;
parmPosition = bones.Position;
#ifndef SIMPLE
vec4 worldcoord = ModelMatrix * mix(parmPosition, aVertex2, uInterpolationFactor);
#else
vec4 worldcoord = ModelMatrix * parmPosition;
#endif
vec4 eyeCoordPos = ViewMatrix * worldcoord;
#ifdef HAS_UNIFORM_VERTEX_DATA
if ((useVertexData & 1) == 0)
vColor = uVertexColor;
else
vColor = aColor;
#else
vColor = aColor;
#endif
#ifndef SIMPLE
pixelpos.xyz = worldcoord.xyz;
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
if (uGlowTopColor.a > 0.0 || uGlowBottomColor.a > 0.0)
{
float topatpoint = (uGlowTopPlane.w + uGlowTopPlane.x * worldcoord.x + uGlowTopPlane.y * worldcoord.z) * uGlowTopPlane.z;
float bottomatpoint = (uGlowBottomPlane.w + uGlowBottomPlane.x * worldcoord.x + uGlowBottomPlane.y * worldcoord.z) * uGlowBottomPlane.z;
glowdist.x = topatpoint - worldcoord.y;
glowdist.y = worldcoord.y - bottomatpoint;
glowdist.z = clamp(glowdist.x / (topatpoint - bottomatpoint), 0.0, 1.0);
}
if (uObjectColor2.a != 0.0)
{
float topatpoint = (uGradientTopPlane.w + uGradientTopPlane.x * worldcoord.x + uGradientTopPlane.y * worldcoord.z) * uGradientTopPlane.z;
float bottomatpoint = (uGradientBottomPlane.w + uGradientBottomPlane.x * worldcoord.x + uGradientBottomPlane.y * worldcoord.z) * uGradientBottomPlane.z;
gradientdist.x = topatpoint - worldcoord.y;
gradientdist.y = worldcoord.y - bottomatpoint;
gradientdist.z = clamp(gradientdist.x / (topatpoint - bottomatpoint), 0.0, 1.0);
}
if (uSplitBottomPlane.z != 0.0)
{
ClipDistance3 = ((uSplitTopPlane.w + uSplitTopPlane.x * worldcoord.x + uSplitTopPlane.y * worldcoord.z) * uSplitTopPlane.z) - worldcoord.y;
ClipDistance4 = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
}
vWorldNormal = NormalModelMatrix * vec4(normalize(bones.Normal), 1.0);
vEyeNormal = NormalViewMatrix * vWorldNormal;
#endif
#ifdef SPHEREMAP
vec3 u = normalize(eyeCoordPos.xyz);
vec4 n = normalize(NormalViewMatrix * vec4(parmTexCoord.x, 0.0, parmTexCoord.y, 0.0));
vec3 r = reflect(u, n.xyz);
float m = 2.0 * sqrt( r.x*r.x + r.y*r.y + (r.z+1.0)*(r.z+1.0) );
vec2 sst = vec2(r.x/m + 0.5, r.y/m + 0.5);
vTexCoord.xy = sst;
#else
vTexCoord = TextureMatrix * vec4(parmTexCoord, 0.0, 1.0);
#endif
if (uClipHeightDirection != 0.0) // clip planes used for reflective flats
{
ClipDistance0 = (worldcoord.y - uClipHeight) * uClipHeightDirection;
}
else if (uClipLine.x > -1000000.0) // and for line portals - this will never be active at the same time as the reflective planes clipping so it can use the same hardware clip plane.
{
ClipDistance0 = -( (worldcoord.z - uClipLine.y) * uClipLine.z + (uClipLine.x - worldcoord.x) * uClipLine.w ) + 1.0/32768.0; // allow a tiny bit of imprecisions for colinear linedefs.
}
else
{
ClipDistance0 = 1.0;
}
// clip planes used for translucency splitting
ClipDistance1 = worldcoord.y - uClipSplit.x;
ClipDistance2 = uClipSplit.y - worldcoord.y;
if (uSplitTopPlane == vec4(0.0))
{
ClipDistance3 = 1.0;
ClipDistance4 = 1.0;
}
ClipDistanceA = vec4(ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3);
ClipDistanceB = vec4(ClipDistance4, 0.0, 0.0, 0.0);
gl_Position = ProjectionMatrix * eyeCoordPos;
}
#if !defined(SIMPLE)
vec3 GetAttrNormal()
{
#ifdef HAS_UNIFORM_VERTEX_DATA
if ((useVertexData & 2) == 0)
return uVertexNormal.xyz;
else
return mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor);
#else
return mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor);
#endif
}
#if __VERSION__ >= 300
void AddWeightedBone(uint boneIndex, float weight, inout vec4 position, inout vec3 normal)
{
if (weight != 0.0)
{
mat4 transform = bones[uBoneIndexBase + int(boneIndex)];
mat3 rotation = mat3(transform);
position += (transform * aPosition) * weight;
normal += (rotation * aNormal.xyz) * weight;
}
}
BonesResult ApplyBones()
{
BonesResult result;
if (uBoneIndexBase >= 0 && aBoneWeight != vec4(0.0))
{
result.Position = vec4(0.0);
result.Normal = vec3(0.0);
// We use low precision input for our bone weights. Rescale so the sum still is 1.0
float totalWeight = aBoneWeight.x + aBoneWeight.y + aBoneWeight.z + aBoneWeight.w;
float weightMultiplier = 1.0 / totalWeight;
vec4 boneWeight = aBoneWeight * weightMultiplier;
AddWeightedBone(aBoneSelector.x, boneWeight.x, result.Position, result.Normal);
AddWeightedBone(aBoneSelector.y, boneWeight.y, result.Position, result.Normal);
AddWeightedBone(aBoneSelector.z, boneWeight.z, result.Position, result.Normal);
AddWeightedBone(aBoneSelector.w, boneWeight.w, result.Position, result.Normal);
result.Position.w = 1.0; // For numerical stability
}
else
{
result.Position = aPosition;
result.Normal = GetAttrNormal();
}
return result;
}
#else
BonesResult ApplyBones()
{
BonesResult result;
result.Position = aPosition;
result.Normal = GetAttrNormal();
return result;
}
#endif
#else // SIMPLE
BonesResult ApplyBones()
{
BonesResult result;
result.Position = aPosition;
return result;
}
#endif