c6c3d3f4e0
Quick hack preliminary d3d11 renderer. I'm not likely to touch this again for quite some time. Sys_Error works properly on android, with an error message shown. Should be less of a stab in the dark if you get errors. Seg faults are still instantly fatal. Not much I can reliably do about those - most of the juicy ones will likely occur within the gl drivers (even if its my fault) and java will still call in to it. Stereoscopic (quad-buffered) rendering is in the gl renderer. You'll likely need a quatro to use it despite it being a gl 1.0 feature. No idea about ati. See r_stereo_method for non-quad-buffered alternatives. Tweaked networking to not overflow so much. Needs testing against other qw clients. Fixed an issue with surface numbers > 32k on limit-breaking maps. Fixed a preparse issue resulting in QW clients dying with the ne_ruins map's progs. Support for the DP-variant of BSP2. The depricated RMQ variant is still supported. QTV proxy now uses ipv6 hybrid sockets where possible. Preliminary pext support. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4105 fc73d0e0-1445-4013-8a0c-d673dee63da5
1246 lines
32 KiB
C
1246 lines
32 KiB
C
/*
|
|
WARNING: THIS FILE IS GENERATED BY 'generatebuiltinsl.c'.
|
|
YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|
*/
|
|
|
|
#ifdef GLQUAKE
|
|
{QR_OPENGL, 110, "altwater",
|
|
//modifier: REFLECT (s_t2 is a reflection instead of diffusemap)
|
|
//modifier: STRENGTH (0.1 = fairly gentle, 0.2 = big waves)
|
|
//modifier: FRESNEL (5=water)
|
|
//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"
|
|
|
|
"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"
|
|
"uniform sampler2D s_t0; //refract\n"
|
|
"uniform sampler2D s_t1; //normalmap\n"
|
|
"uniform sampler2D s_t2; //diffuse/reflection\n"
|
|
"#ifdef RIPPLEMAP\n"
|
|
"uniform sampler2D s_t3; //ripplemap\n"
|
|
"#endif\n"
|
|
|
|
"uniform float e_time;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"vec2 stc, ntc;\n"
|
|
"vec3 n, refr, refl, fres;\n"
|
|
"float f;\n"
|
|
"stc = (1.0 + (tf.xy / tf.w)) * 0.5;\n"
|
|
|
|
//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
|
|
"n = (texture2D(s_t1, TXSCALE*tc + vec2(e_time*0.1, 0.0)).xyz);\n"
|
|
"n += (texture2D(s_t1, TXSCALE*tc - vec2(0, e_time*0.097)).xyz);\n"
|
|
"n -= 1.0 - 4.0/256.0;\n"
|
|
|
|
"#ifdef RIPPLEMAP\n"
|
|
"n += texture2D(s_t3, stc)*3;\n"
|
|
"#endif\n"
|
|
|
|
//the fresnel term decides how transparent the water should be
|
|
"f = pow(1.0-abs(dot(normalize(n), normalize(eye))), float(FRESNEL));\n"
|
|
|
|
"refr = texture2D(s_t0, stc + n.st*STRENGTH).rgb * TINT;\n"
|
|
"#ifdef REFLECT\n"
|
|
"refl = texture2D(s_t2, stc - n.st*STRENGTH).rgb;\n"
|
|
"#else\n"
|
|
"refl = texture2D(s_t2, ntc).xyz;\n"
|
|
"#endif\n"
|
|
// refl += 0.1*pow(dot(n, vec3(0.0,0.0,1.0)), 64.0);
|
|
|
|
"fres = refr * (1.0-f) + refl*f;\n"
|
|
|
|
// fres = texture2D(s_t2, stc).xyz;
|
|
|
|
"gl_FragColor = vec4(fres, 1.0);\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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",
|
|
"!!cvarv r_bloom_filter\n"
|
|
//the bloom filter
|
|
//filter out any texels which are not to bloom
|
|
|
|
"uniform vec3 cvar_r_bloom_filter;\n"
|
|
"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"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"gl_FragColor.rgb = (texture2D(s_t0, tc).rgb - cvar_r_bloom_filter)/(1.0-cvar_r_bloom_filter);\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#ifdef GLQUAKE
|
|
{QR_OPENGL, 110, "bloom_final",
|
|
"!!cvarf r_bloom\n"
|
|
"uniform float cvar_r_bloom;\n"
|
|
//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"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"gl_FragColor = \n"
|
|
"texture2D(s_t0, tc) +\n"
|
|
"cvar_r_bloom*(\n"
|
|
"texture2D(s_t1, tc) +\n"
|
|
"texture2D(s_t2, tc) +\n"
|
|
"texture2D(s_t3, tc)\n"
|
|
") ;\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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"
|
|
"gl_Position = v_position;\n"
|
|
"}\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"
|
|
"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"
|
|
},
|
|
#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.
|
|
|
|
"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 = texture2D(s_t0, tc) * vc;\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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"
|
|
|
|
//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"
|
|
"#ifdef VERTEX_SHADER\n"
|
|
"#include \"sys/skeletal.h\"\n"
|
|
"attribute vec2 v_texcoord;\n"
|
|
"uniform vec3 e_light_dir;\n"
|
|
"uniform vec3 e_light_mul;\n"
|
|
"uniform vec3 e_light_ambient;\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"vec3 n;\n"
|
|
"gl_Position = skeletaltransform_n(n);\n"
|
|
"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"
|
|
"uniform sampler2D s_t0;\n"
|
|
"#ifdef LOWER\n"
|
|
"uniform sampler2D s_t1;\n"
|
|
"uniform vec3 e_lowercolour;\n"
|
|
"#endif\n"
|
|
"#ifdef UPPER\n"
|
|
"uniform sampler2D s_t2;\n"
|
|
"uniform vec3 e_uppercolour;\n"
|
|
"#endif\n"
|
|
"#ifdef FULLBRIGHT\n"
|
|
"uniform sampler2D s_t3;\n"
|
|
"#endif\n"
|
|
"uniform vec4 e_colourident;\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"vec4 col, sp;\n"
|
|
"col = texture2D(s_t0, tc);\n"
|
|
"#ifdef UPPER\n"
|
|
"vec4 uc = texture2D(s_t2, tc);\n"
|
|
"col.rgb = mix(col.rgb, uc.rgb*e_uppercolour, uc.a);\n"
|
|
"#endif\n"
|
|
"#ifdef LOWER\n"
|
|
"vec4 lc = texture2D(s_t1, tc);\n"
|
|
"col.rgb = mix(col.rgb, lc.rgb*e_lowercolour, lc.a);\n"
|
|
"#endif\n"
|
|
"col.rgb *= light;\n"
|
|
"#ifdef FULLBRIGHT\n"
|
|
"vec4 fb = texture2D(s_t3, tc);\n"
|
|
"col.rgb = mix(col.rgb, fb.rgb, fb.a);\n"
|
|
"#endif\n"
|
|
"gl_FragColor = fog4(col * e_colourident);\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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
|
|
#ifdef GLQUAKE
|
|
{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"
|
|
"gl_FragColor = fog4blend(texture2D(s_t0, tc) * vc * e_colourident);\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#ifdef GLQUAKE
|
|
{QR_OPENGL, 110, "defaultwall",
|
|
"!!permu OFFSETMAPPING\n"
|
|
"!!permu FULLBRIGHT\n"
|
|
"!!permu FOG\n"
|
|
"!!permu LIGHTSTYLED\n"
|
|
"!!cvarf r_glsl_offsetmapping_scale\n"
|
|
|
|
//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"
|
|
"#if defined(OFFSETMAPPING)\n"
|
|
"varying vec3 eyevector;\n"
|
|
"#endif\n"
|
|
|
|
"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?
|
|
"varying vec2 lm, lm2, lm3, lm4;\n"
|
|
"#else\n"
|
|
"varying vec2 lm;\n"
|
|
"#endif\n"
|
|
|
|
"#ifdef VERTEX_SHADER\n"
|
|
"attribute vec2 v_texcoord;\n"
|
|
"attribute vec2 v_lmcoord;\n"
|
|
"#ifdef LIGHTSTYLED\n"
|
|
"attribute vec2 v_lmcoord2;\n"
|
|
"attribute vec2 v_lmcoord3;\n"
|
|
"attribute vec2 v_lmcoord4;\n"
|
|
"#endif\n"
|
|
"#if defined(OFFSETMAPPING)\n"
|
|
"uniform vec3 e_eyepos;\n"
|
|
"attribute vec3 v_normal;\n"
|
|
"attribute vec3 v_svector;\n"
|
|
"attribute vec3 v_tvector;\n"
|
|
"#endif\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"#if defined(OFFSETMAPPING)\n"
|
|
"vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n"
|
|
"eyevector.x = -dot(eyeminusvertex, v_svector.xyz);\n"
|
|
"eyevector.y = dot(eyeminusvertex, v_tvector.xyz);\n"
|
|
"eyevector.z = dot(eyeminusvertex, v_normal.xyz);\n"
|
|
"#endif\n"
|
|
"tc = v_texcoord;\n"
|
|
"lm = v_lmcoord;\n"
|
|
"#ifdef LIGHTSTYLED\n"
|
|
"lm2 = v_lmcoord2;\n"
|
|
"lm3 = v_lmcoord3;\n"
|
|
"lm4 = v_lmcoord4;\n"
|
|
"#endif\n"
|
|
"gl_Position = ftetransform();\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
|
|
|
|
"#ifdef FRAGMENT_SHADER\n"
|
|
//samplers
|
|
"uniform sampler2D s_t0;\n"
|
|
"uniform sampler2D s_t1;\n"
|
|
"#ifdef OFFSETMAPPING\n"
|
|
"uniform sampler2D s_t2;\n"
|
|
"#endif\n"
|
|
"#ifdef FULLBRIGHT\n"
|
|
"uniform sampler2D s_t4;\n"
|
|
"#endif\n"
|
|
"#ifdef LIGHTSTYLED\n"
|
|
"uniform sampler2D s_t5;\n"
|
|
"uniform sampler2D s_t6;\n"
|
|
"uniform sampler2D s_t7;\n"
|
|
"#endif\n"
|
|
|
|
"#ifdef LIGHTSTYLED\n"
|
|
"uniform vec4 e_lmscale[4];\n"
|
|
"#else\n"
|
|
"uniform vec4 e_lmscale;\n"
|
|
"#endif\n"
|
|
"uniform vec4 e_colourident;\n"
|
|
"#ifdef OFFSETMAPPING\n"
|
|
"#include \"sys/offsetmapping.h\"\n"
|
|
"#endif\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"#ifdef OFFSETMAPPING\n"
|
|
"vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n"
|
|
"#define tc tcoffsetmap\n"
|
|
"#endif\n"
|
|
"gl_FragColor = texture2D(s_t0, tc);\n"
|
|
"#ifdef LIGHTSTYLED\n"
|
|
"vec4 lightmaps;\n"
|
|
"lightmaps = texture2D(s_t1, lm ) * e_lmscale[0];\n"
|
|
"lightmaps += texture2D(s_t5, lm2) * e_lmscale[1];\n"
|
|
"lightmaps += texture2D(s_t6, lm3) * e_lmscale[2];\n"
|
|
"lightmaps += texture2D(s_t7, lm4) * e_lmscale[3];\n"
|
|
"gl_FragColor.rgb *= lightmaps.rgb;\n"
|
|
"#else\n"
|
|
"gl_FragColor.rgb *= (texture2D(s_t1, lm) * e_lmscale).rgb;\n"
|
|
"#endif\n"
|
|
|
|
"#ifdef FULLBRIGHT\n"
|
|
"gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
|
|
"#endif\n"
|
|
"gl_FragColor = gl_FragColor * e_colourident;\n"
|
|
"#ifdef FOG\n"
|
|
"gl_FragColor = fog4(gl_FragColor);\n"
|
|
"#endif\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#ifdef GLQUAKE
|
|
{QR_OPENGL, 110, "defaultwarp",
|
|
"!!cvarf r_wateralpha\n"
|
|
"!!permu FOG\n"
|
|
|
|
//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"
|
|
"attribute vec2 v_texcoord;\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"tc = v_texcoord.st;\n"
|
|
"gl_Position = ftetransform();\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
"#ifdef FRAGMENT_SHADER\n"
|
|
"uniform sampler2D s_t0;\n"
|
|
"uniform float e_time;\n"
|
|
"uniform float cvar_r_wateralpha;\n"
|
|
"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"
|
|
"vec3 ts = vec3(texture2D(s_t0, ntc));\n"
|
|
"gl_FragColor = fog4(vec4(ts, cvar_r_wateralpha));\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#ifdef GLQUAKE
|
|
{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
|
|
#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"
|
|
"vec3 lmsamp = texture2D(s_t2, lm).rgb*lmscale;\n"
|
|
"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"
|
|
"!!permu SPECULAR\n"
|
|
"!!permu OFFSETMAPPING\n"
|
|
"!!permu SKELETAL\n"
|
|
"!!permu FOG\n"
|
|
"!!cvarf r_glsl_offsetmapping_scale\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
|
|
|
|
"#if 0 && defined(GL_ARB_texture_gather) && defined(PCF) \n"
|
|
"#extension GL_ARB_texture_gather : enable\n"
|
|
"#endif\n"
|
|
|
|
|
|
"varying vec2 tcbase;\n"
|
|
"varying vec3 lightvector;\n"
|
|
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
|
|
"varying vec3 eyevector;\n"
|
|
"#endif\n"
|
|
"#if defined(PCF) || defined(CUBEPROJ)\n"
|
|
"varying vec4 vtexprojcoord;\n"
|
|
"uniform mat4 l_cubematrix;\n"
|
|
"#ifndef SPOT\n"
|
|
"uniform mat4 l_projmatrix;\n"
|
|
"#endif\n"
|
|
"#endif\n"
|
|
"#ifdef VERTEX_SHADER\n"
|
|
"#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"
|
|
"lightvector.x = -dot(lightminusvertex, s.xyz);\n"
|
|
"lightvector.y = dot(lightminusvertex, t.xyz);\n"
|
|
"lightvector.z = dot(lightminusvertex, n.xyz);\n"
|
|
"#if defined(SPECULAR)||defined(OFFSETMAPPING)\n"
|
|
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
|
|
"eyevector.x = -dot(eyeminusvertex, s.xyz);\n"
|
|
"eyevector.y = dot(eyeminusvertex, t.xyz);\n"
|
|
"eyevector.z = dot(eyeminusvertex, n.xyz);\n"
|
|
"#endif\n"
|
|
"#if defined(PCF) || defined(SPOT) || defined(PROJECTION)\n"
|
|
//for texture projections/shadowmapping on dlights
|
|
"vtexprojcoord = (l_cubematrix*vec4(w.xyz, 1.0));\n"
|
|
"#endif\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
|
|
|
|
|
|
|
|
"#ifdef FRAGMENT_SHADER\n"
|
|
"#include \"sys/fog.h\"\n"
|
|
"uniform sampler2D s_t0;\n"
|
|
|
|
"#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)\n"
|
|
"uniform sampler2D s_t1;\n"
|
|
"#endif\n"
|
|
"#ifdef SPECULAR\n"
|
|
"uniform sampler2D s_t2;\n"
|
|
"#endif\n"
|
|
"#ifdef CUBEPROJ\n"
|
|
"uniform samplerCube s_t3;\n"
|
|
"#endif\n"
|
|
"#ifdef PCF\n"
|
|
"#ifdef CUBESHADOW\n"
|
|
"uniform samplerCubeShadow s_t4;\n"
|
|
"#else\n"
|
|
"#if 0//def GL_ARB_texture_gather\n"
|
|
"uniform sampler2D s_t4;\n"
|
|
"#else\n"
|
|
"uniform sampler2DShadow s_t4;\n"
|
|
"#endif\n"
|
|
"#endif\n"
|
|
"#endif\n"
|
|
|
|
|
|
"uniform float l_lightradius;\n"
|
|
"uniform vec3 l_lightcolour;\n"
|
|
"uniform vec3 l_lightcolourscale;\n"
|
|
|
|
|
|
|
|
"#ifdef PCF\n"
|
|
//#define shadow2DProj(t,c) (vec2(1.0,1.0))
|
|
//#define shadow2DProj(t,c) texture2DProj(t,c).rg
|
|
|
|
"float ShadowmapFilter(void)\n"
|
|
"{\n"
|
|
"#ifdef SPOT\n"
|
|
"const vec3 texscale = vec3(1.0/512.0, 1.0/512.0, 1.0);\n"
|
|
"#else\n"
|
|
"const vec3 texscale = vec3(1.0/(512.0*3.0), 1.0/(512.0*2.0), 1.0);\n"
|
|
"#endif\n"
|
|
|
|
//dehomogonize input
|
|
"vec3 shadowcoord = (vtexprojcoord.xyz / vtexprojcoord.w);\n"
|
|
|
|
"#ifdef CUBESHADOW\n"
|
|
// vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w;
|
|
// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r
|
|
"#else\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
|
|
"shadowcoord.xyz = (shadowcoord.xyz + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5);\n"
|
|
"#else\n"
|
|
//figure out which axis to use
|
|
//texture is arranged thusly:
|
|
//forward left up
|
|
//back right down
|
|
"vec3 dir = abs(shadowcoord);\n"
|
|
//assume z is the major axis (ie: forward from the light)
|
|
"vec3 t = shadowcoord;\n"
|
|
"float ma = dir.z;\n"
|
|
"vec4 axis = vec4(1.0, 1.0, 1.0, 0.0);\n"
|
|
"if (dir.x > ma)\n"
|
|
"{\n"
|
|
"ma = dir.x;\n"
|
|
"t = shadowcoord.zyx;\n"
|
|
"axis.x = 3.0;\n"
|
|
"}\n"
|
|
"if (dir.y > ma)\n"
|
|
"{\n"
|
|
"ma = dir.y;\n"
|
|
"t = shadowcoord.xzy;\n"
|
|
"axis.x = 5.0;\n"
|
|
"}\n"
|
|
"if (t.z > 0.0)\n"
|
|
"{\n"
|
|
"axis.y = 3.0;\n"
|
|
"t.z = -t.z;\n"
|
|
"}\n"
|
|
|
|
|
|
//we also need to pass the result through the light's projection matrix too
|
|
"vec4 nsc =l_projmatrix*vec4(t, 1.0);\n"
|
|
"shadowcoord = (nsc.xyz / nsc.w);\n"
|
|
|
|
//now bias and relocate it
|
|
"shadowcoord = (shadowcoord + axis.xyz) * vec3(0.5/3.0, 0.5/2.0, 0.5);\n"
|
|
"#endif\n"
|
|
|
|
"#if 0//def GL_ARB_texture_gather\n"
|
|
"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"
|
|
"#define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*texscale.xyz)).r\n"
|
|
"float s = 0.0;\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"
|
|
"#endif\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
|
|
|
|
"#ifdef OFFSETMAPPING\n"
|
|
"#include \"sys/offsetmapping.h\"\n"
|
|
"#endif\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
//read raw texture samples (offsetmapping munges the tex coords first)
|
|
"#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"
|
|
"#if defined(BUMP) || defined(SPECULAR)\n"
|
|
"vec3 bumps = normalize(vec3(texture2D(s_t1, tcbase)) - 0.5);\n"
|
|
"#endif\n"
|
|
"#ifdef SPECULAR\n"
|
|
"vec4 specs = texture2D(s_t2, tcbase);\n"
|
|
"#endif\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\n"
|
|
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(bumps, nl), 0.0));\n"
|
|
"#else\n"
|
|
//we still do bumpmapping even without bumps to ensure colours are always sane. light.exe does it too.
|
|
"diff = bases * (l_lightcolourscale.x + l_lightcolourscale.y * max(dot(vec3(0.0, 0.0, 1.0), nl), 0.0));\n"
|
|
"#endif\n"
|
|
|
|
|
|
"#ifdef SPECULAR\n"
|
|
"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"
|
|
"#endif\n"
|
|
|
|
|
|
|
|
"#ifdef CUBEPROJ\n"
|
|
/*filter the colour by the cubemap projection*/
|
|
"diff *= textureCube(s_t3, vtexprojcoord.xyz).rgb;\n"
|
|
"#endif\n"
|
|
|
|
"#if defined(SPOT)\n"
|
|
/*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"
|
|
"#endif\n"
|
|
|
|
"#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"
|
|
// gl_FragColor.rgb = vec3(ShadowmapFilter());
|
|
|
|
"#endif\n"
|
|
|
|
"#if defined(PROJECTION)\n"
|
|
/*2d projection, not used*/
|
|
// diff *= texture2d(s_t3, shadowcoord);
|
|
"#endif\n"
|
|
|
|
"gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour);\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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"
|
|
"v_stc = (1.0+(gl_Position.xy / gl_Position.w))/2.0;\n"
|
|
"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"
|
|
"uniform vec3 e_rendertexturescale;\n"
|
|
"uniform float cvar_r_waterwarp;\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"float amptemp;\n"
|
|
"vec3 edge;\n"
|
|
"edge = texture2D( s_t2, v_edge ).rgb;\n"
|
|
"amptemp = (0.010 / 0.625) * cvar_r_waterwarp * edge.x;\n"
|
|
"vec3 offset;\n"
|
|
"offset = texture2D( s_t1, v_warp ).rgb;\n"
|
|
"offset.x = (offset.x - 0.5) * 2.0;\n"
|
|
"offset.y = (offset.y - 0.5) * 2.0;\n"
|
|
"vec2 temp;\n"
|
|
"temp.x = v_stc.x + offset.x * amptemp;\n"
|
|
"temp.y = v_stc.y + offset.y * amptemp;\n"
|
|
"gl_FragColor = texture2D( s_t0, temp*e_rendertexturescale.st );\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#ifdef GLQUAKE
|
|
{QR_OPENGL, 110, "terrain",
|
|
"!!permu FOG\n"
|
|
"#include \"sys/fog.h\"\n"
|
|
"varying vec2 tc;\n"
|
|
"varying vec2 lm;\n"
|
|
"varying vec4 vc;\n"
|
|
|
|
"#ifdef VERTEX_SHADER\n"
|
|
"attribute vec2 v_texcoord;\n"
|
|
"attribute vec2 v_lmcoord;\n"
|
|
"attribute vec4 v_colour;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"tc = v_texcoord.st;\n"
|
|
"lm = v_lmcoord.st;\n"
|
|
"vc = v_colour;\n"
|
|
"gl_Position = ftetransform();\n"
|
|
"}\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"
|
|
|
|
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"vec4 m = texture2D(s_t4, lm);\n"
|
|
|
|
"gl_FragColor = fog4(vc*vec4(m.aaa,1.0)*(\n"
|
|
"texture2D(s_t0, tc)*m.r\n"
|
|
"+ texture2D(s_t1, tc)*m.g\n"
|
|
"+ texture2D(s_t2, tc)*m.b\n"
|
|
"+ texture2D(s_t3, tc)*(1.0 - (m.r + m.g + m.b))\n"
|
|
"));\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|