OctaCore/config/glsl/model.cfg

375 lines
11 KiB
INI

////////////////////////////////////////////////
//
// model shaders
//
////////////////////////////////////////////////
// skeletal animation with dual quaternions
qtangentdecode = [
? $arg1 [
vec4 qxyz = mquat.xxyy*mquat.yzyz, qxzw = vec4(mquat.xzw, -mquat.w);
vec3 mtangent = (qxzw.yzw*mquat.zzy + qxyz.zxy)*vec3(-2.0, 2.0, 2.0) + vec3(1.0, 0.0, 0.0);
vec3 mnormal = (qxzw.zwx*mquat.yxx + qxyz.ywz)*vec3(2.0, 2.0, -2.0) + vec3(0.0, 0.0, 1.0);
// vec3 mtangent = cross(mquat.xyz, vec3(mquat.wz, -mquat.y))*2.0 + vec3(1.0, 0.0, 0.0);
// vec3 mnormal = cross(mquat.xyz, vec3(mquat.y, -mquat.x, mquat.w))*2.0 + vec3(0.0, 0.0, 1.0);
] [
vec3 mnormal = cross(mquat.xyz, vec3(mquat.y, -mquat.x, mquat.w))*2.0 + vec3(0.0, 0.0, 1.0);
]
]
skelanimdefs = [
result [
in vec4 vboneweight, vboneindex;
//:uniform animdata
uniform vec4 animdata[@@(min $maxvsuniforms $maxskelanimdata)];
]
]
skelanim = [
result [
int index = int(vboneindex.x);
@(if (= $arg1 1) [result [
vec4 dqreal = animdata[index];
vec4 dqdual = animdata[index+1];
]] [result [
vec4 dqreal = animdata[index] * vboneweight.x;
vec4 dqdual = animdata[index+1] * vboneweight.x;
index = int(vboneindex.y);
dqreal += animdata[index] * vboneweight.y;
dqdual += animdata[index+1] * vboneweight.y;
@(if (>= $arg1 3) [result [
index = int(vboneindex.z);
dqreal += animdata[index] * vboneweight.z;
dqdual += animdata[index+1] * vboneweight.z;
]])
@(if (>= $arg1 4) [result [
index = int(vboneindex.w);
dqreal += animdata[index] * vboneweight.w;
dqdual += animdata[index+1] * vboneweight.w;
]])
float len = length(dqreal);
dqreal /= len;
dqdual /= len;
]])
vec4 mpos = vec4((cross(dqreal.xyz, cross(dqreal.xyz, vvertex.xyz) + vvertex.xyz*dqreal.w + dqdual.xyz) + dqdual.xyz*dqreal.w - dqreal.xyz*dqdual.w)*2.0 + vvertex.xyz, vvertex.w);
@(if (>= $numargs 2) [result [
vec4 mquat = vec4(cross(dqreal.xyz, vtangent.xyz) + dqreal.xyz*vtangent.w + vtangent.xyz*dqreal.w, dqreal.w*vtangent.w - dot(dqreal.xyz, vtangent.xyz));
@(qtangentdecode $arg2)
]])
]
]
// mdltype:
// a -> alpha test
// b -> dual-quat skeletal animation
mdlopt = [ >= (strstr $modeltype $arg1) 0 ]
shadowmodelvertexshader = [
local modeltype
modeltype = $arg1
result [
in vec4 vvertex;
@(if (mdlopt "b") [skelanimdefs $arg2])
uniform mat4 modelmatrix;
@(? (mdlopt "a") [
in vec2 vtexcoord0;
uniform vec2 texscroll;
out vec2 texcoord0;
])
void main(void)
{
@(if (mdlopt "b") [
skelanim $arg2
] [result [
#define mpos vvertex
]])
gl_Position = modelmatrix * mpos;
@(? (mdlopt "a") [
texcoord0 = vtexcoord0 + texscroll;
])
}
]
]
shadowmodelfragmentshader = [
local modeltype
modeltype = $arg1
result [
@(? (mdlopt "a") [
uniform sampler2D tex0;
uniform float alphatest;
in vec2 texcoord0;
])
void main(void)
{
@(? (mdlopt "a") [
vec4 color = texture(tex0, texcoord0);
if(color.a <= alphatest)
discard;
])
}
]
]
shadowmodelshader = [
defershader 0 $arg1 [
shader 0 @arg1 (shadowmodelvertexshader @arg2) (shadowmodelfragmentshader @arg2)
loop+ i 1 4 [
variantshader 0 @@arg1 0 (shadowmodelvertexshader @@(concatword $arg2 "b") $i) []
]
]
]
shadowmodelshader "shadowmodel" ""
shadowmodelshader "alphashadowmodel" "a"
// mdltype:
// a -> alpha test
// e -> envmap
// n -> normalmap
// m -> masks
// d -> decal
// D -> alpha decal
// b -> dual-quat skeletal animation
// c -> disable cullface
// t -> transparent
modelvertexshader = [
local modeltype
modeltype = $arg1
result [
in vec4 vvertex, vtangent;
in vec2 vtexcoord0;
@(if (mdlopt "b") [skelanimdefs $arg2 (mdlopt "n")])
uniform mat4 modelmatrix;
uniform mat3 modelworld;
uniform vec3 modelcamera;
uniform vec2 texscroll;
@(? (mdlopt "n") [
out mat3 world;
] [
out vec3 nvec;
])
@(? (mdlopt "e") [
out vec3 camvec;
])
@(msaainterpvert)
out vec2 texcoord0;
void main(void)
{
@(if (mdlopt "b") [
skelanim $arg2 (mdlopt "n")
] [result [
#define mpos vvertex
#define mquat vtangent
@(qtangentdecode (mdlopt "n"))
]])
gl_Position = modelmatrix * mpos;
texcoord0 = vtexcoord0 + texscroll;
@(msaapackvert)
@(? (mdlopt "e") [
camvec = modelworld * normalize(modelcamera - mpos.xyz);
])
@(? (mdlopt "n") [
// composition of tangent -> object and object -> world transforms
// becomes tangent -> world
vec3 wnormal = modelworld * mnormal;
vec3 wtangent = modelworld * mtangent;
vec3 wbitangent = cross(wnormal, wtangent) * (vtangent.w < 0.0 ? -1.0 : 1.0);
world = mat3(wtangent, wbitangent, wnormal);
] [
nvec = modelworld * mnormal;
])
}
]
]
modelfragmentshader = [
local modeltype
modeltype = $arg1
result [
@(? (mdlopt "n") [
in mat3 world;
] [
in vec3 nvec;
])
@(? (mdlopt "e") [
uniform vec2 envmapscale;
in vec3 camvec;
])
uniform vec4 colorscale;
uniform vec2 fullbright;
uniform vec3 maskscale;
@(? (mdlopt "a") [uniform float alphatest;])
uniform sampler2D tex0;
@(? (mdlopt "m") [uniform sampler2D tex1;])
@(? (mdlopt "e") [uniform samplerCube tex2;])
@(? (mdlopt "n") [uniform sampler2D tex3;])
@(? (|| (mdlopt "d") [mdlopt "D"]) [uniform sampler2D tex4;])
@(msaainterpfrag)
in vec2 texcoord0;
uniform float aamask;
void main(void)
{
vec4 diffuse = texture(tex0, texcoord0);
@(? (mdlopt "a") [
if(diffuse.a <= alphatest)
discard;
])
gcolor.rgb = diffuse.rgb*colorscale.rgb;
@(? (|| (mdlopt "d") [mdlopt "D"]) [
vec4 decal = texture(tex4, texcoord0);
@(? (mdlopt "D") [
gcolor.rgb = mix(gcolor.rgb, decal.rgb, decal.a);
] [
gcolor.rgb += decal.rgb;
])
])
@(if (mdlopt "n") [result [
vec3 normal = texture(tex3, texcoord0).rgb - 0.5;
@(? (mdlopt "c") [
if(!gl_FrontFacing) normal.z = -normal.z;
])
normal = normalize(world * normal);
]] [result [
vec3 normal = normalize(nvec);
@(? (mdlopt "c") [
if(!gl_FrontFacing) normal = -normal;
])
]])
float spec = maskscale.x;
@(if (mdlopt "m") [result [
vec3 masks = texture(tex1, texcoord0).rgb;
spec *= masks.r; // specmap in red channel
@(? (mdlopt "e") [
vec3 camn = normalize(camvec);
float invfresnel = dot(camn, normal);
vec3 rvec = 2.0*invfresnel*normal - camn;
float rmod = envmapscale.x*clamp(invfresnel, 0.0, 1.0) + envmapscale.y;
vec3 reflect = texture(tex2, rvec).rgb;
gcolor.rgb = mix(gcolor.rgb, reflect, rmod*masks.b); // envmap mask in blue channel
])
float glowk = max(maskscale.z*masks.g, fullbright.y); // glow mask in green channel
]] [result [
float glowk = fullbright.y;
]])
@(gspecpack maskscale.y spec)
float colork = clamp(fullbright.x - glowk, 0.0, 1.0);
@(if (mdlopt "t") [result [
gcolor *= colorscale.a;
gglow.rgb = gcolor.rgb*glowk;
gcolor.rgb *= colork;
#define packnorm colorscale.a
]] [gglowpack "" packnorm])
@(gnormpackdef normal packnorm)
@(msaapackfrag aamask)
}
]
]
modelshader = [
shadername = (concatword "model" $arg1)
maxvariants = 9
shader 0 $shadername (modelvertexshader $arg1) (modelfragmentshader $arg1)
loop+ i 1 4 [
variantshader 0 $shadername 0 (modelvertexshader (concatword $arg1 "b") $i) [] $maxvariants
]
variantshader 0 $shadername 1 [] (modelfragmentshader (concatword $arg1 "t")) $maxvariants
loop i 4 [
variantshader 0 $shadername 1 [0 , @i] 1 $maxvariants
]
]
rsmmodelvertexshader = [
local modeltype
modeltype = $arg1
result [
in vec4 vvertex, vtangent;
in vec2 vtexcoord0;
@(if (mdlopt "b") [skelanimdefs $arg2 (mdlopt "n")])
uniform mat4 modelmatrix;
uniform mat3 modelworld;
uniform vec2 texscroll;
out vec2 texcoord0;
out vec3 nvec;
void main(void)
{
@(if (mdlopt "b") [
skelanim $arg2 (mdlopt "n")
] [result [
#define mpos vvertex
#define mquat vtangent
@(qtangentdecode (mdlopt "n"))
]])
gl_Position = modelmatrix * mpos;
texcoord0 = vtexcoord0 + texscroll;
nvec = modelworld * mnormal;
}
]
]
rsmmodelfragmentshader = [
local modeltype
modeltype = $arg1
result [
in vec2 texcoord0;
in vec3 nvec;
uniform vec4 colorscale;
@(? (mdlopt "a") [uniform float alphatest;])
uniform vec3 rsmdir;
uniform sampler2D tex0;
layout(location = 0) out vec4 gcolor;
layout(location = 1) out vec4 gnormal;
void main(void)
{
vec4 diffuse = texture(tex0, texcoord0);
@(? (mdlopt "a") [
if(diffuse.a <= alphatest)
discard;
])
vec3 normal = normalize(nvec);
@(? (mdlopt "c") [
if(!gl_FrontFacing) normal = -normal;
])
gcolor = vec4(dot(normal, rsmdir)*diffuse.rgb*colorscale.rgb, 1.0);
gnormal = vec4(normal*0.5+0.5, 0.0);
}
]
]
rsmmodelshader = [
shadername = (concatword "rsmmodel" $arg1)
shader 0 $shadername (rsmmodelvertexshader $arg1) (rsmmodelfragmentshader $arg1)
loop+ i 1 4 [
variantshader 0 $shadername 0 (rsmmodelvertexshader (concatword $arg1 "b") $i) []
]
]