mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
93abc60a5b
Shader stage tcMods for matrix and turb effects need to be applied in order for turb to be correct and all tcMod turb need to be applied instead of only the last one. Quake 3's textures/liquids/slime1 had tcMod turb and then tcMod scale. OpenGL2 applied the matrix first and then turb which had the wrong result.
287 lines
8.5 KiB
GLSL
287 lines
8.5 KiB
GLSL
attribute vec4 attr_TexCoord0;
|
|
#if defined(USE_LIGHTMAP) || defined(USE_TCGEN)
|
|
attribute vec4 attr_TexCoord1;
|
|
#endif
|
|
attribute vec4 attr_Color;
|
|
|
|
attribute vec3 attr_Position;
|
|
attribute vec3 attr_Normal;
|
|
attribute vec4 attr_Tangent;
|
|
|
|
#if defined(USE_VERTEX_ANIMATION)
|
|
attribute vec3 attr_Position2;
|
|
attribute vec3 attr_Normal2;
|
|
attribute vec4 attr_Tangent2;
|
|
#elif defined(USE_BONE_ANIMATION)
|
|
attribute vec4 attr_BoneIndexes;
|
|
attribute vec4 attr_BoneWeights;
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
|
|
attribute vec3 attr_LightDirection;
|
|
#endif
|
|
|
|
#if defined(USE_DELUXEMAP)
|
|
uniform vec4 u_EnableTextures; // x = normal, y = deluxe, z = specular, w = cube
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
uniform vec3 u_ViewOrigin;
|
|
#endif
|
|
|
|
#if defined(USE_TCGEN)
|
|
uniform int u_TCGen0;
|
|
uniform vec3 u_TCGen0Vector0;
|
|
uniform vec3 u_TCGen0Vector1;
|
|
uniform vec3 u_LocalViewOrigin;
|
|
#endif
|
|
|
|
#if defined(USE_TCMOD)
|
|
uniform vec4 u_DiffuseTexMatrix0;
|
|
uniform vec4 u_DiffuseTexMatrix1;
|
|
uniform vec4 u_DiffuseTexMatrix2;
|
|
uniform vec4 u_DiffuseTexMatrix3;
|
|
uniform vec4 u_DiffuseTexMatrix4;
|
|
uniform vec4 u_DiffuseTexMatrix5;
|
|
uniform vec4 u_DiffuseTexMatrix6;
|
|
uniform vec4 u_DiffuseTexMatrix7;
|
|
#endif
|
|
|
|
uniform mat4 u_ModelViewProjectionMatrix;
|
|
uniform vec4 u_BaseColor;
|
|
uniform vec4 u_VertColor;
|
|
|
|
#if defined(USE_MODELMATRIX)
|
|
uniform mat4 u_ModelMatrix;
|
|
#endif
|
|
|
|
#if defined(USE_VERTEX_ANIMATION)
|
|
uniform float u_VertexLerp;
|
|
#elif defined(USE_BONE_ANIMATION)
|
|
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT_VECTOR)
|
|
uniform vec4 u_LightOrigin;
|
|
uniform float u_LightRadius;
|
|
uniform vec3 u_DirectedLight;
|
|
uniform vec3 u_AmbientLight;
|
|
#endif
|
|
|
|
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
|
uniform vec4 u_PrimaryLightOrigin;
|
|
uniform float u_PrimaryLightRadius;
|
|
#endif
|
|
|
|
varying vec4 var_TexCoords;
|
|
|
|
varying vec4 var_Color;
|
|
#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
|
|
varying vec4 var_ColorAmbient;
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
varying vec4 var_Normal;
|
|
varying vec4 var_Tangent;
|
|
varying vec4 var_Bitangent;
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
varying vec4 var_LightDir;
|
|
#endif
|
|
|
|
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
|
varying vec4 var_PrimaryLightDir;
|
|
#endif
|
|
|
|
#if defined(USE_TCGEN)
|
|
vec2 GenTexCoords(int TCGen, vec3 position, vec3 normal, vec3 TCGenVector0, vec3 TCGenVector1)
|
|
{
|
|
vec2 tex = attr_TexCoord0.st;
|
|
|
|
if (TCGen == TCGEN_LIGHTMAP)
|
|
{
|
|
tex = attr_TexCoord1.st;
|
|
}
|
|
else if (TCGen == TCGEN_ENVIRONMENT_MAPPED)
|
|
{
|
|
vec3 viewer = normalize(u_LocalViewOrigin - position);
|
|
vec2 ref = reflect(viewer, normal).yz;
|
|
tex.s = ref.x * -0.5 + 0.5;
|
|
tex.t = ref.y * 0.5 + 0.5;
|
|
}
|
|
else if (TCGen == TCGEN_VECTOR)
|
|
{
|
|
tex = vec2(dot(position, TCGenVector0), dot(position, TCGenVector1));
|
|
}
|
|
|
|
return tex;
|
|
}
|
|
#endif
|
|
|
|
#if defined(USE_TCMOD)
|
|
vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix[8])
|
|
{
|
|
vec2 st2 = st;
|
|
vec2 offsetPos = vec2(position.x + position.z, position.y);
|
|
|
|
st2 = vec2(st2.x * texMatrix[0].x + st2.y * texMatrix[0].y + texMatrix[0].z,
|
|
st2.x * texMatrix[1].x + st2.y * texMatrix[1].y + texMatrix[1].z);
|
|
st2 += texMatrix[0].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[1].w * 2.0 * M_PI));
|
|
|
|
st2 = vec2(st2.x * texMatrix[2].x + st2.y * texMatrix[2].y + texMatrix[2].z,
|
|
st2.x * texMatrix[3].x + st2.y * texMatrix[3].y + texMatrix[3].z);
|
|
st2 += texMatrix[2].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[3].w * 2.0 * M_PI));
|
|
|
|
st2 = vec2(st2.x * texMatrix[4].x + st2.y * texMatrix[4].y + texMatrix[4].z,
|
|
st2.x * texMatrix[5].x + st2.y * texMatrix[5].y + texMatrix[5].z);
|
|
st2 += texMatrix[4].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[5].w * 2.0 * M_PI));
|
|
|
|
st2 = vec2(st2.x * texMatrix[6].x + st2.y * texMatrix[6].y + texMatrix[6].z,
|
|
st2.x * texMatrix[7].x + st2.y * texMatrix[7].y + texMatrix[7].z);
|
|
st2 += texMatrix[6].w * sin(offsetPos * (2.0 * M_PI / 1024.0) + vec2(texMatrix[7].w * 2.0 * M_PI));
|
|
|
|
return st2;
|
|
}
|
|
#endif
|
|
|
|
|
|
float CalcLightAttenuation(float point, float normDist)
|
|
{
|
|
// zero light at 1.0, approximating q3 style
|
|
// also don't attenuate directional light
|
|
float attenuation = (0.5 * normDist - 1.5) * point + 1.0;
|
|
|
|
// clamp attenuation
|
|
#if defined(NO_LIGHT_CLAMP)
|
|
attenuation = max(attenuation, 0.0);
|
|
#else
|
|
attenuation = clamp(attenuation, 0.0, 1.0);
|
|
#endif
|
|
|
|
return attenuation;
|
|
}
|
|
|
|
|
|
void main()
|
|
{
|
|
#if defined(USE_VERTEX_ANIMATION)
|
|
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
|
|
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
vec3 tangent = mix(attr_Tangent.xyz, attr_Tangent2.xyz, u_VertexLerp);
|
|
#endif
|
|
#elif defined(USE_BONE_ANIMATION)
|
|
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
|
|
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
|
|
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
|
|
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
|
|
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));
|
|
|
|
vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
|
|
vec3 normal = normalize(nrmMat * attr_Normal);
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
vec3 tangent = normalize(nrmMat * attr_Tangent.xyz);
|
|
#endif
|
|
#else
|
|
vec3 position = attr_Position;
|
|
vec3 normal = attr_Normal;
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
vec3 tangent = attr_Tangent.xyz;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(USE_TCGEN)
|
|
vec2 texCoords = GenTexCoords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1);
|
|
#else
|
|
vec2 texCoords = attr_TexCoord0.st;
|
|
#endif
|
|
|
|
#if defined(USE_TCMOD)
|
|
vec4 diffuseTexMatrix[8];
|
|
diffuseTexMatrix[0] = u_DiffuseTexMatrix0;
|
|
diffuseTexMatrix[1] = u_DiffuseTexMatrix1;
|
|
diffuseTexMatrix[2] = u_DiffuseTexMatrix2;
|
|
diffuseTexMatrix[3] = u_DiffuseTexMatrix3;
|
|
diffuseTexMatrix[4] = u_DiffuseTexMatrix4;
|
|
diffuseTexMatrix[5] = u_DiffuseTexMatrix5;
|
|
diffuseTexMatrix[6] = u_DiffuseTexMatrix6;
|
|
diffuseTexMatrix[7] = u_DiffuseTexMatrix7;
|
|
var_TexCoords.xy = ModTexCoords(texCoords, position, diffuseTexMatrix);
|
|
#else
|
|
var_TexCoords.xy = texCoords;
|
|
#endif
|
|
|
|
gl_Position = u_ModelViewProjectionMatrix * vec4(position, 1.0);
|
|
|
|
#if defined(USE_MODELMATRIX)
|
|
position = (u_ModelMatrix * vec4(position, 1.0)).xyz;
|
|
normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz;
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
vec3 bitangent = cross(normal, tangent) * attr_Tangent.w;
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT_VECTOR)
|
|
vec3 L = u_LightOrigin.xyz - (position * u_LightOrigin.w);
|
|
#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
vec3 L = attr_LightDirection;
|
|
#if defined(USE_MODELMATRIX)
|
|
L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(USE_LIGHTMAP)
|
|
var_TexCoords.zw = attr_TexCoord1.st;
|
|
#endif
|
|
|
|
var_Color = u_VertColor * attr_Color + u_BaseColor;
|
|
|
|
#if defined(USE_LIGHT_VECTOR)
|
|
#if defined(USE_FAST_LIGHT)
|
|
float sqrLightDist = dot(L, L);
|
|
float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0);
|
|
float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist);
|
|
|
|
var_Color.rgb *= u_DirectedLight * (attenuation * NL) + u_AmbientLight;
|
|
#else
|
|
var_ColorAmbient.rgb = u_AmbientLight * var_Color.rgb;
|
|
var_Color.rgb *= u_DirectedLight;
|
|
#if defined(USE_PBR)
|
|
var_ColorAmbient.rgb *= var_ColorAmbient.rgb;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) && defined(USE_PBR)
|
|
var_Color.rgb *= var_Color.rgb;
|
|
#endif
|
|
|
|
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
|
|
var_PrimaryLightDir.xyz = u_PrimaryLightOrigin.xyz - (position * u_PrimaryLightOrigin.w);
|
|
var_PrimaryLightDir.w = u_PrimaryLightRadius * u_PrimaryLightRadius;
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
#if defined(USE_LIGHT_VECTOR)
|
|
var_LightDir = vec4(L, u_LightRadius * u_LightRadius);
|
|
#else
|
|
var_LightDir = vec4(L, 0.0);
|
|
#endif
|
|
#if defined(USE_DELUXEMAP)
|
|
var_LightDir -= u_EnableTextures.y * var_LightDir;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
|
|
vec3 viewDir = u_ViewOrigin - position;
|
|
// store view direction in tangent space to save on varyings
|
|
var_Normal = vec4(normal, viewDir.x);
|
|
var_Tangent = vec4(tangent, viewDir.y);
|
|
var_Bitangent = vec4(bitangent, viewDir.z);
|
|
#endif
|
|
}
|