// standard shader definitions lazyshader = [ defershader $arg1 $arg2 [ shader @arg1 @arg2 [@@arg3] [@@arg4] ] ] lmcoordscale = (divf 1 32767) shader 0 "null" [ attribute vec4 vvertex; void main(void) { gl_Position = vvertex; } ] [ void main(void) { gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0); } ] /////////////////////////////////////////////////// // // used for rendering to the HUD // /////////////////////////////////////////////////// screentexcoord = [ result [ uniform vec4 screentexcoord@arg1; #define vtexcoord@arg1 (vvertex.xy * screentexcoord@arg1.xy + screentexcoord@arg1.zw) ] ] shader 0 "hud" [ attribute vec4 vvertex, vcolor; attribute vec2 vtexcoord0; uniform mat4 hudmatrix; varying vec2 texcoord0; varying vec4 color; void main(void) { gl_Position = hudmatrix * vvertex; texcoord0 = vtexcoord0; color = vcolor; } ] [ varying vec2 texcoord0; varying vec4 color; uniform sampler2D tex0; void main(void) { gl_FragColor = color * texture2D(tex0, texcoord0); } ] shader 0 "hudnotexture" [ attribute vec4 vvertex, vcolor; uniform mat4 hudmatrix; varying vec4 color; void main(void) { gl_Position = hudmatrix * vvertex; color = vcolor; } ] [ varying vec4 color; void main(void) { gl_FragColor = color; } ] shader 0 "hudrgb" [ attribute vec4 vvertex, vcolor; attribute vec2 vtexcoord0; uniform mat4 hudmatrix; varying vec2 texcoord0; varying vec4 color; void main(void) { gl_Position = hudmatrix * vvertex; texcoord0 = vtexcoord0; color = vcolor; } ] [ varying vec2 texcoord0; varying vec4 color; uniform sampler2D tex0; void main(void) { gl_FragColor.rgb = color.rgb * texture2D(tex0, texcoord0).rgb; gl_FragColor.a = color.a; } ] /////////////////////////////////////////////////// // // miscellaneous default shaders // /////////////////////////////////////////////////// shader 0 "texture" [ attribute vec4 vvertex, vcolor; attribute vec2 vtexcoord0; uniform mat4 camprojmatrix; varying vec2 texcoord0; varying vec4 color; void main(void) { gl_Position = camprojmatrix * vvertex; texcoord0 = vtexcoord0; color = vcolor; } ] [ varying vec2 texcoord0; varying vec4 color; uniform sampler2D tex0; void main(void) { gl_FragColor = color * texture2D(tex0, texcoord0); } ] shader 0 "notexture" [ attribute vec4 vvertex, vcolor; uniform mat4 camprojmatrix; varying vec4 color; void main(void) { gl_Position = camprojmatrix * vvertex; color = vcolor; } ] [ varying vec4 color; void main(void) { gl_FragColor = color; } ] shader 0 "cubemap" [ attribute vec4 vvertex, vcolor; attribute vec3 vtexcoord0; varying vec3 texcoord0; varying vec4 color; void main(void) { gl_Position = vvertex; texcoord0 = vtexcoord0; color = vcolor; } ] [ varying vec3 texcoord0; varying vec4 color; uniform samplerCube tex0; void main(void) { gl_FragColor = color * textureCube(tex0, texcoord0); } ] ////////////////////////////////////////////////////////////////////// // // for filling the z-buffer only (i.e. multi-pass rendering, OQ) // ////////////////////////////////////////////////////////////////////// shader 0 "nocolor" [ attribute vec4 vvertex; uniform mat4 camprojmatrix; void main() { gl_Position = camprojmatrix * vvertex; } ] [ void main() {} ] shader 0 "bbquery" [ attribute vec4 vvertex; uniform mat4 camprojmatrix; uniform vec3 bborigin, bbsize; void main() { gl_Position = camprojmatrix * vec4(bborigin + vvertex.xyz*bbsize, vvertex.w); } ] [ void main() {} ] //////////////////////////////////////////////////////// // // default lightmapped world shader.. does texcoord gen // /////////////////////////////////////////////////////// worldshader = [ stype = 0 if (>= (strstr $arg1 "env") 0) [stype = (+ $stype 2)] shader $stype $arg1 [ //:fog //:water @(if (>= $numargs 5) [result $arg5]) attribute vec4 vvertex; attribute vec3 vnormal; attribute vec2 vtexcoord0, vtexcoord1; uniform mat4 camprojmatrix; uniform vec2 texgenscroll; varying vec2 texcoord0, texcoord1; void main(void) { gl_Position = camprojmatrix * vvertex; texcoord0 = vtexcoord0 + texgenscroll; texcoord1 = vtexcoord1 * @lmcoordscale; @arg2 //:shadowmap //:dynlight } ] [ @(if (>= $numargs 5) [result $arg5]) @(if (>= $numargs 6) [result $arg6]) uniform vec4 colorparams; varying vec2 texcoord0, texcoord1; uniform sampler2D diffusemap, lightmap; void main(void) { @(? (>= (strstr $arg1 "alpha") 0) [ vec4 diffuse = texture2D(diffusemap, texcoord0); diffuse.rgb *= diffuse.a; //:fog fogcolor * diffuse.a ] [ vec4 diffuse = vec4(texture2D(diffusemap, texcoord0).rgb, 1.0); ]) vec4 lm = texture2D(lightmap, texcoord1); //:shadowmap lm //:dynlight lm @arg3 diffuse *= colorparams; @(if (|| (< $numargs 4) [=s $arg4 []]) [result [gl_FragColor = diffuse * lm;]] [result $arg4]) } ] ] worldshader "stdworld" [] [] worldshader "alphaworld" [] [] defershader 0 "decalworld" [ worldshader "decalworld" [] [ vec4 diffuse2 = texture2D(decal, texcoord0); diffuse.rgb = mix(diffuse.rgb, diffuse2.rgb, diffuse2.a); ] [] [] [uniform sampler2D decal;] ] shader 0 "noglareworld" [ attribute vec4 vvertex; uniform mat4 camprojmatrix; void main(void) { gl_Position = camprojmatrix * vvertex; } ] [ void main(void) { gl_FragColor = vec4(0.0); } ] shader 0 "noglareblendworld" [ attribute vec4 vvertex; attribute vec2 vtexcoord1; uniform mat4 camprojmatrix; varying vec2 texcoord0; void main(void) { gl_Position = camprojmatrix * vvertex; texcoord0 = vtexcoord1 * @lmcoordscale; } ] [ varying vec2 texcoord0; uniform sampler2D lightmap; void main(void) { gl_FragColor.rgb = vec3(0.0); gl_FragColor.a = texture2D(lightmap, texcoord0).a; } ] shader 0 "noglarealphaworld" [ attribute vec4 vvertex; uniform mat4 camprojmatrix; void main(void) { gl_Position = camprojmatrix * vvertex; } ] [ uniform vec4 colorparams; uniform sampler2D lightmap; void main(void) { gl_FragColor.rgb = vec3(0.0); gl_FragColor.a = colorparams.a; } ] // bumptype: // o -> orthonormalize // t -> tangent space cam // s -> spec // S -> spec map // p -> parallax // a -> alpha map btopt = [ >= (strstr $bumptype $arg1) 0 ] bumpvariantshader = [ bumptype = $arg2 stype = (? (btopt "e") 3 1) if (! (btopt "i")) [ if (btopt "S") [ defuniformparam "specscale" 6 6 6 // spec map multiplier ] [if (btopt "s") [ defuniformparam "specscale" 1 1 1 // spec multiplier ]] if (|| (btopt "p") (btopt "P")) [ defuniformparam "parallaxscale" 0.06 -0.03 // parallax scaling ] ] [ if (btopt "s") [stype = (+ $stype 8)] ] variantshader $stype $arg1 (? (btopt "i") 4 -1) [ //:fog attribute vec4 vvertex; attribute vec3 vnormal; attribute vec2 vtexcoord0, vtexcoord1; @(? (btopt "o") [attribute vec4 vtangent;]) uniform mat4 camprojmatrix; uniform vec2 texgenscroll; varying vec2 texcoord0, texcoord1; void main(void) { gl_Position = camprojmatrix * vvertex; texcoord0 = vtexcoord0 + texgenscroll; texcoord1 = vtexcoord1 * @lmcoordscale; @(if (btopt "o") [result [ vec3 bitangent = cross(vnormal, vtangent.xyz) * vtangent.w; @@(if (btopt "t") [result [ // trans eye vector into TS vec3 camobj = camera - vvertex.xyz; camvec = vec3(dot(camobj, vtangent.xyz), dot(camobj, bitangent), dot(camobj, vnormal)); ]]) @@(if (btopt "r") [result [ @@(if (! (btopt "t")) [result [ camvec = camera - vvertex.xyz; ]]) // calculate tangent -> world transform world = mat3(vtangent.xyz, bitangent, vnormal); ]]) ]]) @(if (|| (! (btopt "i")) (btopt "s")) [result [ //:dynlight ]]) @(if (! (btopt "i")) [result [ //:shadowmap //:water ]]) } ] [ uniform vec4 colorparams; varying vec2 texcoord0, texcoord1; uniform sampler2D diffusemap, lmcolor, lmdir; @(if (|| (! (btopt "i")) (btopt "s") (btopt "p") (btopt "P")) [result [uniform sampler2D normalmap;]]) void main(void) { @(if (|| (! (btopt "i")) (btopt "s")) [result [ vec4 lmc = texture2D(lmcolor, texcoord1); gl_FragColor.a = colorparams.a * lmc.a; vec3 lmlv = texture2D(lmdir, texcoord1).rgb*2.0 - 1.0; ]]) @(if (btopt "t") [result [vec3 camdir = normalize(camvec);]]) @(if (btopt "p") [result [ float height = texture2D(normalmap, texcoord0).a; vec2 dtc = texcoord0 + camdir.xy*(height*parallaxscale.x + parallaxscale.y); ]]) @(if (btopt "P") [result [ const float step = -1.0/7.0; vec3 duv = vec3((step*parallaxscale.x/camdir.z)*camdir.xy, step); vec3 htc = vec3(texcoord0 + duv.xy*parallaxscale.y, 1.0); vec4 height = texture2D(normalmap, htc.xy); @@(loopconcat i 7 [concatword [ htc += height.w < htc.z ? duv : vec3(0.0); height = texture2D(normalmap, htc.xy); ]]) #define dtc htc.xy #define bump height.xyz ]]) @(if (|| (btopt "p") (btopt "P")) [] [result [#define dtc texcoord0]]) @(if (btopt "s") [result [ vec3 halfangle = normalize(camdir + lmlv); float spec = pow(clamp(dot(halfangle, bump), 0.0, 1.0), @(? (btopt "i") "128.0" "32.0")); @(if (btopt "i") [result [spec = min(spec*64.0, 1.0);]]) @(if (btopt "S") [result [spec *= diffuse.a;]]) @(if (btopt "i") [result [ @(? (btopt "S") "diffuse.rgb" "vec3 diffuse") = specscale.xyz*spec; ]] [result [ diffuse.rgb += specscale.xyz*spec; ]]) ]]) @(if (btopt "a") [result [ gl_FragColor.a *= alpha; //:fog fogcolor * alpha ]]) } ] ] bumpshader = [ defershader (? (>= (strstr $arg2 "e") 0) 3 1) $arg1 [ bumpvariantshader @arg1 @arg2 if (|| (btopt "g") (btopt "s")) [ bumpvariantshader @@arg1 (strreplace (concatword @@arg2 "i") "r") ] ] ] bumpshader "bumpworld" "" bumpshader "bumpspecworld" "ots" fastshader bumpspecworld bumpworld 2 altshader bumpspecworld bumpworld bumpshader "bumpspecmapworld" "otsS" fastshader bumpspecmapworld bumpworld 2 altshader bumpspecmapworld bumpworld bumpshader "bumpalphaworld" "a" bumpshader "bumpspecalphaworld" "otsa" fastshader bumpspecalphaworld bumpalphaworld 1 altshader bumpspecalphaworld bumpalphaworld bumpshader "bumpspecmapalphaworld" "otsSa" fastshader bumpspecmapalphaworld bumpalphaworld 1 altshader bumpspecmapalphaworld bumpalphaworld bumpshader "bumpparallaxworld" "pot" fastshader bumpparallaxworld bumpworld 1 altshader bumpparallaxworld bumpworld bumpshader "bumpspecparallaxworld" "pots" fastshader bumpspecparallaxworld bumpparallaxworld 2 fastshader bumpspecparallaxworld bumpworld 1 altshader bumpspecparallaxworld bumpworld bumpshader "bumpspecmapparallaxworld" "potsS" fastshader bumpspecmapparallaxworld bumpparallaxworld 2 fastshader bumpspecmapparallaxworld bumpworld 1 altshader bumpspecmapparallaxworld bumpworld bumpshader "bumpenvworldalt" "e" bumpshader "bumpenvworld" "eor" altshader bumpenvworld bumpenvworldalt fastshader bumpenvworld bumpenvworldalt 2 bumpshader "bumpenvspecworld" "eotsr" altshader bumpenvspecworld bumpenvworldalt fastshader bumpenvspecworld bumpenvworldalt 2 bumpshader "bumpenvspecmapworld" "eotsSrR" altshader bumpenvspecmapworld bumpenvworldalt fastshader bumpenvspecmapworld bumpenvworldalt 2 bumpshader "bumpenvparallaxworldalt" "epot" altshader bumpenvparallaxworldalt bumpenvworldalt bumpshader "bumpenvparallaxworld" "epotr" altshader bumpenvparallaxworld bumpenvparallaxworldalt fastshader bumpenvparallaxworld bumpenvparallaxworldalt 2 fastshader bumpenvparallaxworld bumpenvworldalt 1 bumpshader "bumpenvspecparallaxworld" "epotsr" altshader bumpenvspecparallaxworld bumpenvparallaxworldalt fastshader bumpenvspecparallaxworld bumpenvparallaxworldalt 2 fastshader bumpenvspecparallaxworld bumpenvworldalt 1 bumpshader "bumpenvspecmapparallaxworld" "epotsSrR" altshader bumpenvspecmapparallaxworld bumpenvparallaxworldalt fastshader bumpenvspecmapparallaxworld bumpenvparallaxworldalt 2 fastshader bumpenvspecmapparallaxworld bumpenvworldalt 1 //////////////////////////////////////////////// // // model shaders // //////////////////////////////////////////////// // skeletal animation for 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 = [ skelanimlength = (min (- $maxvsuniforms (+ $reservevpparams 10)) $maxskelanimdata) result [ attribute vec4 vboneweight; attribute vec4 vboneindex; //:uniform animdata uniform vec4 animdata[@@skelanimlength]; ] ] 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 $arg2 [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 $arg3) ]] [if (>= $numargs 2) [result [ vec3 mnormal = cross(dqreal.xyz, cross(dqreal.xyz, vnormal) + vnormal*dqreal.w)*2.0 + vnormal; ]]]) ] ] // model shadowmapping shadowmapcastervertexshader = [ result [ @(if (>= $numargs 2) [result $arg1]) attribute vec4 vvertex; uniform mat4 modelmatrix; uniform vec4 shadowintensity; varying vec4 shadowmapvals; void main(void) { @(if (>= $numargs 2) [result $arg2] [result [ #define mpos vvertex ]]) gl_Position = modelmatrix * mpos; shadowmapvals = vec4(1.0 - gl_Position.z, 1.0, 0.0, shadowintensity.x); } ] ] shader 0 shadowmapcaster (shadowmapcastervertexshader) [ varying vec4 shadowmapvals; void main(void) { gl_FragColor = shadowmapvals; } ] loop i 4 [ variantshader 0 shadowmapcaster 0 (shadowmapcastervertexshader (skelanimdefs (+ $i 1)) (skelanim (+ $i 1))) [] ] shader 0 "shadowmapreceiver" [ attribute vec4 vvertex; uniform mat4 shadowmatrix; uniform vec2 shadowmapbias; varying vec4 shadowmapvals; void main(void) { gl_Position = shadowmatrix * vvertex; shadowmapvals = vec4(0.0, 0.0, shadowmapbias.y - gl_Position.z, 0.0); } ] [ varying vec4 shadowmapvals; void main(void) { gl_FragColor = shadowmapvals; } ] // model stenciling notexturemodelvertexshader = [ result [ attribute vec4 vvertex, vcolor; uniform mat4 modelmatrix; varying vec4 color; @(if (>= $numargs 2) [result $arg1]) //:fog void main(void) { @(if (>= $numargs 2) [result $arg2] [result [ #define mpos vvertex ]]) gl_Position = modelmatrix * mpos; color = vcolor; } ] ] shader 0 notexturemodel (notexturemodelvertexshader) [ varying vec4 color; void main(void) { gl_FragColor = color; } ] loop i 4 [ variantshader 0 notexturemodel 0 (notexturemodelvertexshader (skelanimdefs (+ $i 1)) (skelanim (+ $i 1))) [] ] // mdltype: // n -> normalmap // s -> spec // m -> masks // b -> dual-quat skeletal animation // a -> alpha-tested // q -> qtangents mdlopt = [ >= (strstr $modeltype $arg1) 0 ] modelvertexshader = [ modeltype = $arg1 result [ @(if (mdlopt "b") [skelanimdefs $arg2 (mdlopt "q") (mdlopt "n")]) //:fog attribute vec4 vvertex, vcolor; attribute vec2 vtexcoord0; @(if (mdlopt "q") [result [ attribute vec4 vtangent; ]] [result [ attribute vec3 vnormal; ]]) uniform mat4 modelmatrix; uniform vec3 modelcamera, lightdir, lightscale; uniform vec2 texscroll; varying vec2 texcoord0; varying vec4 color; @(if (mdlopt "n") [result [ @(if (mdlopt "e") [result [ uniform mat3 modelworld; varying vec3 camvec; varying mat3 world; ]] [result [ varying vec3 lightvec, halfangle; ]]) ]] [result [ @(if (mdlopt "s") [result [ varying vec3 nvec, halfangle; ]]) @(if (mdlopt "e") [result [ uniform mat3 modelworld; varying vec3 rvec; varying float rmod; ]]) ]]) void main(void) { @(if (mdlopt "b") [result [ @(skelanim $arg2 (mdlopt "q") (mdlopt "n")) ]] [result [ #define mpos vvertex @(if (mdlopt "q") [result [ #define mquat vtangent @(qtangentdecode (mdlopt "n")) ]] [result [ #define mnormal vnormal ]]) ]]) gl_Position = modelmatrix * mpos; @(if (|| (mdlopt "n") (mdlopt "s") (mdlopt "i")) [result [ color = vcolor; ]]) texcoord0 = vtexcoord0 + texscroll; @(if (|| (mdlopt "e") (mdlopt "s")) [result [ vec3 camdir = normalize(modelcamera - mpos.xyz); ]]) @(if (mdlopt "n") [ if (mdlopt "e") [result [ camvec = modelworld * camdir; // 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); ]] [result [ vec3 mbitangent = cross(mnormal, mtangent) * (vtangent.w < 0.0 ? -1.0 : 1.0); lightvec = vec3(dot(lightdir, mtangent), dot(lightdir, mbitangent), dot(lightdir, mnormal)); @(if (mdlopt "s") [result [ vec3 halfdir = lightdir + camdir; halfangle = vec3(dot(halfdir, mtangent), dot(halfdir, mbitangent), dot(halfdir, mnormal)); ]]) ]] ] [result [ @(if (mdlopt "s") [result [ nvec = mnormal; halfangle = lightdir + camdir; ]] [if (! (mdlopt "i")) [result [ float intensity = dot(mnormal, lightdir); color = vec4(vcolor.rgb*clamp(intensity*(intensity*lightscale.x + lightscale.y) + lightscale.z, 0.0, 1.0), vcolor.a); ]]]) @(if (mdlopt "e") [result [ float invfresnel = dot(camdir, mnormal); rvec = modelworld * (2.0*invfresnel*mnormal - camdir); ]]) ]]) } ] ] modelfragmentshader = [ modeltype = $arg1 result [ varying vec2 texcoord0; varying vec4 color; @(if (mdlopt "n") [result [ @(if (mdlopt "e") [result [ #define lightvec lightdirworld uniform vec3 lightdirworld; varying vec3 camvec; varying mat3 world; ]] [result [ varying vec3 lightvec, halfangle; ]]) ]] [result [ @(if (mdlopt "s") [result [ #define lightvec lightdir uniform vec3 lightdir; varying vec3 nvec, halfangle; ]]) @(if (mdlopt "e") [result [ varying vec3 rvec; varying float rmod; ]]) ]]) @(if (&& (|| (mdlopt "s") (mdlopt "n")) (! (mdlopt "i"))) [result [uniform vec3 lightscale;]]) @(if (|| (mdlopt "s") (mdlopt "m")) [result [uniform vec4 maskscale;]]) uniform sampler2D tex0; @(if (mdlopt "m") [result [uniform sampler2D tex1;]]) @(if (mdlopt "e") [result [uniform samplerCube tex2;]]) @(if (mdlopt "n") [result [uniform sampler2D tex3;]]) @(? (mdlopt "a") [uniform float alphatest;]) void main(void) { vec4 light = texture2D(tex0, texcoord0); @(? (mdlopt "a") [ if(light.a <= alphatest) discard; ]) light.rgb *= 2.0; @(if (mdlopt "n") [result [ vec3 normal = texture2D(tex3, texcoord0).rgb - 0.5; @(if (mdlopt "e") [result [ normal = world * normal; ]]) normal = normalize(normal); ]]) @(if (mdlopt "s") [result [ @(if (mdlopt "n") [ if (mdlopt "e") [result [ vec3 halfangle = lightvec + camvec; ]] ] [result [ vec3 normal = normalize(nvec); ]]) float spec = maskscale.x * pow(clamp(dot(normalize(halfangle), normal), 0.0, 1.0), @(? (mdlopt "i") "256.0" "128.0")); @(if (mdlopt "m") [result [spec *= masks.r;]]) // specmap in red channel ]]) @(if (mdlopt "i") [ if (mdlopt "s") [result [ spec *= maskscale.z; @(? (mdlopt "m") "light.rgb" "gl_FragColor.rgb") = spec * color.rgb; ]] [ if (! (mdlopt "m")) [result [gl_FragColor.rgb = vec3(0.0);]] ] ] [result [ @(if (|| (mdlopt "s") (mdlopt "n")) [result [ float intensity = dot(normal, lightvec); light.rgb *= clamp(intensity*(intensity*lightscale.x + lightscale.y) + lightscale.z, 0.0, 1.0); ]]) @(if (mdlopt "s") [result [ light.rgb += spec; ]]) @(if (|| (mdlopt "m") (mdlopt "e")) [result [ light.rgb *= color.rgb; ]] [result [ gl_FragColor = light * color; ]]) ]]) @(if (mdlopt "e") [result [ @(if (mdlopt "n") [result [ vec3 camn = normalize(camvec); float invfresnel = dot(camn, normal); vec3 rvec = 2.0*invfresnel*normal - camn; ]]) vec3 reflect = textureCube(tex2, rvec).rgb; @(if (! (mdlopt "m")) [result [ gl_FragColor.rgb = mix(light.rgb, reflect, rmod); ]]) ]]) @(if (|| (mdlopt "i") (mdlopt "m") (mdlopt "e")) [result [ gl_FragColor.a = light.a * color.a; ]]) } ] ] modelshader = [ local shadername shadername = (concatword model $arg1) if (! (isshaderdefined $shadername)) [ shader 0 $shadername (modelvertexshader $arg1) (modelfragmentshader $arg1) loop i 4 [ variantshader 0 $shadername 0 (modelvertexshader (concatword $arg1 "b") (+ $i 1)) [] ] if (>= (strstr $arg1 "e") 0) [ altshader $shadername (modelshader (strreplace $arg1 "e")) ] if (>= (strstr $arg1 "s") 0) [ fastshader $shadername (modelshader (strreplace $arg1 "s")) 1 ] ] result $shadername ] //////////////////////////////////////////////// // // separable blur with up to 7 taps // //////////////////////////////////////////////// blurshader = [ shader 0 $arg1 [ attribute vec4 vvertex; @(screentexcoord 0) uniform float offsets[8]; varying vec2 texcoord0, texcoordp1, texcoordn1; @(loopconcat i (min (- $arg2 1) 2) [result [ varying vec2 texcoordp@(+ $i 2), texcoordn@(+ $i 2); ]]) void main(void) { gl_Position = vvertex; texcoord0 = vtexcoord0; vec2 tcp = vtexcoord0, tcn = vtexcoord0; tcp.@arg3 += offsets[1]; tcn.@arg3 -= offsets[1]; texcoordp1 = tcp; texcoordn1 = tcn; @(loopconcat i (min (- $arg2 1) 2) [result [ tcp.@arg3 = vtexcoord0.@arg3 + offsets[@@(+ $i 2)]; tcn.@arg3 = vtexcoord0.@arg3 - offsets[@@(+ $i 2)]; texcoordp@(+ $i 2) = tcp; texcoordn@(+ $i 2) = tcn; ]]) } ] [ uniform float weights[8]; uniform float offsets[8]; varying vec2 texcoord0, texcoordp1, texcoordn1; @(loopconcat i (min (- $arg2 1) 2) [result [ varying vec2 texcoordp@(+ $i 2), texcoordn@(+ $i 2); ]]) uniform sampler2D tex0; void main(void) { #define texval(coords) texture2D(tex0, (coords)) vec4 val = texval(texcoord0) * weights[0]; @(loopconcat i $arg2 [ if (< $i 3) [result [ val += weights[@@(+ $i 1)] * (texval(texcoordp@(+ $i 1)) + texval(texcoordn@(+ $i 1))); ]] [result [ val += weights[@@(+ $i 1)] * @(if (=s $arg3 "x") [result [ (texval(vec2(texcoord0.x + offsets[@@(+ $i 1)], texcoord0.y)) + texval(vec2(texcoord0.x - offsets[@@(+ $i 1)], texcoord0.y))); ]] [result [ (texval(vec2(texcoord0.x, texcoord0.y + offsets[@@(+ $i 1)])) + texval(vec2(texcoord0.x, texcoord0.y - offsets[@@(+ $i 1)]))); ]]) ]] ]) gl_FragColor = val; } ] ] loop i 7 [ blurshader (format "blurx%1" (+ $i 1)) (+ $i 1) x blurshader (format "blury%1" (+ $i 1)) (+ $i 1) y if (> $i 0) [ altshader (format "blurx%1" (+ $i 1)) (format "blurx%1" $i) altshader (format "blury%1" (+ $i 1)) (format "blury%1" $i) ] ] blur3shader = [ lazyshader 0 $arg1 [ attribute vec4 vvertex; @(screentexcoord 0) uniform vec2 postfxscale; varying vec2 texcoord0, texcoord1; void main(void) { gl_Position = vvertex; texcoord0 = vtexcoord0 + vec2(@(if $arg2 -0.5 0.0), @(if $arg3 -0.5 0.0))*postfxscale; texcoord1 = vtexcoord0 + vec2(@(if $arg2 0.5 0.0), @(if $arg3 0.5 0.0))*postfxscale; } ] [ varying vec2 texcoord0, texcoord1; uniform sampler2D tex0; void main(void) { gl_FragColor = 0.5*(texture2D(tex0, texcoord0) + texture2D(tex0, texcoord1)); } ] ] blur3shader hblur3 1 0 blur3shader vblur3 0 1 blur5shader = [ lazyshader 0 $arg1 [ attribute vec4 vvertex; @(screentexcoord 0) uniform vec2 postfxscale; varying vec2 texcoord0, texcoord1, texcoord2; void main(void) { gl_Position = vvertex; texcoord0 = vtexcoord0; texcoord1 = vtexcoord0 + vec2(@(? $arg2 -1.333 0.0), @(? $arg3 -1.333 0.0))*postfxscale; texcoord2 = vtexcoord0 + vec2(@(? $arg2 1.333 0.0), @(? $arg3 1.333 0.0))*postfxscale; } ] [ uniform sampler2D tex0; varying vec2 texcoord0, texcoord1, texcoord2; void main(void) { gl_FragColor = 0.4*texture2D(tex0, texcoord0) + 0.3*(texture2D(tex0, texcoord1) + texture2D(tex0, texcoord2)); } ] ] blur5shader hblur5 1 0 blur5shader vblur5 0 1 //////////////////////////////////////////////// // // miscellaneous effect shaders: // //////////////////////////////////////////////// // wobbles the vertices of an explosion sphere // and generates all texcoords // and blends the edge color // and modulates the texture explosionshader = [ shader 0 $arg1 [ //:fog attribute vec4 vvertex, vcolor; attribute vec2 vtexcoord0; uniform mat4 explosionmatrix; uniform vec3 center; uniform float millis; uniform vec3 texgenS, texgenT; varying vec4 color; varying vec2 texcoord0, texcoord1, texcoord2; @(if (>= (strstr $arg1 "soft") 0) [result [uniform vec4 depthfxparams; varying vec4 texcoord3; ]]) void main(void) { vec4 wobble = vec4(vvertex.xyz*(1.0 + 0.5*abs(fract(dot(vvertex.xyz, center) + millis*2.0) - 0.5)), vvertex.w); @(if (>= (strstr $arg1 "soft") 0) [result [ gl_Position = explosionmatrix * wobble; texcoord3 = vec4(0.5*(gl_Position.xy + gl_Position.w), gl_Position.w, depthfxparams.y + gl_Position.w*depthfxparams.x); ]] [result [ gl_Position = explosionmatrix * wobble; ]]) color = vcolor; texcoord0 = vtexcoord0; vec2 texgen = vec2(dot(texgenS, vvertex.xyz), dot(texgenT, vvertex.xyz)); texcoord1 = texgen; texcoord2 = 0.5*texgen - millis*0.5; } ] [ @(if (>= (strstr $arg1 "soft") 0) [result [ uniform sampler2D tex2; ]]) uniform sampler2D tex0, tex1; uniform vec2 blendparams; varying vec4 color; varying vec2 texcoord0, texcoord1, texcoord2; @(if (>= (strstr $arg1 "soft") 0) [result [uniform vec4 depthfxparams; varying vec4 texcoord3; ]]) @(if (>= (strstr $arg1 "soft8") 0) [result [uniform vec4 depthfxselect;]]) void main(void) { vec2 dtc = texcoord0 + texture2D(tex0, texcoord2).xy*0.1; // use color texture as noise to distort texcoords vec4 diffuse = texture2D(tex0, dtc); float blend = max(pow(clamp(1.0 - dot(texcoord1, texcoord1), 0.0, 1.0), blendparams.x), blendparams.y); @(if (>= (strstr $arg1 "soft") 0) [result [ gl_FragColor.rgb = diffuse.rgb * color.rgb; #define depthvals texture2DProj(tex2, texcoord3.xyz) @(if (>= (strstr $arg1 "soft8") 0) [result [ float depth = dot(depthvals, depthfxselect); ]] [result [ float depth = depthvals.x*depthfxparams.z; ]]) gl_FragColor.a = diffuse.a * max(clamp(depth - texcoord3.w, 0.0, 1.0) * color.a, depthfxparams.w); ]] [result [ gl_FragColor = diffuse * color; ]]) } ] ] looplist i ["" "soft" "soft8"] [ explosionshader [explosion@i] ] shader 0 "particlenotexture" [ //:fog attribute vec4 vvertex, vcolor; uniform mat4 camprojmatrix; uniform vec4 colorscale; varying vec4 color; void main(void) { gl_Position = camprojmatrix * vvertex; color = vcolor * colorscale; } ] [ varying vec4 color; void main(void) { gl_FragColor = color; } ] particleshader = [ shader 0 $arg1 [ //:fog attribute vec4 vvertex, vcolor; attribute vec2 vtexcoord0; uniform mat4 camprojmatrix; uniform vec4 colorscale; varying vec2 texcoord0; varying vec4 color; @(if (>= (strstr $arg1 "soft") 0) [result [uniform vec4 depthfxparams; varying vec3 texcoord1, surface; ]]) void main(void) { gl_Position = camprojmatrix * vvertex; texcoord0 = vtexcoord0; color = vcolor * colorscale; @(if (>= (strstr $arg1 "soft") 0) [result [ texcoord1 = vec3(0.5*(gl_Position.xy + gl_Position.w), gl_Position.w); vec2 offset = vtexcoord0*2.82842712474619 - 1.4142135623731; surface = vec3(offset, depthfxparams.y + gl_Position.w*depthfxparams.x); ]]) } ] [ @(if (>= (strstr $arg1 "soft") 0) [result [ uniform sampler2D tex2; ]]) uniform sampler2D tex0; varying vec2 texcoord0; varying vec4 color; @(if (>= (strstr $arg1 "soft") 0) [result [uniform vec4 depthfxparams; varying vec3 texcoord1, surface;]]) @(if (>= (strstr $arg1 "soft8") 0) [result [uniform vec4 depthfxselect;]]) void main(void) { vec4 diffuse = texture2D(tex0, texcoord0); @(if (>= (strstr $arg1 "soft") 0) [result [ #define depthvals texture2DProj(tex2, texcoord1) @(if (>= (strstr $arg1 "soft8") 0) [result [ float depth = dot(depthvals, depthfxselect); ]] [result [ float depth = depthvals.x*depthfxparams.z; ]]) diffuse.a *= clamp(depth - dot(surface.xy, surface.xy) - surface.z, 0.0, 1.0); ]]) gl_FragColor = diffuse * color; } ] ] looplist i ["" "soft" "soft8"] [ particleshader [particle@i] ] lazyshader 0 "prefab" [ attribute vec4 vvertex, vcolor; attribute vec3 vnormal; uniform mat4 prefabmatrix; uniform mat3 prefabworld; varying vec4 color; void main(void) { gl_Position = prefabmatrix * vvertex; color = vcolor; color.rgb *= dot(prefabworld * vnormal, vec3(0.0, -0.447213595, 0.894427191)); } ] [ varying vec4 color; void main(void) { gl_FragColor = color; } ] shader 0 "overbrightdecal" [ attribute vec4 vvertex, vcolor; attribute vec2 vtexcoord0; uniform mat4 camprojmatrix; varying vec4 color; varying vec2 texcoord0; void main(void) { gl_Position = camprojmatrix * vvertex; color = vcolor; texcoord0 = vtexcoord0; } ] [ varying vec4 color; varying vec2 texcoord0; uniform sampler2D tex0; void main(void) { vec4 diffuse = texture2D(tex0, texcoord0); gl_FragColor = mix(color, diffuse, color.a); } ] shader 0 "saturatedecal" [ attribute vec4 vvertex, vcolor; attribute vec2 vtexcoord0; uniform mat4 camprojmatrix; varying vec4 color; varying vec2 texcoord0; void main(void) { gl_Position = camprojmatrix * vvertex; color = vcolor; texcoord0 = vtexcoord0; } ] [ varying vec4 color; varying vec2 texcoord0; uniform sampler2D tex0; void main(void) { vec4 diffuse = texture2D(tex0, texcoord0); diffuse.rgb *= 2.0; gl_FragColor = diffuse * color; } ]