2012-01-18 02:44:50 +00:00
/*
WARNING : THIS FILE IS GENERATED BY ' generatebuiltinsl . c ' .
YOU SHOULD NOT EDIT THIS FILE BY HAND
*/
2012-05-11 01:57:00 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " altwater " ,
2012-11-27 03:23:19 +00:00
" !!cvarf r_glsl_turbscale \n "
2012-07-05 19:42:36 +00:00
//modifier: REFLECT (s_t2 is a reflection instead of diffusemap)
//modifier: STRENGTH (0.1 = fairly gentle, 0.2 = big waves)
2012-05-11 01:57:00 +00:00
//modifier: FRESNEL (5=water)
2012-07-05 19:42:36 +00:00
//modifier: TXSCALE (0.2 - wave strength)
//modifier: RIPPLEMAP (s_t3 contains a ripplemap
//modifier: TINT (some colour value)
" #ifndef FRESNEL \n "
" #define FRESNEL 5.0 \n "
" #endif \n "
" #ifndef STRENGTH \n "
" #define STRENGTH 0.1 \n "
" #endif \n "
" #ifndef TXSCALE \n "
" #define TXSCALE 0.2 \n "
" #endif \n "
" #ifndef TINT \n "
" #define TINT vec3(0.7, 0.8, 0.7) \n "
" #endif \n "
2013-03-12 23:13:39 +00:00
" #ifndef FOGTINT \n "
" #define FOGTINT vec3(0.2, 0.3, 0.2) \n "
" #endif \n "
2012-05-11 01:57:00 +00:00
" varying vec2 tc; \n "
" varying vec4 tf; \n "
" varying vec3 norm; \n "
" varying vec3 eye; \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" attribute vec3 v_normal; \n "
" uniform vec3 e_eyepos; \n "
" void main (void) \n "
" { \n "
" tc = v_texcoord.st; \n "
" tf = ftetransform(); \n "
" norm = v_normal; \n "
" eye = e_eyepos - v_position.xyz; \n "
" gl_Position = tf; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
2015-03-03 00:14:43 +00:00
" #define s_refract s_t0 \n "
" #define s_reflect s_t1 \n "
" #define s_ripplemap s_t2 \n "
" #define s_refractdepth s_t3 \n "
2014-08-27 08:41:31 +00:00
" uniform float cvar_r_glsl_turbscale; \n "
2015-03-03 07:54:10 +00:00
" uniform sampler2D s_normalmap; \n "
" uniform sampler2D s_diffuse; \n "
2015-03-03 00:14:43 +00:00
" uniform sampler2D s_refract; //refract \n "
" uniform sampler2D s_reflect; //reflection \n "
" uniform sampler2D s_refractdepth; //refraction depth \n "
2013-03-31 04:21:08 +00:00
" uniform sampler2D s_ripplemap; //ripplemap \n "
2012-05-11 01:57:00 +00:00
" uniform float e_time; \n "
" void main (void) \n "
" { \n "
" vec2 stc, ntc; \n "
2013-03-12 23:13:39 +00:00
" vec3 n, refr, refl; \n "
" float fres; \n "
" float depth; \n "
2012-05-11 01:57:00 +00:00
" stc = (1.0 + (tf.xy / tf.w)) * 0.5; \n "
2013-03-12 23:13:39 +00:00
//hack the texture coords slightly so that there are no obvious gaps
" stc.t -= 1.5*norm.z/1080.0; \n "
2012-05-11 01:57:00 +00:00
//apply q1-style warp, just for kicks
" ntc.s = tc.s + sin(tc.t+e_time)*0.125; \n "
" ntc.t = tc.t + sin(tc.s+e_time)*0.125; \n "
//generate the two wave patterns from the normalmap
2015-03-03 00:14:43 +00:00
" n = (texture2D(s_normalmap, TXSCALE*tc + vec2(e_time*0.1, 0.0)).xyz); \n "
" n += (texture2D(s_normalmap, TXSCALE*tc - vec2(0, e_time*0.097)).xyz); \n "
2012-05-11 01:57:00 +00:00
" n -= 1.0 - 4.0/256.0; \n "
2012-07-05 19:42:36 +00:00
" #ifdef RIPPLEMAP \n "
2013-03-31 04:21:08 +00:00
" n += texture2D(s_ripplemap, stc).rgb*3.0; \n "
2012-05-11 01:57:00 +00:00
" #endif \n "
2012-07-05 19:42:36 +00:00
//the fresnel term decides how transparent the water should be
2013-03-12 23:13:39 +00:00
" fres = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL)); \n "
" #ifdef DEPTH \n "
" float far = #include \" cvar/gl_maxdist \" ; \n "
" float near = #include \" cvar/gl_mindist \" ; \n "
//get depth value at the surface
" float sdepth = gl_FragCoord.z; \n "
" sdepth = (2.0*near) / (far + near - sdepth * (far - near)); \n "
" sdepth = mix(near, far, sdepth); \n "
//get depth value at the ground beyond the surface.
2015-03-03 00:14:43 +00:00
" float gdepth = texture2D(s_refractdepth, stc).x; \n "
2013-03-12 23:13:39 +00:00
" gdepth = (2.0*near) / (far + near - gdepth * (far - near)); \n "
" if (gdepth >= 0.5) \n "
" { \n "
" gdepth = sdepth; \n "
" depth = 0.0; \n "
" } \n "
" else \n "
" { \n "
" gdepth = mix(near, far, gdepth); \n "
" depth = gdepth - sdepth; \n "
" } \n "
//reduce the normals in shallow water (near walls, reduces the pain of linear sampling)
2013-03-12 23:14:23 +00:00
" if (depth < 100.0) \n "
2013-03-12 23:13:39 +00:00
" n *= depth/100.0; \n "
" #else \n "
2013-03-12 23:14:23 +00:00
" depth = 1.0; \n "
2013-03-12 23:13:39 +00:00
" #endif \n "
2012-07-05 19:42:36 +00:00
2013-03-12 23:13:39 +00:00
//refraction image (and water fog, if possible)
2015-03-03 00:14:43 +00:00
" refr = texture2D(s_refract, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT; \n "
2013-03-12 23:13:39 +00:00
" #ifdef DEPTH \n "
2013-03-12 23:14:23 +00:00
" refr = mix(refr, FOGTINT, min(depth/4096.0, 1.0)); \n "
2013-03-12 23:13:39 +00:00
" #endif \n "
//reflection/diffuse
2012-05-11 01:57:00 +00:00
" #ifdef REFLECT \n "
2015-03-03 00:14:43 +00:00
" refl = texture2D(s_reflect, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb; \n "
2012-05-11 01:57:00 +00:00
" #else \n "
2015-03-03 00:14:43 +00:00
" refl = texture2D(s_diffuse, ntc).xyz; \n "
2012-05-11 01:57:00 +00:00
" #endif \n "
2013-03-12 23:13:39 +00:00
//FIXME: add specular
2012-05-11 01:57:00 +00:00
2013-03-12 23:13:39 +00:00
//interplate by fresnel
" refr = mix(refr, refl, fres); \n "
2012-07-05 19:42:36 +00:00
2013-03-12 23:13:39 +00:00
//done
" gl_FragColor = vec4(refr, 1.0); \n "
2012-05-11 01:57:00 +00:00
" } \n "
" #endif \n "
} ,
# endif
2012-01-18 02:44:50 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " bloom_blur " ,
//apply gaussian filter
" varying vec2 tc; \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
/*offset should be 1.2 pixels away from the center*/
" uniform vec3 e_glowmod; \n "
" uniform sampler2D s_t0; \n "
" void main () \n "
" { \n "
" gl_FragColor = \n "
" 0.3125 * texture2D(s_t0, tc - e_glowmod.st) + \n "
" 0.375 * texture2D(s_t0, tc) + \n "
" 0.3125 * texture2D(s_t0, tc + e_glowmod.st); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " bloom_filter " ,
2012-05-11 01:57:00 +00:00
" !!cvarv r_bloom_filter \n "
2012-01-18 02:44:50 +00:00
//the bloom filter
//filter out any texels which are not to bloom
" varying vec2 tc; \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
2014-08-27 08:41:31 +00:00
" uniform vec3 cvar_r_bloom_filter; \n "
2012-01-18 02:44:50 +00:00
" uniform sampler2D s_t0; \n "
" void main () \n "
" { \n "
2012-05-11 01:57:00 +00:00
" gl_FragColor.rgb = (texture2D(s_t0, tc).rgb - cvar_r_bloom_filter)/(1.0-cvar_r_bloom_filter); \n "
2012-01-18 02:44:50 +00:00
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " bloom_final " ,
2012-05-11 01:57:00 +00:00
" !!cvarf r_bloom \n "
2012-01-18 02:44:50 +00:00
//add them together
//optionally apply tonemapping
" varying vec2 tc; \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" uniform sampler2D s_t1; \n "
" uniform sampler2D s_t2; \n "
" uniform sampler2D s_t3; \n "
2014-08-27 08:41:31 +00:00
" uniform float cvar_r_bloom; \n "
2012-01-18 02:44:50 +00:00
" void main () \n "
" { \n "
" gl_FragColor = \n "
" texture2D(s_t0, tc) + \n "
2012-05-11 01:57:00 +00:00
" cvar_r_bloom*( \n "
2012-01-18 02:44:50 +00:00
" texture2D(s_t1, tc) + \n "
" texture2D(s_t2, tc) + \n "
2012-05-11 01:57:00 +00:00
" texture2D(s_t3, tc) \n "
" ) ; \n "
2012-01-18 02:44:50 +00:00
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " colourtint " ,
//this glsl shader is useful for cubemapped post processing effects (see csaddon for an example)
" varying vec4 tf; \n "
" #ifdef VERTEX_SHADER \n "
" void main () \n "
" { \n "
" gl_Position = tf = vec4(v_position.xy,-1.0, 1.0); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" uniform sampler3D s_t1; \n "
" void main() \n "
" { \n "
" vec2 fc; \n "
" fc = tf.xy / tf.w; \n "
" vec3 raw = texture2D(s_t0, (1.0 + fc) / 2.0).rgb; \n "
" #define LUTSIZE 16.0 \n "
" vec3 scale = vec3((LUTSIZE-1.0)/LUTSIZE); \n "
" vec3 bias = vec3(1.0/(2.0*LUTSIZE)); \n "
" gl_FragColor = texture3D(s_t1, raw * scale + bias); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " crepuscular_opaque " ,
//opaque surfaces are drawn to the render target to mask out skies
" #ifdef VERTEX_SHADER \n "
" void main () \n "
" { \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" void main() \n "
" { \n "
" gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " crepuscular_rays " ,
" !!cvarf crep_decay \n "
" !!cvarf crep_density \n "
" !!cvarf crep_weight \n "
//this is a post-processing shader, drawn in 2d
//there will be a render target containing sky surfaces drawn with crepuscular_sky, and everything else drawn with crepuscular_opaque (to mask out the sky)
//this shader then just smudges the sky out a bit as though its coming from the sun or whatever through the clouds.
//yoinked from http://fabiensanglard.net/lightScattering/index.php
" varying vec2 tc; \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
2015-01-21 18:18:37 +00:00
" gl_Position = vec4(v_position, 1.0); \n "
2012-05-09 15:30:53 +00:00
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" const float crep_decay = 0.94; \n "
" const float crep_density = 0.5; \n "
" const float crep_weight = 0.2; \n "
" uniform vec3 l_lightcolour; \n "
" uniform vec3 l_lightscreen; \n "
" uniform sampler2D s_t0; \n "
" const int NUM_SAMPLES = 100; \n "
" void main() \n "
" { \n "
" vec2 deltaTextCoord = vec2(tc.st - l_lightscreen.xy); \n "
" vec2 textCoo = tc.st; \n "
" deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * crep_density; \n "
" float illuminationDecay = 1.0; \n "
2015-01-21 18:18:37 +00:00
" gl_FragColor = vec4(0.0,0.0,0.0,0.0); \n "
2012-05-09 15:30:53 +00:00
" for(int i=0; i < NUM_SAMPLES ; i++) \n "
" { \n "
" textCoo -= deltaTextCoord; \n "
" vec4 sample = texture2D(s_t0, textCoo); \n "
" sample *= illuminationDecay * crep_weight; \n "
" gl_FragColor += sample; \n "
" illuminationDecay *= crep_decay; \n "
" } \n "
" gl_FragColor *= vec4(l_lightcolour, 1.0); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " crepuscular_sky " ,
//pretty much a regular sky shader
//though in reality we should render a sun circle in the middle.
//still, its kinda cool to have scrolling clouds masking out parts of the sun.
" #ifdef VERTEX_SHADER \n "
" varying vec3 pos; \n "
" void main () \n "
" { \n "
" pos = v_position.xyz; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform float e_time; \n "
" uniform vec3 e_eyepos; \n "
" varying vec3 pos; \n "
" uniform sampler2D s_t0; \n "
" uniform sampler2D s_t1; \n "
" void main () \n "
" { \n "
" vec2 tccoord; \n "
" vec3 dir = pos - e_eyepos; \n "
" dir.z *= 3.0; \n "
" dir.xy /= 0.5*length(dir); \n "
" tccoord = (dir.xy + e_time*0.03125); \n "
" vec3 solid = vec3(texture2D(s_t0, tccoord)); \n "
" tccoord = (dir.xy + e_time*0.0625); \n "
" vec4 clouds = texture2D(s_t1, tccoord); \n "
" gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb); \n "
" } \n "
" #endif \n "
2013-10-08 14:28:11 +00:00
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " depthonly " ,
" !!permu FRAMEBLEND \n "
" !!permu SKELETAL \n "
//standard shader used for drawing shadowmap depth.
//also used for masking off portals and other things that want depth and no colour.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
" #ifdef VERTEX_SHADER \n "
" #include \" sys/skeletal.h \" \n "
" void main () \n "
" { \n "
" gl_Position = skeletaltransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" void main () \n "
" { \n "
//must always draw something, supposedly. It might as well be black.
" gl_FragColor = vec4(0, 0, 0, 1); \n "
" } \n "
" #endif \n "
2013-11-10 21:14:28 +00:00
} ,
# endif
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " depthonly " ,
//used for generating shadowmaps and stuff that draws nothing.
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float3 normal: NORMAL; \n "
2014-03-30 08:55:06 +00:00
" #ifdef MASK \n "
" float4 tc: TEXCOORD0; \n "
" #endif \n "
2013-11-10 21:14:28 +00:00
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
2014-03-30 08:55:06 +00:00
" #ifdef MASK \n "
" float2 tc: TEXCOORD0; \n "
" #endif \n "
2013-11-10 21:14:28 +00:00
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
2014-03-30 08:55:06 +00:00
" #ifdef MASK \n "
" outp.tc = inp.tc.xy; \n "
" #endif \n "
2013-11-10 21:14:28 +00:00
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
2014-03-30 08:55:06 +00:00
" #ifdef MASK \n "
" Texture2D shaderTexture[1]; \n "
" SamplerState SampleType[1]; \n "
" #endif \n "
" #if LEVEL < 1000 \n "
//pre dx10 requires that we ALWAYS write to a target.
" float4 main (v2f inp) : SV_TARGET \n "
" #else \n "
//but on 10, it'll write depth automatically and we don't care about colour.
" void main (v2f inp) //dx10-level \n "
" #endif \n "
2013-11-10 21:14:28 +00:00
" { \n "
2014-03-30 08:55:06 +00:00
" #ifdef MASK \n "
" float alpha = shaderTexture[0].Sample(SampleType[0], inp.tc).a; \n "
" #ifndef MASKOP \n "
" #define MASKOP >= //drawn if (alpha OP ref) is true. \n "
" #endif \n "
//support for alpha masking
" if (!(alpha MASKOP MASK)) \n "
" discard; \n "
" #endif \n "
" #if LEVEL < 1000 \n "
" return float4(0, 0, 0, 1); \n "
" #endif \n "
2013-11-10 21:14:28 +00:00
" } \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " default2d " ,
//this shader is present for support for gles/gl3core contexts
//it is single-texture-with-vertex-colours, and doesn't do anything special.
//beware that a few things use this, including apparently fonts and bloom rescaling.
//its really not meant to do anything special.
2012-09-30 05:52:03 +00:00
" varying vec2 tc; \n "
" varying vec4 vc; \n "
2012-05-09 15:30:53 +00:00
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" attribute vec4 v_colour; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
" vc = v_colour; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" void main () \n "
" { \n "
2015-02-02 08:01:53 +00:00
" vec4 f = vc; \n "
" #ifdef PREMUL \n "
" f.rgb *= f.a; \n "
" #endif \n "
" f *= texture2D(s_t0, tc); \n "
" gl_FragColor = f; \n "
2012-05-09 15:30:53 +00:00
" } \n "
" #endif \n "
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " default2d " ,
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float4 vcol: COLOR0; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float4 vcol: COLOR0; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
2014-03-30 08:55:06 +00:00
" outp.pos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
2012-11-27 03:23:19 +00:00
" outp.tc = inp.tc; \n "
" outp.vcol = inp.vcol; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" Texture2D shaderTexture; \n "
" SamplerState SampleType; \n "
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
" return shaderTexture.Sample(SampleType, inp.tc) * inp.vcol; \n "
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " defaultadditivesprite " ,
" !!permu FOG \n "
//meant to be used for additive stuff. presumably particles and sprites. though actually its only flashblend effects that use this at the time of writing.
//includes fog, apparently.
" #include \" sys/fog.h \" \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" attribute vec4 v_colour; \n "
" varying vec2 tc; \n "
" varying vec4 vc; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
" vc = v_colour; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" varying vec2 tc; \n "
" varying vec4 vc; \n "
" uniform vec4 e_colourident; \n "
" void main () \n "
" { \n "
" gl_FragColor = fog4additive(texture2D(s_t0, tc) * vc * e_colourident); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " defaultskin " ,
" !!permu FULLBRIGHT \n "
" !!permu UPPERLOWER \n "
" !!permu FRAMEBLEND \n "
" !!permu SKELETAL \n "
" !!permu FOG \n "
2013-03-12 23:14:57 +00:00
" !!permu BUMP \n "
2013-03-12 22:35:33 +00:00
" !!cvarf r_glsl_offsetmapping_scale \n "
" !!cvarf gl_specular \n "
2012-05-09 15:30:53 +00:00
2015-03-03 00:14:43 +00:00
" #include \" sys/defs.h \" \n "
2012-05-09 15:30:53 +00:00
//standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
" varying vec2 tc; \n "
" varying vec3 light; \n "
2013-03-12 22:35:33 +00:00
" #if defined(SPECULAR) || defined(OFFSETMAPPING) \n "
" varying vec3 eyevector; \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" #ifdef VERTEX_SHADER \n "
" #include \" sys/skeletal.h \" \n "
" void main () \n "
" { \n "
2013-03-12 22:35:33 +00:00
" #if defined(SPECULAR)||defined(OFFSETMAPPING) \n "
" vec3 n, s, t, w; \n "
" gl_Position = skeletaltransform_wnst(w,n,s,t); \n "
" vec3 eyeminusvertex = e_eyepos - w.xyz; \n "
2014-01-13 02:42:25 +00:00
" eyevector.x = dot(eyeminusvertex, s.xyz); \n "
2013-03-12 22:35:33 +00:00
" eyevector.y = dot(eyeminusvertex, t.xyz); \n "
" eyevector.z = dot(eyeminusvertex, n.xyz); \n "
" #else \n "
2012-05-09 15:30:53 +00:00
" vec3 n; \n "
" gl_Position = skeletaltransform_n(n); \n "
2013-03-12 22:35:33 +00:00
" #endif \n "
2014-08-15 02:20:41 +00:00
" float d = dot(n,e_light_dir); \n "
" if (d < 0.0) //vertex shader. this might get ugly, but I don't really want to make it per vertex. \n "
" d = 0.0; //this avoids the dark side going below the ambient level. \n "
2012-05-09 15:30:53 +00:00
" light = e_light_ambient + (dot(n,e_light_dir)*e_light_mul); \n "
" tc = v_texcoord; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" #include \" sys/fog.h \" \n "
2013-03-12 23:14:57 +00:00
" #if defined(SPECULAR) \n "
2013-03-12 22:35:33 +00:00
" uniform float cvar_gl_specular; \n "
" #endif \n "
" #ifdef OFFSETMAPPING \n "
" #include \" sys/offsetmapping.h \" \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" void main () \n "
" { \n "
" vec4 col, sp; \n "
2013-03-12 22:35:33 +00:00
" #ifdef OFFSETMAPPING \n "
2015-03-03 00:14:43 +00:00
" vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector); \n "
2013-03-12 22:35:33 +00:00
" #define tc tcoffsetmap \n "
" #endif \n "
2015-03-03 00:14:43 +00:00
" col = texture2D(s_diffuse, tc); \n "
2012-05-09 15:30:53 +00:00
" #ifdef UPPER \n "
2015-03-03 00:14:43 +00:00
" vec4 uc = texture2D(s_upper, tc); \n "
2013-03-12 22:35:33 +00:00
" col.rgb += uc.rgb*e_uppercolour*uc.a; \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
" #ifdef LOWER \n "
2015-03-03 00:14:43 +00:00
" vec4 lc = texture2D(s_lower, tc); \n "
2013-03-12 22:35:33 +00:00
" col.rgb += lc.rgb*e_lowercolour*lc.a; \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
2013-03-12 22:35:33 +00:00
2013-03-12 23:14:57 +00:00
" #if defined(BUMP) && defined(SPECULAR) \n "
2015-03-03 00:14:43 +00:00
" vec3 bumps = normalize(vec3(texture2D(s_normalmap, tc)) - 0.5); \n "
" vec4 specs = texture2D(s_specular, tc); \n "
2013-03-12 22:35:33 +00:00
" vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); \n "
" float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a); \n "
" col.rgb += cvar_gl_specular * spec * specs.rgb; \n "
" #endif \n "
2014-10-05 20:04:11 +00:00
" col.rgb *= light; \n "
2012-05-09 15:30:53 +00:00
" #ifdef FULLBRIGHT \n "
2015-03-03 00:14:43 +00:00
" vec4 fb = texture2D(s_fullbright, tc); \n "
2013-03-12 23:14:57 +00:00
// col.rgb = mix(col.rgb, fb.rgb, fb.a);
" col.rgb += fb.rgb * fb.a; \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
2013-03-12 22:35:33 +00:00
2012-05-09 15:30:53 +00:00
" gl_FragColor = fog4(col * e_colourident); \n "
" } \n "
" #endif \n "
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " defaultskin " ,
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float4 tc: TEXCOORD0; \n "
" float3 normal: NORMAL; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float3 light: TEXCOORD1; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
//attribute vec2 v_texcoord;
//uniform vec3 e_light_dir;
//uniform vec3 e_light_mul;
//uniform vec3 e_light_ambient;
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
" outp.light = e_light_ambient + (dot(inp.normal,e_light_dir)*e_light_mul); \n "
" outp.tc = inp.tc.xy; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" Texture2D shaderTexture[4]; //diffuse, lower, upper, fullbright \n "
" SamplerState SampleType; \n "
//uniform vec4 e_colourident;
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
" float4 col; \n "
" col = shaderTexture[0].Sample(SampleType, inp.tc); \n "
2014-03-30 08:55:06 +00:00
" #ifdef MASK \n "
" #ifndef MASKOP \n "
" #define MASKOP >= //drawn if (alpha OP ref) is true. \n "
" #endif \n "
//support for alpha masking
" if (!(col.a MASKOP MASK)) \n "
" discard; \n "
" #endif \n "
2012-11-27 03:23:19 +00:00
" #ifdef UPPER \n "
" float4 uc = shaderTexture[2].Sample(SampleType, inp.tc); \n "
" col.rgb = mix(col.rgb, uc.rgb*e_uppercolour, uc.a); \n "
" #endif \n "
" #ifdef LOWER \n "
" float4 lc = shaderTexture[1].Sample(SampleType, inp.tc); \n "
" col.rgb = mix(col.rgb, lc.rgb*e_lowercolour, lc.a); \n "
" #endif \n "
" col.rgb *= inp.light; \n "
" #ifdef FULLBRIGHT \n "
" float4 fb = shaderTexture[3].Sample(SampleType, inp.tc); \n "
" col.rgb = mix(col.rgb, fb.rgb, fb.a); \n "
" #endif \n "
" return col; \n "
// return fog4(col * e_colourident);
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " defaultsky " ,
//regular sky shader for scrolling q1 skies
//the sky surfaces are thrown through this as-is.
" #ifdef VERTEX_SHADER \n "
" varying vec3 pos; \n "
" void main () \n "
" { \n "
" pos = v_position.xyz; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform float e_time; \n "
" uniform vec3 e_eyepos; \n "
" varying vec3 pos; \n "
" uniform sampler2D s_t0; \n "
" uniform sampler2D s_t1; \n "
" void main () \n "
" { \n "
" vec2 tccoord; \n "
" vec3 dir = pos - e_eyepos; \n "
" dir.z *= 3.0; \n "
" dir.xy /= 0.5*length(dir); \n "
" tccoord = (dir.xy + e_time*0.03125); \n "
" vec3 solid = vec3(texture2D(s_t0, tccoord)); \n "
" tccoord = (dir.xy + e_time*0.0625); \n "
" vec4 clouds = texture2D(s_t1, tccoord); \n "
" gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb); \n "
" } \n "
" #endif \n "
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D9QUAKE
{ QR_DIRECT3D9 , 9 , " defaultsky " ,
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" }; \n "
" struct v2f \n "
" { \n "
" #ifndef FRAGMENT_SHADER \n "
" float4 pos: POSITION; \n "
" #endif \n "
" float3 vpos: TEXCOORD0; \n "
" }; \n "
" #ifdef VERTEX_SHADER \n "
" float4x4 m_modelviewprojection; \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_modelviewprojection, inp.pos); \n "
" outp.vpos = inp.pos; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" float e_time; \n "
" float3 e_eyepos; \n "
" float l_lightradius; \n "
" float3 l_lightcolour; \n "
" float3 l_lightposition; \n "
2015-03-03 00:14:43 +00:00
" sampler s_diffuse; /*diffuse*/ \n "
" sampler s_fullbright; /*normal*/ \n "
2012-11-27 03:23:19 +00:00
" float4 main (v2f inp) : COLOR0 \n "
" { \n "
" float2 tccoord; \n "
" float3 dir = inp.vpos - e_eyepos; \n "
" dir.z *= 3.0; \n "
" dir.xy /= 0.5*length(dir); \n "
" tccoord = (dir.xy + e_time*0.03125); \n "
2015-03-03 00:14:43 +00:00
" float4 solid = tex2D(s_diffuse, tccoord); \n "
2012-11-27 03:23:19 +00:00
" tccoord = (dir.xy + e_time*0.0625); \n "
2015-03-03 00:14:43 +00:00
" float4 clouds = tex2D(s_fullbright, tccoord); \n "
2012-11-27 03:23:19 +00:00
" return float4((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb), 1); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " defaultsky " ,
//regular sky shader for scrolling q1 skies
//the sky surfaces are thrown through this as-is.
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float3 mpos: TEXCOORD1; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_model, inp.pos); \n "
" outp.mpos = outp.pos.xyz; \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
" outp.tc = inp.tc; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" Texture2D shaderTexture[2]; \n "
" SamplerState SampleType; \n "
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
" float2 tccoord; \n "
" float3 dir = inp.mpos - v_eyepos; \n "
" dir.z *= 3.0; \n "
" dir.xy /= 0.5*length(dir); \n "
" tccoord = (dir.xy + e_time*0.03125); \n "
" float4 solid = shaderTexture[0].Sample(SampleType, tccoord); \n "
" tccoord = (dir.xy + e_time*0.0625); \n "
" float4 clouds = shaderTexture[1].Sample(SampleType, tccoord); \n "
" return (solid*(1.0-clouds.a)) + (clouds.a*clouds); \n "
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
2013-03-12 23:09:25 +00:00
{ QR_OPENGL , 110 , " defaultfill " ,
" #ifdef VERTEX_SHADER \n "
" attribute vec4 v_colour; \n "
" varying vec4 vc; \n "
" void main () \n "
" { \n "
" vc = v_colour; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" varying vec4 vc; \n "
" void main () \n "
" { \n "
" gl_FragColor = vc; \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " defaultfill " ,
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float4 vcol: COLOR0; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float4 vcol: COLOR0; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_projection, inp.pos); \n "
" outp.vcol = inp.vcol; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
" return inp.vcol; \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
2012-05-09 15:30:53 +00:00
{ QR_OPENGL , 110 , " defaultsprite " ,
" !!permu FOG \n "
//used by both particles and sprites.
//note the fog blending mode is all that differs from defaultadditivesprite
" #include \" sys/fog.h \" \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" attribute vec4 v_colour; \n "
" varying vec2 tc; \n "
" varying vec4 vc; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
" vc = v_colour; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" varying vec2 tc; \n "
" varying vec4 vc; \n "
" uniform vec4 e_colourident; \n "
" void main () \n "
" { \n "
2013-04-08 03:51:21 +00:00
" vec4 col = texture2D(s_t0, tc); \n "
" #ifdef MASK \n "
2014-01-13 02:42:25 +00:00
" if (col.a < float(MASK)) \n "
2013-04-08 03:51:21 +00:00
" discard; \n "
" #endif \n "
" gl_FragColor = fog4blend(col * vc * e_colourident); \n "
2012-05-09 15:30:53 +00:00
" } \n "
" #endif \n "
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " defaultsprite " ,
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float4 tc: TEXCOORD0; \n "
" float4 vcol: COLOR0; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float4 vcol: COLOR0; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
" outp.tc = inp.tc.xy; \n "
" outp.vcol = inp.vcol; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" Texture2D shaderTexture; \n "
" SamplerState SampleType; \n "
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
2015-01-21 18:18:37 +00:00
" float4 tex = shaderTexture.Sample(SampleType, inp.tc); \n "
" #ifdef MASK \n "
" if (tex.a < float(MASK)) \n "
" discard; \n "
" #endif \n "
//FIXME: no fog, no colourmod
" return tex * inp.vcol; \n "
2012-11-27 03:23:19 +00:00
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " defaultwall " ,
2012-10-08 04:36:10 +00:00
" !!permu DELUXE \n "
2012-05-09 15:30:53 +00:00
" !!permu FULLBRIGHT \n "
" !!permu FOG \n "
2012-07-05 19:42:36 +00:00
" !!permu LIGHTSTYLED \n "
2012-10-08 04:36:10 +00:00
" !!permu BUMP \n "
2012-11-27 03:23:19 +00:00
" !!permu SPECULAR \n "
2012-05-09 15:30:53 +00:00
" !!cvarf r_glsl_offsetmapping_scale \n "
2012-11-27 03:23:19 +00:00
" !!cvarf gl_specular \n "
2012-05-09 15:30:53 +00:00
2015-03-03 00:14:43 +00:00
" #include \" sys/defs.h \" \n "
2012-05-09 15:30:53 +00:00
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
" #include \" sys/fog.h \" \n "
2012-11-27 03:23:19 +00:00
" #if defined(OFFSETMAPPING) || defined(SPECULAR) \n "
2012-05-09 15:30:53 +00:00
" varying vec3 eyevector; \n "
" #endif \n "
2012-07-05 19:42:36 +00:00
" varying vec2 tc; \n "
" #ifdef LIGHTSTYLED \n "
//we could use an offset, but that would still need to be per-surface which would break batches
//fixme: merge attributes?
2015-02-07 22:34:22 +00:00
" varying vec2 lm0, lm1, lm2, lm3; \n "
2012-07-05 19:42:36 +00:00
" #else \n "
2015-02-07 22:34:22 +00:00
" varying vec2 lm0; \n "
2012-07-05 19:42:36 +00:00
" #endif \n "
2012-05-09 15:30:53 +00:00
" #ifdef VERTEX_SHADER \n "
" void main () \n "
" { \n "
2012-11-27 03:23:19 +00:00
" #if defined(OFFSETMAPPING) || defined(SPECULAR) \n "
2012-05-09 15:30:53 +00:00
" vec3 eyeminusvertex = e_eyepos - v_position.xyz; \n "
2014-01-13 02:42:25 +00:00
" eyevector.x = dot(eyeminusvertex, v_svector.xyz); \n "
2012-07-05 19:42:36 +00:00
" eyevector.y = dot(eyeminusvertex, v_tvector.xyz); \n "
2012-05-09 15:30:53 +00:00
" eyevector.z = dot(eyeminusvertex, v_normal.xyz); \n "
" #endif \n "
" tc = v_texcoord; \n "
2015-02-07 22:34:22 +00:00
" lm0 = v_lmcoord; \n "
2012-07-05 19:42:36 +00:00
" #ifdef LIGHTSTYLED \n "
2015-02-07 22:34:22 +00:00
" lm1 = v_lmcoord2; \n "
" lm2 = v_lmcoord3; \n "
" lm3 = v_lmcoord4; \n "
2012-07-05 19:42:36 +00:00
" #endif \n "
2012-05-09 15:30:53 +00:00
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
2012-07-05 19:42:36 +00:00
2012-05-09 15:30:53 +00:00
" #ifdef FRAGMENT_SHADER \n "
2015-02-07 22:34:22 +00:00
2012-07-05 19:42:36 +00:00
//samplers
2015-03-03 00:14:43 +00:00
" #define s_colourmap s_t0 \n "
" uniform sampler2D s_colourmap; \n "
2012-07-05 19:42:36 +00:00
2012-11-27 03:23:19 +00:00
" #ifdef SPECULAR \n "
" uniform float cvar_gl_specular; \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" #ifdef OFFSETMAPPING \n "
" #include \" sys/offsetmapping.h \" \n "
" #endif \n "
" void main () \n "
" { \n "
2012-10-08 04:36:10 +00:00
//adjust texture coords for offsetmapping
2012-05-09 15:30:53 +00:00
" #ifdef OFFSETMAPPING \n "
2015-02-07 22:34:22 +00:00
" vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector); \n "
2012-05-09 15:30:53 +00:00
" #define tc tcoffsetmap \n "
" #endif \n "
2012-10-08 04:36:10 +00:00
2015-02-07 22:34:22 +00:00
" #if defined(EIGHTBIT) && !defined(LIGHTSTYLED) \n "
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
" vec2 lmcoord0 = floor(lm0 * 256.0*8.0)/(256.0*8.0); \n "
" #define lm0 lmcoord0 \n "
" #endif \n "
2012-10-08 04:36:10 +00:00
//yay, regular texture!
2015-02-07 22:34:22 +00:00
" gl_FragColor = texture2D(s_diffuse, tc); \n "
2012-10-08 04:36:10 +00:00
2012-11-27 03:23:19 +00:00
" #if defined(BUMP) && (defined(DELUXE) || defined(SPECULAR)) \n "
2015-02-07 22:34:22 +00:00
" vec3 norm = normalize(texture2D(s_normalmap, tc).rgb - 0.5); \n "
2012-11-27 03:23:19 +00:00
" #elif defined(SPECULAR) || defined(DELUXE) \n "
" vec3 norm = vec3(0, 0, 1); //specular lighting expects this to exist. \n "
" #endif \n "
2012-10-08 04:36:10 +00:00
//modulate that by the lightmap(s) including deluxemap(s)
2012-07-05 19:42:36 +00:00
" #ifdef LIGHTSTYLED \n "
2012-11-27 03:23:19 +00:00
" vec3 lightmaps; \n "
2012-10-08 04:36:10 +00:00
" #ifdef DELUXE \n "
2015-03-03 00:14:43 +00:00
" lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxmap0, lm0).rgb-0.5); \n "
" lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxmap1, lm1).rgb-0.5); \n "
" lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxmap2, lm2).rgb-0.5); \n "
" lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxmap3, lm3).rgb-0.5); \n "
2012-10-08 04:36:10 +00:00
" #else \n "
2015-02-07 22:34:22 +00:00
" lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb; \n "
" lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb; \n "
" lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb; \n "
" lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb; \n "
2012-10-08 04:36:10 +00:00
" #endif \n "
2012-07-05 19:42:36 +00:00
" #else \n "
2015-03-03 00:14:43 +00:00
" vec3 lightmaps = (texture2D(s_lightmap, lm0) * e_lmscale).rgb; \n "
2012-11-27 03:23:19 +00:00
//modulate by the bumpmap dot light
2012-10-08 04:36:10 +00:00
" #ifdef DELUXE \n "
2015-03-03 00:14:43 +00:00
" vec3 delux = 2.0*(texture2D(s_deluxmap, lm0).rgb-0.5); \n "
" lightmaps *= 1.0 / max(0.25, delux.z); //counter the darkening from deluxmaps \n "
" lightmaps *= dot(norm, delux); \n "
2012-11-27 03:23:19 +00:00
" #endif \n "
" #endif \n "
2015-02-07 22:34:22 +00:00
//add in specular, if applicable.
2012-11-27 03:23:19 +00:00
" #ifdef SPECULAR \n "
2015-02-07 22:34:22 +00:00
" vec4 specs = texture2D(s_specular, tc); \n "
2012-11-27 03:23:19 +00:00
" #ifdef DELUXE \n "
//not lightstyled...
2015-03-03 00:14:43 +00:00
" vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_deluxmap0, lm0).rgb-0.5)); //this norm should be the deluxemap info instead \n "
2012-10-08 04:36:10 +00:00
" #else \n "
2012-11-27 03:23:19 +00:00
" vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead \n "
2012-07-05 19:42:36 +00:00
" #endif \n "
2012-11-27 03:23:19 +00:00
" float spec = pow(max(dot(halfdir, norm), 0.0), 32.0 * specs.a); \n "
" spec *= cvar_gl_specular; \n "
//NOTE: rtlights tend to have a *4 scaler here to over-emphasise the effect because it looks cool.
//As not all maps will have deluxemapping, and the double-cos from the light util makes everything far too dark anyway,
//we default to something that is not garish when the light value is directly infront of every single pixel.
//we can justify this difference due to the rtlight editor etc showing the *4.
" gl_FragColor.rgb += spec * specs.rgb; \n "
2012-10-08 04:36:10 +00:00
" #endif \n "
2012-07-05 19:42:36 +00:00
2015-02-07 22:34:22 +00:00
" #ifdef EIGHTBIT //FIXME: with this extra flag, half the permutations are redundant. \n "
" lightmaps *= 0.5; //counter the fact that the colourmap contains overbright values and logically ranges from 0 to 2 intead of to 1. \n "
2015-03-03 00:14:43 +00:00
" float pal = texture2D(s_paletted, tc).r; //the palette index. hopefully not interpolated. \n "
2015-02-07 22:34:22 +00:00
" lightmaps -= 1.0 / 128.0; //software rendering appears to round down, so make sure we favour the lower values instead of rounding to the nearest \n "
" gl_FragColor.r = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.r)).r; //do 3 lookups. this is to cope with lit files, would be a waste to not support those. \n "
" gl_FragColor.g = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.g)).g; //its not very softwarey, but re-palettizing is ugly. \n "
" gl_FragColor.b = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.b)).b; //without lits, it should be identical. \n "
" #else \n "
2012-11-27 03:23:19 +00:00
//now we have our diffuse+specular terms, modulate by lightmap values.
" gl_FragColor.rgb *= lightmaps.rgb; \n "
2012-10-08 04:36:10 +00:00
//add on the fullbright
2012-05-09 15:30:53 +00:00
" #ifdef FULLBRIGHT \n "
2015-02-07 22:34:22 +00:00
" gl_FragColor.rgb += texture2D(s_fullbright, tc).rgb; \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
2015-02-07 22:34:22 +00:00
" #endif \n "
2012-10-08 04:36:10 +00:00
//entity modifiers
2012-05-09 15:30:53 +00:00
" gl_FragColor = gl_FragColor * e_colourident; \n "
2012-10-08 04:36:10 +00:00
//and finally hide it all if we're fogged.
2012-05-09 15:30:53 +00:00
" #ifdef FOG \n "
" gl_FragColor = fog4(gl_FragColor); \n "
" #endif \n "
" } \n "
" #endif \n "
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " defaultwall " ,
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float4 tc: TEXCOORD0; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float2 lmtc: TEXCOORD1; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
" outp.tc = inp.tc.xy; \n "
" outp.lmtc = inp.tc.zw; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" Texture2D shaderTexture[2]; \n "
" SamplerState SampleType[2]; \n "
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
2014-03-30 08:55:06 +00:00
" float4 tex = shaderTexture[0].Sample(SampleType[0], inp.tc); \n "
" float4 lm = shaderTexture[1].Sample(SampleType[1], inp.lmtc); \n "
" #ifdef MASK \n "
" #ifndef MASKOP \n "
" #define MASKOP >= //drawn if (alpha OP ref) is true. \n "
" #endif \n "
//support for alpha masking
" if (!(tex.a MASKOP MASK)) \n "
" discard; \n "
" #endif \n "
" return tex * lm.bgra; \n "
2012-11-27 03:23:19 +00:00
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " defaultwarp " ,
" !!permu FOG \n "
2015-03-03 00:14:43 +00:00
" !!cvarf r_wateralpha \n "
" #include \" sys/defs.h \" \n "
2012-05-09 15:30:53 +00:00
//this is the shader that's responsible for drawing default q1 turbulant water surfaces
//this is expected to be moderately fast.
" #include \" sys/fog.h \" \n "
" varying vec2 tc; \n "
" #ifdef VERTEX_SHADER \n "
" void main () \n "
" { \n "
" tc = v_texcoord.st; \n "
2015-03-03 00:14:43 +00:00
" #ifdef FLOW \n "
" tc.s += e_time * -0.5; \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
2013-03-12 23:13:39 +00:00
" #ifndef ALPHA \n "
2012-05-09 15:30:53 +00:00
" uniform float cvar_r_wateralpha; \n "
2013-03-12 23:13:39 +00:00
" #define USEALPHA cvar_r_wateralpha \n "
" #else \n "
" #define USEALPHA float(ALPHA) \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" void main () \n "
" { \n "
" vec2 ntc; \n "
" ntc.s = tc.s + sin(tc.t+e_time)*0.125; \n "
" ntc.t = tc.t + sin(tc.s+e_time)*0.125; \n "
2015-03-03 00:14:43 +00:00
" vec3 ts = vec3(texture2D(s_diffuse, ntc)); \n "
2013-03-12 23:13:39 +00:00
" gl_FragColor = fog4(vec4(ts, USEALPHA)); \n "
2012-05-09 15:30:53 +00:00
" } \n "
" #endif \n "
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D9QUAKE
{ QR_DIRECT3D9 , 9 , " defaultwarp " ,
" !!cvarf r_wateralpha \n "
" struct a2v { \n "
" float4 pos: POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" }; \n "
" struct v2f { \n "
" #ifndef FRAGMENT_SHADER \n "
" float4 pos: POSITION; \n "
" #endif \n "
" float2 tc: TEXCOORD0; \n "
" }; \n "
" #ifdef VERTEX_SHADER \n "
" float4x4 m_modelviewprojection; \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_modelviewprojection, inp.pos); \n "
" outp.tc = inp.tc; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" float cvar_r_wateralpha; \n "
" float e_time; \n "
2015-03-03 00:14:43 +00:00
" sampler s_diffuse; \n "
2012-11-27 03:23:19 +00:00
" float4 main (v2f inp) : COLOR0 \n "
" { \n "
" float2 ntc; \n "
" ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125; \n "
" ntc.y = inp.tc.y + sin(inp.tc.x+e_time)*0.125; \n "
2015-03-03 00:14:43 +00:00
" float3 ts = tex2D(s_diffuse, ntc).xyz; \n "
2012-11-27 03:23:19 +00:00
" return float4(ts, cvar_r_wateralpha); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " defaultwarp " ,
" !!cvarf r_wateralpha \n "
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
" outp.tc = inp.tc; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
// float cvar_r_wateralpha;
// float e_time;
// sampler s_t0;
" Texture2D shaderTexture; \n "
" SamplerState SampleType; \n "
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
" float2 ntc; \n "
" ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125; \n "
" ntc.y = inp.tc.y + sin(inp.tc.x+e_time)*0.125; \n "
" return shaderTexture.Sample(SampleType, ntc); \n "
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
2013-05-11 14:02:55 +00:00
{ QR_OPENGL , 110 , " defaultgammacb " ,
//this shader is applies gamma/contrast/brightness to the source image, and dumps it out.
" varying vec2 tc; \n "
" varying vec4 vc; \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" attribute vec4 v_colour; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
" vc = v_colour; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" void main () \n "
" { \n "
" gl_FragColor = pow(texture2D(s_t0, tc) * vc.g, vec4(vc.r)) + vc.b; \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
2012-05-09 15:30:53 +00:00
{ QR_OPENGL , 110 , " drawflat_wall " ,
" !!cvarv r_floorcolor \n "
" !!cvarv r_wallcolor \n "
" !!permu FOG \n "
//this is for the '286' preset walls, and just draws lightmaps coloured based upon surface normals.
" #include \" sys/fog.h \" \n "
" varying vec4 col; \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec3 v_normal; \n "
" attribute vec2 v_lmcoord; \n "
" varying vec2 lm; \n "
" uniform vec3 cvar_r_wallcolor; \n "
" uniform vec3 cvar_r_floorcolor; \n "
" uniform vec4 e_lmscale; \n "
" void main () \n "
" { \n "
" col = vec4(e_lmscale.rgb/255.0 * ((v_normal.z < 0.73)?cvar_r_wallcolor:cvar_r_floorcolor), e_lmscale.a); \n "
" lm = v_lmcoord; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" varying vec2 lm; \n "
" void main () \n "
" { \n "
" gl_FragColor = fog4(col * texture2D(s_t0, lm)); \n "
" } \n "
" #endif \n "
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " drawflat_wall " ,
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float4 tc: TEXCOORD0; \n "
" float3 norm: NORMAL; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float2 lmtc: TEXCOORD1; \n "
" float4 col: TEXCOORD2; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
" outp.tc = inp.tc.xy; \n "
" outp.lmtc = inp.tc.zw; \n "
" outp.col = ((inp.norm.z<0.73)?float4(0.5, 0.5, 0.5, 1):float4(0.25, 0.25, 0.5, 1)); \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" Texture2D shaderTexture; \n "
" SamplerState SampleType; \n "
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
" return inp.col * shaderTexture.Sample(SampleType, inp.lmtc); \n "
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " lpp_depthnorm " ,
" !!permu BUMP \n "
" !!permu SKELETAL \n "
//light pre-pass rendering (defered lighting)
//this is the initial pass, that draws the surface normals and depth to the initial colour buffer
" varying vec3 norm, tang, bitang; \n "
" #if defined(BUMP) \n "
" varying vec2 tc; \n "
" #endif \n "
" #ifdef VERTEX_SHADER \n "
" #include \" sys/skeletal.h \" \n "
" attribute vec2 v_texcoord; \n "
" void main() \n "
" { \n "
" #if defined(BUMP) \n "
" gl_Position = skeletaltransform_nst(norm, tang, bitang); \n "
" tc = v_texcoord; \n "
" #else \n "
" gl_Position = skeletaltransform_n(norm); \n "
" #endif \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" #if defined(BUMP) \n "
" uniform sampler2D s_t0; \n "
" #endif \n "
" void main() \n "
" { \n "
" vec3 onorm; \n "
" #if defined(BUMP) \n "
" vec3 bm = 2.0*texture2D(s_t0, tc).xyz - 1.0; \n "
" onorm = normalize(bm.x * tang + bm.y * bitang + bm.z * norm); \n "
" #else \n "
" onorm = norm; \n "
" #endif \n "
" gl_FragColor = vec4(onorm.xyz, gl_FragCoord.z / gl_FragCoord.w); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " lpp_light " ,
//this shader is a light shader. ideally drawn with a quad covering the entire region
//the output is contribution from this light (which will be additively blended)
//you can blame Electro for much of the maths in here.
//fixme: no fog
" varying vec4 tf; \n "
" #ifdef VERTEX_SHADER \n "
" void main() \n "
" { \n "
" tf = ftetransform(); \n "
" gl_Position = tf; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" uniform vec3 l_lightposition; \n "
" uniform mat4 m_invviewprojection; \n "
" uniform vec3 l_lightcolour; \n "
" uniform float l_lightradius; \n "
" vec3 calcLightWorldPos(vec2 screenPos, float depth) \n "
" { \n "
" vec4 pos; \n "
" pos.x = screenPos.x; \n "
" pos.y = screenPos.y; \n "
" pos.z = depth; \n "
" pos.w = 1.0; \n "
" pos = m_invviewprojection * pos; \n "
" return pos.xyz / pos.w; \n "
" } \n "
" void main () \n "
" { \n "
" vec3 lightColour = l_lightcolour.rgb; \n "
" float lightIntensity = 1.0; \n "
" float lightAttenuation = l_lightradius; // fixme: just use the light radius for now, use better near/far att math separately once working \n "
" float radiusFar = l_lightradius; \n "
" float radiusNear = l_lightradius*0.5; \n "
" vec2 fc; \n "
" fc = tf.xy / tf.w; \n "
" vec4 data = texture2D(s_t0, (1.0 + fc) / 2.0); \n "
" float depth = data.a; \n "
" vec3 norm = data.xyz; \n "
/* calc where the wall that generated this sample came from */
" vec3 worldPos = calcLightWorldPos(fc, depth); \n "
/*calc diffuse lighting term*/
" vec3 lightDir = l_lightposition - worldPos; \n "
" float zdiff = 1.0 - clamp(length(lightDir) / lightAttenuation, 0.0, 1.0); \n "
" float atten = (radiusFar * zdiff) / (radiusFar - radiusNear); \n "
" atten = pow(atten, 2.0); \n "
" lightDir = normalize(lightDir); \n "
" float nDotL = dot(norm, lightDir) * atten; \n "
" float lightDiffuse = max(0.0, nDotL); \n "
" gl_FragColor = vec4(lightDiffuse * (lightColour * lightIntensity), 1.0); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " lpp_wall " ,
//the final defered lighting pass.
//the lighting values were written to some render target, which is fed into this shader, and now we draw all the wall textures with it.
" varying vec2 tc, lm; \n "
" varying vec4 tf; \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" attribute vec2 v_lmcoord; \n "
" void main () \n "
" { \n "
" tc = v_texcoord; \n "
" lm = v_lmcoord; \n "
" gl_Position = tf = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform sampler2D s_t0; \n "
" uniform sampler2D s_t1; \n "
" uniform sampler2D s_t2; \n "
" uniform vec4 e_lmscale; \n "
" void main () \n "
" { \n "
" vec2 nst; \n "
" nst = tf.xy / tf.w; \n "
" nst = (1.0 + nst) / 2.0; \n "
" vec4 l = texture2D(s_t0, nst)*5.0; \n "
" vec4 c = texture2D(s_t1, tc); \n "
2014-08-15 02:20:41 +00:00
" vec3 lmsamp = texture2D(s_t2, lm).rgb*e_lmscale; \n "
2012-05-09 15:30:53 +00:00
" vec3 diff = l.rgb; \n "
" vec3 chrom = diff / (0.001 + dot(diff, vec3(0.3, 0.59, 0.11))); \n "
" vec3 spec = chrom * l.a; \n "
" gl_FragColor = vec4((diff + lmsamp) * c.xyz, 1.0); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " postproc_fisheye " ,
" !!cvarf ffov \n "
//fisheye view rendering, for silly fovs that are still playable.
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" varying vec2 texcoord; \n "
" void main() \n "
" { \n "
" texcoord = v_texcoord.xy; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform samplerCube s_t0; \n "
" varying vec2 texcoord; \n "
" uniform float cvar_ffov; \n "
" void main() \n "
" { \n "
" vec3 tc; \n "
" vec2 d; \n "
" vec2 ang; \n "
" d = texcoord; \n "
" ang.x = sqrt(d.x*d.x+d.y*d.y)*radians(cvar_ffov); \n "
" ang.y = -atan(d.y, d.x); \n "
" tc.x = sin(ang.x) * cos(ang.y); \n "
" tc.y = sin(ang.x) * sin(ang.y); \n "
" tc.z = cos(ang.x); \n "
" gl_FragColor = textureCube(s_t0, tc); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " postproc_panorama " ,
" !!cvarf ffov \n "
//panoramic view rendering, for promo map shots or whatever.
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" varying vec2 texcoord; \n "
" void main() \n "
" { \n "
" texcoord = v_texcoord.xy; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" uniform samplerCube s_t0; \n "
" varying vec2 texcoord; \n "
" uniform float cvar_ffov; \n "
" void main() \n "
" { \n "
" vec3 tc; \n "
" float ang; \n "
" ang = texcoord.x*-radians(cvar_ffov); \n "
" tc.x = sin(ang); \n "
" tc.y = -texcoord.y; \n "
" tc.z = cos(ang); \n "
" gl_FragColor = textureCube(s_t0, tc); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " rtlight " ,
" !!permu BUMP \n "
2013-10-08 14:28:11 +00:00
" !!permu FRAMEBLEND \n "
2012-05-09 15:30:53 +00:00
" !!permu SKELETAL \n "
2013-03-12 22:35:33 +00:00
" !!permu UPPERLOWER \n "
2012-05-09 15:30:53 +00:00
" !!permu FOG \n "
" !!cvarf r_glsl_offsetmapping_scale \n "
2013-10-08 14:28:11 +00:00
" !!cvardf r_glsl_pcf \n "
2012-05-09 15:30:53 +00:00
2014-08-27 08:41:31 +00:00
" #ifndef USE_ARB_SHADOW \n "
//fall back on regular samplers if we must
" #define sampler2DShadow sampler2D \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
//this is the main shader responsible for realtime dlights.
//texture units:
//s0=diffuse, s1=normal, s2=specular, s3=shadowmap
//custom modifiers:
//PCF(shadowmap)
2013-10-08 14:28:11 +00:00
//CUBEPROJ(projected cubemap)
2012-08-04 01:35:52 +00:00
//SPOT(projected circle
//CUBESHADOW
2013-10-08 14:28:11 +00:00
" #ifndef r_glsl_pcf \n "
2014-08-27 08:41:31 +00:00
" #error r_glsl_pcf wasnt defined \n "
2013-10-08 14:28:11 +00:00
" #endif \n "
" #if r_glsl_pcf < 1 \n "
" #undef r_glsl_pcf \n "
" #define r_glsl_pcf 9 \n "
" #endif \n "
2015-04-14 23:12:17 +00:00
//texturegather is a gl4 feature, but these shaders are gl2.0 or something
" #if #include \" cvar/texgather \" && defined(GL_ARB_texture_gather) && defined(PCF) \n "
2012-08-04 01:35:52 +00:00
" #extension GL_ARB_texture_gather : enable \n "
2015-04-14 23:12:17 +00:00
" #define DOTEXTUREGATHER \n "
2012-08-04 01:35:52 +00:00
" #endif \n "
2012-05-09 15:30:53 +00:00
2013-03-12 22:35:33 +00:00
" #ifdef UPPERLOWER \n "
" #define UPPER \n "
" #define LOWER \n "
" #endif \n "
2014-10-05 20:04:11 +00:00
//if there's no vertex normals known, disable some stuff.
//FIXME: this results in dupe permutations.
" #ifdef NOBUMP \n "
" #undef SPECULAR \n "
" #undef BUMP \n "
" #undef OFFSETMAPPING \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" varying vec2 tcbase; \n "
" varying vec3 lightvector; \n "
" #if defined(SPECULAR) || defined(OFFSETMAPPING) \n "
" varying vec3 eyevector; \n "
" #endif \n "
2013-06-26 00:39:13 +00:00
" #if defined(PCF) || defined(CUBE) || defined(SPOT) \n "
2012-08-04 01:35:52 +00:00
" varying vec4 vtexprojcoord; \n "
" #endif \n "
2014-08-27 08:41:31 +00:00
2012-05-09 15:30:53 +00:00
" #ifdef VERTEX_SHADER \n "
2014-08-27 08:41:31 +00:00
" #if defined(PCF) || defined(CUBE) || defined(SPOT) \n "
" uniform mat4 l_cubematrix; \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" #include \" sys/skeletal.h \" \n "
" uniform vec3 l_lightposition; \n "
" attribute vec2 v_texcoord; \n "
" #if defined(SPECULAR) || defined(OFFSETMAPPING) \n "
" uniform vec3 e_eyepos; \n "
" #endif \n "
" void main () \n "
" { \n "
" vec3 n, s, t, w; \n "
" gl_Position = skeletaltransform_wnst(w,n,s,t); \n "
" tcbase = v_texcoord; //pass the texture coords straight through \n "
" vec3 lightminusvertex = l_lightposition - w.xyz; \n "
2014-10-05 20:04:11 +00:00
" #ifdef NOBUMP \n "
//the only important thing is distance
" lightvector = lightminusvertex; \n "
" #else \n "
//the light direction relative to the surface normal, for bumpmapping.
2014-01-13 02:42:25 +00:00
" lightvector.x = dot(lightminusvertex, s.xyz); \n "
2012-05-09 15:30:53 +00:00
" lightvector.y = dot(lightminusvertex, t.xyz); \n "
" lightvector.z = dot(lightminusvertex, n.xyz); \n "
2014-10-05 20:04:11 +00:00
" #endif \n "
2012-05-09 15:30:53 +00:00
" #if defined(SPECULAR)||defined(OFFSETMAPPING) \n "
" vec3 eyeminusvertex = e_eyepos - w.xyz; \n "
2014-01-13 02:42:25 +00:00
" eyevector.x = dot(eyeminusvertex, s.xyz); \n "
2012-07-05 19:42:36 +00:00
" eyevector.y = dot(eyeminusvertex, t.xyz); \n "
2012-05-09 15:30:53 +00:00
" eyevector.z = dot(eyeminusvertex, n.xyz); \n "
" #endif \n "
2013-06-26 00:39:13 +00:00
" #if defined(PCF) || defined(SPOT) || defined(CUBE) \n "
2012-08-04 01:35:52 +00:00
//for texture projections/shadowmapping on dlights
" vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0)); \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
" } \n "
" #endif \n "
2012-08-04 01:35:52 +00:00
2012-05-09 15:30:53 +00:00
" #ifdef FRAGMENT_SHADER \n "
" #include \" sys/fog.h \" \n "
2013-03-12 22:35:33 +00:00
" uniform sampler2D s_t0; //diffuse \n "
2012-08-04 01:35:52 +00:00
2012-05-09 15:30:53 +00:00
" #if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING) \n "
2013-03-12 22:35:33 +00:00
" uniform sampler2D s_t1; //normalmap \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
" #ifdef SPECULAR \n "
2013-03-12 22:35:33 +00:00
" uniform sampler2D s_t2; //specular \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
2013-06-26 00:39:13 +00:00
" #ifdef CUBE \n "
2013-03-12 22:35:33 +00:00
" uniform samplerCube s_t3; //projected cubemap \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
" #ifdef PCF \n "
2012-08-04 01:35:52 +00:00
" #ifdef CUBESHADOW \n "
2013-03-12 22:35:33 +00:00
" uniform samplerCubeShadow s_t4; //shadowmap \n "
2012-05-09 15:30:53 +00:00
" #else \n "
2012-08-04 01:35:52 +00:00
" #if 0//def GL_ARB_texture_gather \n "
" uniform sampler2D s_t4; \n "
" #else \n "
" uniform sampler2DShadow s_t4; \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
" #endif \n "
2012-08-04 01:35:52 +00:00
" #endif \n "
2013-03-12 22:35:33 +00:00
" #ifdef LOWER \n "
" uniform sampler2D s_t5; //pants colours \n "
" uniform vec3 e_lowercolour; \n "
" #endif \n "
" #ifdef UPPER \n "
" uniform sampler2D s_t6; //shirt colours \n "
" uniform vec3 e_uppercolour; \n "
" #endif \n "
2012-08-04 01:35:52 +00:00
2012-05-09 15:30:53 +00:00
" uniform float l_lightradius; \n "
" uniform vec3 l_lightcolour; \n "
" uniform vec3 l_lightcolourscale; \n "
2013-03-12 23:13:39 +00:00
" #ifdef PCF \n "
2013-10-08 14:28:11 +00:00
" uniform vec4 l_shadowmapproj; //light projection matrix info \n "
" uniform vec2 l_shadowmapscale; //xy are the texture scale, z is 1, w is the scale. \n "
" vec3 ShadowmapCoord(void) \n "
2012-08-04 01:35:52 +00:00
" { \n "
" #ifdef SPOT \n "
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
2014-10-05 20:04:11 +00:00
" return ((vtexprojcoord.xyz-vec3(0.0,0.0,0.015))/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5); \n "
2013-10-08 14:28:11 +00:00
//#elif defined(CUBESHADOW)
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
2012-08-04 01:35:52 +00:00
" #else \n "
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
2013-10-08 14:28:11 +00:00
" vec3 dir = abs(vtexprojcoord.xyz); \n "
2012-08-04 01:35:52 +00:00
//assume z is the major axis (ie: forward from the light)
2013-10-08 14:28:11 +00:00
" vec3 t = vtexprojcoord.xyz; \n "
2012-08-04 01:35:52 +00:00
" float ma = dir.z; \n "
2013-10-08 14:28:11 +00:00
" vec3 axis = vec3(0.5/3.0, 0.5/2.0, 0.5); \n "
2012-08-04 01:35:52 +00:00
" if (dir.x > ma) \n "
" { \n "
" ma = dir.x; \n "
2013-10-08 14:28:11 +00:00
" t = vtexprojcoord.zyx; \n "
" axis.x = 0.5; \n "
2012-08-04 01:35:52 +00:00
" } \n "
" if (dir.y > ma) \n "
" { \n "
" ma = dir.y; \n "
2013-10-08 14:28:11 +00:00
" t = vtexprojcoord.xzy; \n "
" axis.x = 2.5/3.0; \n "
2012-08-04 01:35:52 +00:00
" } \n "
2013-10-08 14:28:11 +00:00
//if the axis is negative, flip it.
2012-08-04 01:35:52 +00:00
" if (t.z > 0.0) \n "
" { \n "
2013-10-08 14:28:11 +00:00
" axis.y = 1.5/2.0; \n "
2012-08-04 01:35:52 +00:00
" t.z = -t.z; \n "
" } \n "
//we also need to pass the result through the light's projection matrix too
2013-10-08 14:28:11 +00:00
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
" return axis + ((l_shadowmapproj.xyz*t.xyz + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z); \n "
2012-08-04 01:35:52 +00:00
" #endif \n "
2013-10-08 14:28:11 +00:00
" } \n "
" float ShadowmapFilter(void) \n "
" { \n "
" vec3 shadowcoord = ShadowmapCoord(); \n "
2012-08-04 01:35:52 +00:00
2015-04-14 23:12:17 +00:00
" #ifdef DOTEXTUREGATHER \n "
2012-08-04 01:35:52 +00:00
" vec2 ipart, fpart; \n "
" #define dosamp(x,y) textureGatherOffset(s_t4, ipart.xy, vec2(x,y))) \n "
" vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0)); \n "
" vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0)); \n "
" vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0)); \n "
" vec4 br = step(shadowcoord.z, dosamp(1.0, 1.0)); \n "
//we now have 4*4 results, woo
//we can just average them for 1/16th precision, but that's still limited graduations
//the middle four pixels are 'full strength', but we interpolate the sides to effectively give 3*3
" vec4 col = vec4(tl.ba, tr.ba) + vec4(bl.rg, br.rg) + //middle two rows are full strength \n "
" mix(vec4(tl.rg, tr.rg), vec4(bl.ba, br.ba), fpart.y); //top+bottom rows \n "
" return dot(mix(col.rgb, col.agb, fpart.x), vec3(1.0/9.0)); //blend r+a, gb are mixed because its pretty much free and gives a nicer dot instruction instead of lots of adds. \n "
" #else \n "
2014-08-27 08:41:31 +00:00
" #ifdef USE_ARB_SHADOW \n "
//with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows
2013-10-08 14:28:11 +00:00
" #define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r \n "
2014-08-27 08:41:31 +00:00
" #else \n "
//this will probably be a bit blocky.
" #define dosamp(x,y) float(texture2D(s_t4, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z) \n "
" #endif \n "
2012-08-04 01:35:52 +00:00
" float s = 0.0; \n "
2013-10-08 14:28:11 +00:00
" #if r_glsl_pcf >= 1 && r_glsl_pcf < 5 \n "
" s += dosamp(0.0, 0.0); \n "
" return s; \n "
" #elif r_glsl_pcf >= 5 && r_glsl_pcf < 9 \n "
" s += dosamp(-1.0, 0.0); \n "
" s += dosamp(0.0, -1.0); \n "
" s += dosamp(0.0, 0.0); \n "
" s += dosamp(0.0, 1.0); \n "
" s += dosamp(1.0, 0.0); \n "
" return s/5.0; \n "
" #else \n "
2012-08-04 01:35:52 +00:00
" s += dosamp(-1.0, -1.0); \n "
" s += dosamp(-1.0, 0.0); \n "
" s += dosamp(-1.0, 1.0); \n "
" s += dosamp(0.0, -1.0); \n "
" s += dosamp(0.0, 0.0); \n "
" s += dosamp(0.0, 1.0); \n "
" s += dosamp(1.0, -1.0); \n "
" s += dosamp(1.0, 0.0); \n "
" s += dosamp(1.0, 1.0); \n "
" return s/9.0; \n "
" #endif \n "
" #endif \n "
" } \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" #ifdef OFFSETMAPPING \n "
" #include \" sys/offsetmapping.h \" \n "
" #endif \n "
2013-10-29 17:38:22 +00:00
2012-05-09 15:30:53 +00:00
" void main () \n "
" { \n "
2012-07-05 19:42:36 +00:00
//read raw texture samples (offsetmapping munges the tex coords first)
2012-05-09 15:30:53 +00:00
" #ifdef OFFSETMAPPING \n "
" vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector); \n "
" #define tcbase tcoffsetmap \n "
" #endif \n "
" vec3 bases = vec3(texture2D(s_t0, tcbase)); \n "
2013-03-12 22:35:33 +00:00
" #ifdef UPPER \n "
" vec4 uc = texture2D(s_t6, tcbase); \n "
" bases.rgb += uc.rgb*e_uppercolour*uc.a; \n "
" #endif \n "
" #ifdef LOWER \n "
" vec4 lc = texture2D(s_t5, tcbase); \n "
" bases.rgb += lc.rgb*e_lowercolour*lc.a; \n "
" #endif \n "
2012-05-09 15:30:53 +00:00
" #if defined(BUMP) || defined(SPECULAR) \n "
2012-07-05 19:42:36 +00:00
" vec3 bumps = normalize(vec3(texture2D(s_t1, tcbase)) - 0.5); \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
" #ifdef SPECULAR \n "
" vec4 specs = texture2D(s_t2, tcbase); \n "
" #endif \n "
2012-07-05 19:42:36 +00:00
" float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0); \n "
2012-05-09 15:30:53 +00:00
" vec3 diff; \n "
2014-10-05 20:04:11 +00:00
" #ifdef NOBUMP \n "
//surface can only support ambient lighting, even for lights that try to avoid it.
" diff = bases * (l_lightcolourscale.x+l_lightcolourscale.y); \n "
" #else \n "
" vec3 nl = normalize(lightvector); \n "
2012-05-09 15:30:53 +00:00
" #ifdef BUMP \n "
2012-07-05 19:42:36 +00:00
" diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0)); \n "
2012-05-09 15:30:53 +00:00
" #else \n "
2012-08-04 01:35:52 +00:00
//we still do bumpmapping even without bumps to ensure colours are always sane. light.exe does it too.
2012-05-09 15:30:53 +00:00
" diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0)); \n "
" #endif \n "
2014-10-05 20:04:11 +00:00
" #endif \n "
2012-07-05 19:42:36 +00:00
2012-05-09 15:30:53 +00:00
" #ifdef SPECULAR \n "
2012-07-05 19:42:36 +00:00
" vec3 halfdir = normalize(normalize(eyevector) + nl); \n "
" float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a); \n "
" diff += l_lightcolourscale.z * spec * specs.rgb; \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
2012-07-05 19:42:36 +00:00
2013-06-26 00:39:13 +00:00
" #ifdef CUBE \n "
2012-08-04 01:35:52 +00:00
/*filter the colour by the cubemap projection*/
" diff *= textureCube(s_t3, vtexprojcoord.xyz).rgb; \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
2012-08-04 01:35:52 +00:00
2012-05-09 15:30:53 +00:00
" #if defined(SPOT) \n "
2012-08-04 01:35:52 +00:00
/*filter the colour by the spotlight. discard anything behind the light so we don't get a mirror image*/
" if (vtexprojcoord.w < 0.0) discard; \n "
" vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w);colorscale*=1.0-(dot(spot,spot)); \n "
2012-05-09 15:30:53 +00:00
" #endif \n "
2012-08-04 01:35:52 +00:00
" #ifdef PCF \n "
/*filter the light by the shadowmap. logically a boolean, but we allow fractions for softer shadows*/
//diff.rgb = (vtexprojcoord.xyz/vtexprojcoord.w) * 0.5 + 0.5;
" colorscale *= ShadowmapFilter(); \n "
2013-11-10 21:14:28 +00:00
// diff = ShadowmapCoord();
2012-05-09 15:30:53 +00:00
" #endif \n "
2012-08-04 01:35:52 +00:00
2012-05-09 15:30:53 +00:00
" #if defined(PROJECTION) \n "
2012-08-04 01:35:52 +00:00
/*2d projection, not used*/
// diff *= texture2d(s_t3, shadowcoord);
2012-05-09 15:30:53 +00:00
" #endif \n "
2012-08-04 01:35:52 +00:00
2012-05-09 15:30:53 +00:00
" gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour); \n "
" } \n "
" #endif \n "
2014-08-27 08:41:31 +00:00
2012-05-09 15:30:53 +00:00
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D9QUAKE
{ QR_DIRECT3D9 , 9 , " rtlight " ,
" !!permu BUMP \n "
" !!permu SPECULAR \n "
" !!permu OFFSETMAPPING \n "
" !!permu SKELETAL \n "
" !!permu FOG \n "
// texture units:
// s0=diffuse, s1=normal, s2=specular, s3=shadowmap
// custom modifiers:
// PCF(shadowmap)
// CUBE(projected cubemap)
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float3 tc: TEXCOORD0; \n "
" float3 n: NORMAL0; \n "
" float3 s: TANGENT0; \n "
" float3 t: BINORMAL0; \n "
" }; \n "
" struct v2f \n "
" { \n "
" #ifndef FRAGMENT_SHADER \n "
" float4 pos: POSITION; \n "
" #endif \n "
" float3 tc: TEXCOORD0; \n "
" float3 lpos: TEXCOORD1; \n "
" }; \n "
" #ifdef VERTEX_SHADER \n "
" float4x4 m_modelviewprojection; \n "
" float3 l_lightposition; \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_modelviewprojection, inp.pos); \n "
" outp.tc = inp.tc; \n "
" float3 lightminusvertex = l_lightposition - inp.pos.xyz; \n "
" outp.lpos.x = dot(lightminusvertex, inp.s.xyz); \n "
" outp.lpos.y = dot(lightminusvertex, inp.t.xyz); \n "
" outp.lpos.z = dot(lightminusvertex, inp.n.xyz); \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
2015-03-03 00:14:43 +00:00
" sampler s_diffuse; \n "
2012-11-27 03:23:19 +00:00
" float l_lightradius; \n "
" float3 l_lightcolour; \n "
" float4 main (v2f inp) : COLOR0 \n "
" { \n "
" float3 col = l_lightcolour; \n "
" col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0); \n "
2015-03-03 00:14:43 +00:00
" float3 diff = tex2D(s_diffuse, inp.tc); \n "
2012-11-27 03:23:19 +00:00
" return float4(diff * col, 1); \n "
" } \n "
" #endif \n "
} ,
# endif
2013-11-10 21:14:28 +00:00
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " rtlight " ,
" !!permu BUMP \n "
" !!permu FRAMEBLEND \n "
" !!permu SKELETAL \n "
" !!permu UPPERLOWER \n "
" !!permu FOG \n "
" !!cvarf r_glsl_offsetmapping_scale \n "
" !!cvardf r_glsl_pcf \n "
//this is the main shader responsible for realtime dlights.
//texture units:
//s0=diffuse, s1=normal, s2=specular, s3=shadowmap
//custom modifiers:
//PCF(shadowmap)
//CUBEPROJ(projected cubemap)
//SPOT(projected circle
//CUBESHADOW
" #undef CUBE //engine cannot load cubemaps properly with d3d yet. \n "
" #ifndef r_glsl_pcf \n "
" #error r_glsl_pcf wasn't defined \n "
" #endif \n "
" #if r_glsl_pcf < 1 \n "
" #undef r_glsl_pcf \n "
" #define r_glsl_pcf 9 \n "
" #endif \n "
" #ifdef UPPERLOWER \n "
" #define UPPER \n "
" #define LOWER \n "
" #endif \n "
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float4 tc: TEXCOORD0; \n "
" float3 n: NORMAL; \n "
" float3 s: TANGENT; \n "
" float3 t: BINORMAL; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float3 lightvector: TEXCOORD1; \n "
" float3 eyevector: TEXCOORD2; \n "
" float3 vtexprojcoord: TEXCOORD3; \n "
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" float4 wpos; \n "
" wpos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, wpos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
" outp.tc = inp.tc.xy; \n "
" float3 lightminusvertex = l_lightposition - wpos.xyz; \n "
" outp.lightvector.x = -dot(lightminusvertex, inp.s.xyz); \n "
" outp.lightvector.y = dot(lightminusvertex, inp.t.xyz); \n "
" outp.lightvector.z = dot(lightminusvertex, inp.n.xyz); \n "
" float3 eyeminusvertex = e_eyepos - wpos.xyz; \n "
" outp.eyevector.x = -dot(eyeminusvertex, inp.s.xyz); \n "
" outp.eyevector.y = dot(eyeminusvertex, inp.t.xyz); \n "
" outp.eyevector.z = dot(eyeminusvertex, inp.n.xyz); \n "
" outp.vtexprojcoord = mul(l_cubematrix, wpos).xyz; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" Texture2D tx_base : register(t0); \n "
" Texture2D tx_bump : register(t1); \n "
" Texture2D tx_spec : register(t2); \n "
" TextureCube tx_cube : register(t3); \n "
" Texture2D tx_smap : register(t4); \n "
" Texture2D tx_lower : register(t5); \n "
" Texture2D tx_upper : register(t6); \n "
" SamplerState ss_base : register(s0); \n "
" SamplerState ss_bump : register(s1); \n "
" SamplerState ss_spec : register(s2); \n "
" SamplerState ss_cube : register(s3); \n "
" SamplerComparisonState ss_smap : register(s4); \n "
" SamplerState ss_lower : register(s5); \n "
" SamplerState ss_upper : register(s6); \n "
" #ifdef PCF \n "
" float3 ShadowmapCoord(float3 vtexprojcoord) \n "
" { \n "
" #ifdef SPOT \n "
//bias it. don't bother figuring out which side or anything, its not needed
//l_projmatrix contains the light's projection matrix so no other magic needed
" vtexprojcoord.z -= 0.015; \n "
" return (vtexprojcoord.xyz + float3(1.0, 1.0, 1.0)) * float3(0.5, 0.5, 0.5); \n "
//#elif defined(CUBESHADOW)
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
" #else \n "
//figure out which axis to use
//texture is arranged thusly:
//forward left up
//back right down
" float3 dir = abs(vtexprojcoord.xyz); \n "
//assume z is the major axis (ie: forward from the light)
" float3 t = vtexprojcoord.xyz; \n "
" float ma = dir.z; \n "
" float3 axis = float3(0.5/3.0, 0.5/2.0, 0.5); \n "
" if (dir.x > ma) \n "
" { \n "
" ma = dir.x; \n "
" t = vtexprojcoord.zyx; \n "
" axis.x = 0.5; \n "
" } \n "
" if (dir.y > ma) \n "
" { \n "
" ma = dir.y; \n "
" t = vtexprojcoord.xzy; \n "
" axis.x = 2.5/3.0; \n "
" } \n "
//if the axis is negative, flip it.
" if (t.z > 0.0) \n "
" { \n "
" axis.y = 1.5/2.0; \n "
" t.z = -t.z; \n "
" } \n "
//we also need to pass the result through the light's projection matrix too
//the 'matrix' we need only contains 5 actual values. and one of them is a -1. So we might as well just use a vec4.
//note: the projection matrix also includes scalers to pinch the image inwards to avoid sampling over borders, as well as to cope with non-square source image
//the resulting z is prescaled to result in a value between -0.5 and 0.5.
//also make sure we're in the right quadrant type thing
" return axis + ((l_shadowmapproj.xyz*t.xyz + float3(0.0, 0.0, l_shadowmapproj.w)) / -t.z); \n "
" #endif \n "
" } \n "
" float ShadowmapFilter(float3 vtexprojcoord) \n "
" { \n "
" float3 shadowcoord = ShadowmapCoord(vtexprojcoord); \n "
// #define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r
// #define dosamp(x,y) (tx_smap.Sample(ss_smap, shadowcoord.xy + (float2(x,y)*l_shadowmapscale.xy)).r < shadowcoord.z)
" #define dosamp(x,y) (tx_smap.SampleCmpLevelZero(ss_smap, shadowcoord.xy+(float2(x,y)*l_shadowmapscale.xy), shadowcoord.z)) \n "
" float s = 0.0; \n "
" #if r_glsl_pcf >= 1 && r_glsl_pcf < 5 \n "
" s += dosamp(0.0, 0.0); \n "
" return s; \n "
" #elif r_glsl_pcf >= 5 && r_glsl_pcf < 9 \n "
" s += dosamp(-1.0, 0.0); \n "
" s += dosamp(0.0, -1.0); \n "
" s += dosamp(0.0, 0.0); \n "
" s += dosamp(0.0, 1.0); \n "
" s += dosamp(1.0, 0.0); \n "
" return s/5.0; \n "
" #else \n "
" s += dosamp(-1.0, -1.0); \n "
" s += dosamp(-1.0, 0.0); \n "
" s += dosamp(-1.0, 1.0); \n "
" s += dosamp(0.0, -1.0); \n "
" s += dosamp(0.0, 0.0); \n "
" s += dosamp(0.0, 1.0); \n "
" s += dosamp(1.0, -1.0); \n "
" s += dosamp(1.0, 0.0); \n "
" s += dosamp(1.0, 1.0); \n "
" return s/9.0; \n "
" #endif \n "
" } \n "
" #endif \n "
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
" float2 tc = inp.tc; //TODO: offsetmapping. \n "
" float4 base = tx_base.Sample(ss_base, tc); \n "
" #ifdef BUMP \n "
" float4 bump = tx_bump.Sample(ss_bump, tc); \n "
" bump.rgb = normalize(bump.rgb - 0.5); \n "
" #else \n "
" float4 bump = float4(0, 0, 1, 0); \n "
" #endif \n "
" float4 spec = tx_spec.Sample(ss_spec, tc); \n "
" #ifdef CUBE \n "
" float4 cubemap = tx_cube.Sample(ss_cube, inp.vtexprojcoord); \n "
" #endif \n "
" #ifdef LOWER \n "
" float4 lower = tx_lower.Sample(ss_lower, tc); \n "
" base += lower; \n "
" #endif \n "
" #ifdef UPPER \n "
" float4 upper = tx_upper.Sample(ss_upper, tc); \n "
" base += upper; \n "
" #endif \n "
" float lightscale = max(1.0 - (dot(inp.lightvector,inp.lightvector)/(l_lightradius*l_lightradius)), 0.0); \n "
" float3 nl = normalize(inp.lightvector); \n "
" float bumpscale = max(dot(bump.xyz, nl), 0.0); \n "
" float3 halfdir = normalize(normalize(inp.eyevector) + nl); \n "
" float specscale = pow(max(dot(halfdir, bump.rgb), 0.0), 32.0 * spec.a); \n "
" float4 result; \n "
" result.a = base.a; \n "
" result.rgb = base.rgb * (l_lightcolourscale.x + l_lightcolourscale.y * bumpscale); //amient light + diffuse \n "
" result.rgb += spec.rgb * l_lightcolourscale.z * specscale; //specular \n "
" result.rgb *= lightscale * l_colour; //fade light by distance and light colour. \n "
" #ifdef CUBE \n "
" result.rgb *= cubemap.rgb; //fade by cubemap \n "
" #endif \n "
" #ifdef PCF \n "
" result.rgb *= ShadowmapFilter(inp.vtexprojcoord); \n "
" #endif \n "
//TODO: fog
" return result; \n "
" } \n "
" #endif \n "
} ,
# endif
2012-05-09 15:30:53 +00:00
# ifdef GLQUAKE
{ QR_OPENGL , 110 , " underwaterwarp " ,
" !!cvarf r_waterwarp \n "
//this is a post processing shader that is drawn fullscreen whenever the view is underwater.
//its generally expected to warp the view a little.
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" varying vec2 v_stc; \n "
" varying vec2 v_warp; \n "
" varying vec2 v_edge; \n "
" uniform float e_time; \n "
" void main () \n "
" { \n "
" gl_Position = ftetransform(); \n "
2014-08-19 06:08:23 +00:00
" v_stc = vec2(v_texcoord.x, 1.0-v_texcoord.y); \n "
2012-05-09 15:30:53 +00:00
" v_warp.s = e_time * 0.25 + v_texcoord.s; \n "
" v_warp.t = e_time * 0.25 + v_texcoord.t; \n "
" v_edge = v_texcoord.xy; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" varying vec2 v_stc; \n "
" varying vec2 v_warp; \n "
" varying vec2 v_edge; \n "
" uniform sampler2D s_t0;/*$currentrender*/ \n "
" uniform sampler2D s_t1;/*warp image*/ \n "
" uniform sampler2D s_t2;/*edge image*/ \n "
2013-03-12 22:35:33 +00:00
" uniform vec4 e_rendertexturescale; \n "
2012-05-09 15:30:53 +00:00
" uniform float cvar_r_waterwarp; \n "
" void main () \n "
" { \n "
2013-03-12 23:13:39 +00:00
" vec2 amp = (0.010 / 0.625) * cvar_r_waterwarp * texture2D(s_t2, v_edge).rg; \n "
" vec3 offset = (texture2D(s_t1, v_warp).rgb - 0.5) * 2.0; \n "
" vec2 temp = v_stc + offset.xy * amp; \n "
" gl_FragColor = texture2D(s_t0, temp*e_rendertexturescale.st); \n "
2012-05-09 15:30:53 +00:00
" } \n "
" #endif \n "
} ,
# endif
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
# ifdef GLQUAKE
2013-03-12 22:37:59 +00:00
{ QR_OPENGL , 110 , " menutint " ,
" !!cvari r_menutint_inverse \n "
" !!cvarv r_menutint \n "
" #ifdef VERTEX_SHADER \n "
" attribute vec2 v_texcoord; \n "
" varying vec2 texcoord; \n "
" uniform vec4 e_rendertexturescale; \n "
" void main(void) \n "
" { \n "
" texcoord.x = v_texcoord.x*e_rendertexturescale.x; \n "
" texcoord.y = (1.0-v_texcoord.y)*e_rendertexturescale.y; \n "
" gl_Position = ftetransform(); \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
" varying vec2 texcoord; \n "
" uniform vec3 cvar_r_menutint; \n "
" uniform sampler2D s_t0; \n "
" uniform int cvar_r_menutint_inverse; \n "
" const vec3 lumfactors = vec3(0.299, 0.587, 0.114); \n "
" const vec3 invertvec = vec3(1.0, 1.0, 1.0); \n "
" void main(void) \n "
" { \n "
" vec3 texcolor = texture2D(s_t0, texcoord).rgb; \n "
" float luminance = dot(lumfactors, texcolor); \n "
" texcolor = vec3(luminance, luminance, luminance); \n "
" texcolor *= cvar_r_menutint; \n "
" texcolor = (cvar_r_menutint_inverse > 0) ? (invertvec - texcolor) : texcolor; \n "
" gl_FragColor = vec4(texcolor, 1.0); \n "
" } \n "
" #endif \n "
} ,
# endif
# ifdef GLQUAKE
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
{ QR_OPENGL , 110 , " terrain " ,
" !!permu FOG \n "
" #include \" sys/fog.h \" \n "
" varying vec2 tc; \n "
" varying vec2 lm; \n "
2012-08-04 01:35:52 +00:00
" varying vec4 vc; \n "
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
2013-10-29 17:38:22 +00:00
" #ifdef RTLIGHT \n "
" varying vec3 lightvector; \n "
// #if defined(SPECULAR) || defined(OFFSETMAPPING)
// varying vec3 eyevector;
// #endif
" #if defined(PCF) || defined(CUBE) || defined(SPOT) \n "
" varying vec4 vtexprojcoord; \n "
" #endif \n "
" #endif \n "
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
" #ifdef VERTEX_SHADER \n "
2013-10-29 17:38:22 +00:00
" #ifdef RTLIGHT \n "
" uniform vec3 l_lightposition; \n "
// #if defined(SPECULAR) || defined(OFFSETMAPPING)
// uniform vec3 e_eyepos;
// #endif
" #if defined(PCF) || defined(CUBE) || defined(SPOT) \n "
" uniform mat4 l_cubematrix; \n "
" #endif \n "
" attribute vec3 v_normal; \n "
" attribute vec3 v_svector; \n "
" attribute vec3 v_tvector; \n "
" #endif \n "
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
" attribute vec2 v_texcoord; \n "
" attribute vec2 v_lmcoord; \n "
2012-08-04 01:35:52 +00:00
" attribute vec4 v_colour; \n "
2013-10-29 17:38:22 +00:00
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
" void main (void) \n "
" { \n "
" tc = v_texcoord.st; \n "
" lm = v_lmcoord.st; \n "
2012-08-04 01:35:52 +00:00
" vc = v_colour; \n "
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
" gl_Position = ftetransform(); \n "
2013-10-29 17:38:22 +00:00
" #ifdef RTLIGHT \n "
//light position is in model space, which is handy.
" vec3 lightminusvertex = l_lightposition - v_position.xyz; \n "
//no bumpmapping, so we can just use distance without regard for actual surface direction. we still do scalecos stuff. you might notice it on steep slopes.
" lightvector = lightminusvertex; \n "
2014-01-13 02:42:25 +00:00
// lightvector.x = dot(lightminusvertex, v_svector.xyz);
2013-10-29 17:38:22 +00:00
// lightvector.y = dot(lightminusvertex, v_tvector.xyz);
// lightvector.z = dot(lightminusvertex, v_normal.xyz);
// #if defined(SPECULAR)||defined(OFFSETMAPPING)
// vec3 eyeminusvertex = e_eyepos - v_position.xyz;
2014-01-13 02:42:25 +00:00
// eyevector.x = dot(eyeminusvertex, v_svector.xyz);
2013-10-29 17:38:22 +00:00
// eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
// eyevector.z = dot(eyeminusvertex, v_normal.xyz);
// #endif
" #if defined(PCF) || defined(SPOT) || defined(CUBE) \n "
//for texture projections/shadowmapping on dlights
" vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0)); \n "
" #endif \n "
" #endif \n "
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
//four texture passes
" uniform sampler2D s_t0; \n "
" uniform sampler2D s_t1; \n "
" uniform sampler2D s_t2; \n "
" uniform sampler2D s_t3; \n "
//mix values
" uniform sampler2D s_t4; \n "
2013-10-29 17:38:22 +00:00
" #ifdef PCF \n "
2013-11-10 21:14:28 +00:00
" uniform sampler2DShadow s_t5; \n "
2013-10-29 17:38:22 +00:00
" #include \" sys/pcf.h \" \n "
" #endif \n "
2013-11-10 21:14:28 +00:00
" #ifdef CUBE \n "
" uniform samplerCube s_t6; \n "
" #endif \n "
2013-10-29 17:38:22 +00:00
//light levels
" uniform vec4 e_lmscale; \n "
" #ifdef RTLIGHT \n "
" uniform float l_lightradius; \n "
" uniform vec3 l_lightcolour; \n "
" uniform vec3 l_lightcolourscale; \n "
" #endif \n "
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
" void main (void) \n "
" { \n "
2013-10-29 17:38:22 +00:00
" vec4 r; \n "
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
" vec4 m = texture2D(s_t4, lm); \n "
2013-10-29 17:38:22 +00:00
" r = texture2D(s_t0, tc)*m.r; \n "
" r += texture2D(s_t1, tc)*m.g; \n "
" r += texture2D(s_t2, tc)*m.b; \n "
" r += texture2D(s_t3, tc)*(1.0 - (m.r + m.g + m.b)); \n "
//vertex colours provide a scaler that applies even through rtlights.
" r *= vc; \n "
" #ifdef RTLIGHT \n "
" vec3 nl = normalize(lightvector); \n "
" float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0); \n "
" vec3 diff; \n "
// #ifdef BUMP
// colorscale *= (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0));
// #else
" colorscale *= (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0)); \n "
// #endif
// #ifdef SPECULAR
// vec3 halfdir = normalize(normalize(eyevector) + nl);
// float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);
// diff += l_lightcolourscale.z * spec * specs.rgb;
// #endif
" #if defined(SPOT) \n "
" if (vtexprojcoord.w < 0.0) discard; \n "
" vec2 spot = ((vtexprojcoord.st)/vtexprojcoord.w); \n "
" colorscale *= 1.0-(dot(spot,spot)); \n "
" #endif \n "
" #ifdef PCF \n "
" colorscale *= ShadowmapFilter(s_t5); \n "
" #endif \n "
" r.rgb *= colorscale * l_lightcolour; \n "
2013-11-10 21:14:28 +00:00
" #ifdef CUBE \n "
" r.rgb *= textureCube(s_t6, vtexprojcoord.xyz).rgb; \n "
" #endif \n "
2013-10-29 17:38:22 +00:00
" gl_FragColor = fog4additive(r); \n "
" #else \n "
//lightmap is greyscale in m.a. probably we should just scale the texture mix, but precision errors when editing make me paranoid.
" r *= e_lmscale*vec4(m.aaa,1.0); \n "
" gl_FragColor = fog4(r); \n "
" #endif \n "
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
" } \n "
" #endif \n "
} ,
# endif
2012-11-27 03:23:19 +00:00
# ifdef D3D11QUAKE
{ QR_DIRECT3D11 , 11 , " terrain " ,
" struct a2v \n "
" { \n "
" float4 pos: POSITION; \n "
" float4 tc: TEXCOORD0; \n "
" float4 vcol: COLOR0; \n "
" }; \n "
" struct v2f \n "
" { \n "
" float4 pos: SV_POSITION; \n "
" float2 tc: TEXCOORD0; \n "
" float2 lmtc: TEXCOORD1; \n "
" float4 vcol: COLOR0; \n "
2013-11-10 21:14:28 +00:00
" float3 vtexprojcoord: TEXCOORD2; \n "
" float3 vtexprojcoord: TEXCOORD2; \n "
2012-11-27 03:23:19 +00:00
" }; \n "
" #include <ftedefs.h> \n "
" #ifdef VERTEX_SHADER \n "
" v2f main (a2v inp) \n "
" { \n "
" v2f outp; \n "
" outp.pos = mul(m_model, inp.pos); \n "
" outp.pos = mul(m_view, outp.pos); \n "
" outp.pos = mul(m_projection, outp.pos); \n "
" outp.tc = inp.tc.xy; \n "
" outp.lmtc = inp.tc.zw; \n "
" outp.vcol = inp.vcol; \n "
" return outp; \n "
" } \n "
" #endif \n "
" #ifdef FRAGMENT_SHADER \n "
2013-11-10 21:14:28 +00:00
" Texture2D shaderTexture[7]; \n "
" SamplerState SampleType[7]; \n "
2012-11-27 03:23:19 +00:00
" float4 main (v2f inp) : SV_TARGET \n "
" { \n "
2013-11-10 21:14:28 +00:00
" float4 result; \n "
" float4 base = shaderTexture[0].Sample(SampleType[0], inp.tc); \n "
" #ifdef BUMP \n "
" float4 bump = shaderTexture[1].Sample(SampleType[1], inp.tc); \n "
" #else \n "
" float4 bump = float4(0, 0, 1, 0); \n "
" #endif \n "
" float4 spec = shaderTexture[2].Sample(SampleType[2], inp.tc); \n "
" #ifdef CUBE \n "
" float4 cubemap = shaderTexture[3].Sample(SampleType[3], inp.vtexprojcoord); \n "
" #endif \n "
//shadowmap 2d
" #ifdef LOWER \n "
" float4 lower = shaderTexture[5].Sample(SampleType[5], inp.tc); \n "
" base += lower; \n "
" #endif \n "
" #ifdef UPPER \n "
" float4 upper = shaderTexture[6].Sample(SampleType[6], inp.tc); \n "
" base += upper; \n "
" #endif \n "
" float lightscale = max(1.0 - (dot(inp.lightvector,inp.lightvector)/(l_lightradius*l_lightradius)), 0.0); \n "
" float3 nl = normalize(inp.lightvector); \n "
" float bumpscale = max(dot(bump.xyz, nl), 0.0); \n "
" float3 halfdir = normalize(normalize(eyevector) + nl); \n "
" float specscale = pow(max(dot(halfdir, bumps), 0.0), 32.0 * spec.a); \n "
2012-11-27 03:23:19 +00:00
2013-11-10 21:14:28 +00:00
" result.a = base.a; \n "
" result.rgb = base.rgb * (l_lightcolourscale.x + l_lightcolourscale.y * bumpscale); //amient light + diffuse \n "
" result.rgb += spec.rgb * l_lightcolourscale.z * specscale; //specular \n "
2012-11-27 03:23:19 +00:00
2013-11-10 21:14:28 +00:00
" result.rgb *= lightscale; //fade light by distance \n "
" #ifdef CUBE \n "
" result.rgb *= cubemap.rgb; //fade by cubemap \n "
" #endif \n "
2012-11-27 03:23:19 +00:00
2013-11-10 21:14:28 +00:00
" return result; \n "
2012-11-27 03:23:19 +00:00
" } \n "
" #endif \n "
} ,
# endif