mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-26 13:50:53 +00:00
2e1a70e319
maplist command now generates links. implemented skin objects for q3. added a csqc builtin for it. also supports compositing skins. playing demos inside zips/pk3s/paks should now work. bumped default rate cvar. added cl_transfer to attempt to connect to a new server without disconnecting first. rewrote fog command. alpha and mindist arguments are now supported. fog change also happens over a short time period. added new args to the showpic console command. can now create clickable items for touchscreen/absmouse users. fixed menus to properly support right-aligned text. this finally fixes variable-width fonts. rewrote console tab completion suggestions display. now clickable links. strings obtained from qc are now marked as const. this has required quite a few added consts all over the place. probably crappy attempt at adding joypad support to the sdl port. no idea if it works. changed key bind event code. buttons now track which event they should trigger when released, instead of being the same one the whole time. this allows +forward etc clickable buttons on screen. Also simplified modifier keys - they no longer trigger random events when pressing the modifier key itself. Right modifiers can now be bound separately from left modifiers. Right will use left's binding if not otherwise bound. Bind assumes left if there's no prefix. multiplayer->setup->network menu no longer crashes. added rgb colours to the translation view (but not to the colour-changing keys). added modelviewer command to view models. added menu_mods menu to switch mods in a more friendly way. will be shown by default if multiple manifests exist in the binarydir. clamped classic tracer density. scrag particles no longer look quite so buggy. added ifdefs to facilitate a potential winrt port. the engine should now have no extra dependencies, but still needs system code+audio drivers to be written. if it can't set a renderer, it'll now try to use *every* renderer until it finds one that works. added experimental mapcluster server mode (that console command). New maps will be started up as required. rewrote skeletal blending code a bit. added cylinder geomtypes. fix cfg_save writing to the wrong path bug. VFS_CLOSE now returns a boolean. false means there was some sort of fatal error (either crc when reading was bad, or the write got corrupted or something). Typically ignorable, depends how robust you want to be. win32 tls code now supports running as a server. added connect tls://address support, as well as equivalent sv_addport support. exposed basic model loading api to plugins. d3d11 backend now optionally supports tessellation hlsl. no suitable hlsl provided by default. !!tess to enable. attempted to add gamma ramp support for d3d11. added support for shader blobs to speed up load times. r_shaderblobs 1 to enable. almost vital for d3d11. added vid_srgb cvar. shadowless lights are no longer disabled if shadows are not supported. attempt to add support for touchscreens in win7/8. Wrote gimmicky lua support, using lua instead of ssqc. define VM_LUA to enable. updated saved game code. can again load saved games from vanilla-like engines. changed scale clamping. 0.0001 should no longer appear as 1. changed default mintic from 0.03 to 0.013 to match vanilla qw. I don't know why it was at 0.03. probably a typo. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4623 fc73d0e0-1445-4013-8a0c-d673dee63da5
2592 lines
67 KiB
C
2592 lines
67 KiB
C
/*
|
|
WARNING: THIS FILE IS GENERATED BY 'generatebuiltinsl.c'.
|
|
YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|
*/
|
|
|
|
#ifdef GLQUAKE
|
|
{QR_OPENGL, 110, "altwater",
|
|
"!!cvarf r_glsl_turbscale\n"
|
|
//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)
|
|
|
|
"uniform float cvar_r_glsl_turbscale;\n"
|
|
|
|
"#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"
|
|
"#ifndef FOGTINT\n"
|
|
"#define FOGTINT vec3(0.2, 0.3, 0.2)\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 DEPTH\n"
|
|
"uniform sampler2D s_t3; //refraction depth\n"
|
|
"#define s_ripplemap s_t4\n"
|
|
"#else\n"
|
|
"#define s_ripplemap s_t3\n"
|
|
"#endif\n"
|
|
"#ifdef RIPPLEMAP\n"
|
|
"uniform sampler2D s_ripplemap; //ripplemap\n"
|
|
"#endif\n"
|
|
|
|
"uniform float e_time;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"vec2 stc, ntc;\n"
|
|
"vec3 n, refr, refl;\n"
|
|
"float fres;\n"
|
|
"float depth;\n"
|
|
"stc = (1.0 + (tf.xy / tf.w)) * 0.5;\n"
|
|
//hack the texture coords slightly so that there are no obvious gaps
|
|
"stc.t -= 1.5*norm.z/1080.0;\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_ripplemap, stc).rgb*3.0;\n"
|
|
"#endif\n"
|
|
|
|
//the fresnel term decides how transparent the water should be
|
|
"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.
|
|
"float gdepth = texture2D(s_t3, stc).x;\n"
|
|
"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)
|
|
"if (depth < 100.0)\n"
|
|
"n *= depth/100.0;\n"
|
|
"#else\n"
|
|
"depth = 1.0;\n"
|
|
"#endif \n"
|
|
|
|
|
|
//refraction image (and water fog, if possible)
|
|
"refr = texture2D(s_t0, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT;\n"
|
|
"#ifdef DEPTH\n"
|
|
"refr = mix(refr, FOGTINT, min(depth/4096.0, 1.0));\n"
|
|
"#endif\n"
|
|
|
|
//reflection/diffuse
|
|
"#ifdef REFLECT\n"
|
|
"refl = texture2D(s_t2, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb;\n"
|
|
"#else\n"
|
|
"refl = texture2D(s_t2, ntc).xyz;\n"
|
|
"#endif\n"
|
|
//FIXME: add specular
|
|
|
|
//interplate by fresnel
|
|
"refr = mix(refr, refl, fres);\n"
|
|
|
|
//done
|
|
"gl_FragColor = vec4(refr, 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, "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"
|
|
|
|
},
|
|
#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"
|
|
"#ifdef MASK\n"
|
|
"float4 tc: TEXCOORD0;\n"
|
|
"#endif\n"
|
|
"};\n"
|
|
"struct v2f\n"
|
|
"{\n"
|
|
"float4 pos: SV_POSITION;\n"
|
|
"#ifdef MASK\n"
|
|
"float2 tc: TEXCOORD0;\n"
|
|
"#endif\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"
|
|
|
|
"#ifdef MASK\n"
|
|
"outp.tc = inp.tc.xy;\n"
|
|
"#endif\n"
|
|
|
|
"return outp;\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
"#ifdef FRAGMENT_SHADER\n"
|
|
"#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"
|
|
"{\n"
|
|
|
|
"#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"
|
|
"}\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 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"
|
|
"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"
|
|
"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
|
|
#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"
|
|
"!!permu BUMP\n"
|
|
"!!cvarf r_glsl_offsetmapping_scale\n"
|
|
"!!cvarf gl_specular\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"
|
|
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
|
|
"varying vec3 eyevector;\n"
|
|
"#endif\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"
|
|
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
|
|
"uniform vec3 e_eyepos;\n"
|
|
"#endif\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"#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"
|
|
"eyevector.x = dot(eyeminusvertex, s.xyz);\n"
|
|
"eyevector.y = dot(eyeminusvertex, t.xyz);\n"
|
|
"eyevector.z = dot(eyeminusvertex, n.xyz);\n"
|
|
"#else\n"
|
|
"vec3 n;\n"
|
|
"gl_Position = skeletaltransform_n(n);\n"
|
|
"#endif\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"
|
|
|
|
"#if defined(BUMP)\n"
|
|
"uniform sampler2D s_t4;\n"
|
|
"#endif\n"
|
|
|
|
"#if defined(SPECULAR)\n"
|
|
"uniform sampler2D s_t5;\n"
|
|
"uniform float cvar_gl_specular;\n"
|
|
"#endif\n"
|
|
|
|
"#ifdef OFFSETMAPPING\n"
|
|
"#include \"sys/offsetmapping.h\"\n"
|
|
"#endif\n"
|
|
|
|
|
|
|
|
"uniform vec4 e_colourident;\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"vec4 col, sp;\n"
|
|
|
|
"#ifdef OFFSETMAPPING\n"
|
|
"vec2 tcoffsetmap = offsetmap(s_t4, tc, eyevector);\n"
|
|
"#define tc tcoffsetmap\n"
|
|
"#endif\n"
|
|
|
|
"col = texture2D(s_t0, tc);\n"
|
|
"#ifdef UPPER\n"
|
|
"vec4 uc = texture2D(s_t2, tc);\n"
|
|
"col.rgb += uc.rgb*e_uppercolour*uc.a;\n"
|
|
"#endif\n"
|
|
"#ifdef LOWER\n"
|
|
"vec4 lc = texture2D(s_t1, tc);\n"
|
|
"col.rgb += lc.rgb*e_lowercolour*lc.a;\n"
|
|
"#endif\n"
|
|
"col.rgb *= light;\n"
|
|
|
|
"#if defined(BUMP) && defined(SPECULAR)\n"
|
|
"vec3 bumps = normalize(vec3(texture2D(s_t4, tc)) - 0.5);\n"
|
|
"vec4 specs = texture2D(s_t5, tc);\n"
|
|
|
|
"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"
|
|
|
|
"#ifdef FULLBRIGHT\n"
|
|
"vec4 fb = texture2D(s_t3, tc);\n"
|
|
// col.rgb = mix(col.rgb, fb.rgb, fb.a);
|
|
"col.rgb += fb.rgb * fb.a;\n"
|
|
"#endif\n"
|
|
|
|
"gl_FragColor = fog4(col * e_colourident);\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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"
|
|
|
|
"#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"
|
|
|
|
"#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
|
|
#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 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"
|
|
|
|
"sampler s_t0; /*diffuse*/\n"
|
|
"sampler s_t1; /*normal*/\n"
|
|
"sampler s_t2; /*specular*/\n"
|
|
"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"
|
|
"float4 solid = tex2D(s_t0, tccoord);\n"
|
|
|
|
"tccoord = (dir.xy + e_time*0.0625);\n"
|
|
"float4 clouds = tex2D(s_t1, tccoord);\n"
|
|
|
|
"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
|
|
#ifdef GLQUAKE
|
|
{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
|
|
{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"
|
|
"vec4 col = texture2D(s_t0, tc);\n"
|
|
"#ifdef MASK\n"
|
|
"if (col.a < float(MASK))\n"
|
|
"discard;\n"
|
|
"#endif\n"
|
|
"gl_FragColor = fog4blend(col * vc * e_colourident);\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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"
|
|
"return shaderTexture.Sample(SampleType, inp.tc) * inp.vcol;\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#ifdef GLQUAKE
|
|
{QR_OPENGL, 110, "defaultwall",
|
|
"!!permu DELUXE\n"
|
|
"!!permu FULLBRIGHT\n"
|
|
"!!permu FOG\n"
|
|
"!!permu LIGHTSTYLED\n"
|
|
"!!permu BUMP\n"
|
|
"!!permu SPECULAR\n"
|
|
"!!cvarf r_glsl_offsetmapping_scale\n"
|
|
"!!cvarf gl_specular\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) || defined(SPECULAR)\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) || defined(SPECULAR)\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) || defined(SPECULAR)\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; //diffuse\n"
|
|
"uniform sampler2D s_t1; //lightmap0\n"
|
|
"#if defined(BUMP) && (defined(OFFSETMAPPING) || defined(DELUXE) || defined(SPECULAR))\n"
|
|
"uniform sampler2D s_t2; //normal.rgb+height.a\n"
|
|
"#endif\n"
|
|
"#ifdef DELUXE\n"
|
|
"uniform sampler2D s_t3; //deluxe0\n"
|
|
"#endif\n"
|
|
"#ifdef FULLBRIGHT\n"
|
|
"uniform sampler2D s_t4; //fullbright\n"
|
|
"#endif\n"
|
|
"#ifdef SPECULAR\n"
|
|
"uniform sampler2D s_t5; //specular\n"
|
|
"#endif\n"
|
|
"#ifdef LIGHTSTYLED\n"
|
|
"uniform sampler2D s_t6; //lightmap1\n"
|
|
"uniform sampler2D s_t7; //lightmap2\n"
|
|
"uniform sampler2D s_t8; //lightmap3\n"
|
|
"uniform sampler2D s_t9; //deluxe1\n"
|
|
"uniform sampler2D s_t10; //deluxe2\n"
|
|
"uniform sampler2D s_t11; //deluxe3\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 SPECULAR\n"
|
|
"uniform float cvar_gl_specular;\n"
|
|
"#endif\n"
|
|
"#ifdef OFFSETMAPPING\n"
|
|
"#include \"sys/offsetmapping.h\"\n"
|
|
"#endif\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
//adjust texture coords for offsetmapping
|
|
"#ifdef OFFSETMAPPING\n"
|
|
"vec2 tcoffsetmap = offsetmap(s_t2, tc, eyevector);\n"
|
|
"#define tc tcoffsetmap\n"
|
|
"#endif\n"
|
|
|
|
//yay, regular texture!
|
|
"gl_FragColor = texture2D(s_t0, tc);\n"
|
|
|
|
"#if defined(BUMP) && (defined(DELUXE) || defined(SPECULAR))\n"
|
|
"vec3 norm = normalize(texture2D(s_t2, tc).rgb - 0.5);\n"
|
|
"#elif defined(SPECULAR) || defined(DELUXE)\n"
|
|
"vec3 norm = vec3(0, 0, 1); //specular lighting expects this to exist.\n"
|
|
"#endif\n"
|
|
|
|
//modulate that by the lightmap(s) including deluxemap(s)
|
|
"#ifdef LIGHTSTYLED\n"
|
|
"vec3 lightmaps;\n"
|
|
"#ifdef DELUXE\n"
|
|
"lightmaps = texture2D(s_t1, lm ).rgb * e_lmscale[0].rgb * dot(norm, texture2D(s_t3, lm ).rgb);\n"
|
|
"lightmaps += texture2D(s_t6, lm2).rgb * e_lmscale[1].rgb * dot(norm, texture2D(s_t9, lm2).rgb);\n"
|
|
"lightmaps += texture2D(s_t7, lm3).rgb * e_lmscale[2].rgb * dot(norm, texture2D(s_t10, lm3).rgb);\n"
|
|
"lightmaps += texture2D(s_t8, lm4).rgb * e_lmscale[3].rgb * dot(norm, texture2D(s_t11,lm4).rgb);\n"
|
|
"#else\n"
|
|
"lightmaps = texture2D(s_t1, lm ).rgb * e_lmscale[0].rgb;\n"
|
|
"lightmaps += texture2D(s_t6, lm2).rgb * e_lmscale[1].rgb;\n"
|
|
"lightmaps += texture2D(s_t7, lm3).rgb * e_lmscale[2].rgb;\n"
|
|
"lightmaps += texture2D(s_t8, lm4).rgb * e_lmscale[3].rgb;\n"
|
|
"#endif\n"
|
|
"#else\n"
|
|
"vec3 lightmaps = (texture2D(s_t1, lm) * e_lmscale).rgb;\n"
|
|
//modulate by the bumpmap dot light
|
|
"#ifdef DELUXE\n"
|
|
"lightmaps *= dot(norm, 2.0*(texture2D(s_t3, lm).rgb-0.5));\n"
|
|
"#endif\n"
|
|
"#endif\n"
|
|
|
|
"#ifdef SPECULAR\n"
|
|
"vec4 specs = texture2D(s_t5, tc);\n"
|
|
"#ifdef DELUXE\n"
|
|
//not lightstyled...
|
|
"vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_t3, lm).rgb-0.5)); //this norm should be the deluxemap info instead\n"
|
|
"#else\n"
|
|
"vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead\n"
|
|
"#endif\n"
|
|
"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"
|
|
"#endif\n"
|
|
|
|
//now we have our diffuse+specular terms, modulate by lightmap values.
|
|
"gl_FragColor.rgb *= lightmaps.rgb;\n"
|
|
|
|
//add on the fullbright
|
|
"#ifdef FULLBRIGHT\n"
|
|
"gl_FragColor.rgb += texture2D(s_t4, tc).rgb;\n"
|
|
"#endif\n"
|
|
|
|
//entity modifiers
|
|
"gl_FragColor = gl_FragColor * e_colourident;\n"
|
|
|
|
//and finally hide it all if we're fogged.
|
|
"#ifdef FOG\n"
|
|
"gl_FragColor = fog4(gl_FragColor);\n"
|
|
"#endif\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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"
|
|
"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"
|
|
"}\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"
|
|
"#ifndef ALPHA\n"
|
|
"uniform float cvar_r_wateralpha;\n"
|
|
"#define USEALPHA cvar_r_wateralpha\n"
|
|
"#else\n"
|
|
"#define USEALPHA float(ALPHA)\n"
|
|
"#endif\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, USEALPHA));\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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"
|
|
"sampler s_t0;\n"
|
|
"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"
|
|
"float3 ts = tex2D(s_t0, ntc).xyz;\n"
|
|
|
|
"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
|
|
#ifdef GLQUAKE
|
|
{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
|
|
{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 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
|
|
#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 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
|
|
|
|
"#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"
|
|
|
|
"#if 0 && defined(GL_ARB_texture_gather) && defined(PCF) \n"
|
|
"#extension GL_ARB_texture_gather : enable\n"
|
|
"#endif\n"
|
|
|
|
"#ifdef UPPERLOWER\n"
|
|
"#define UPPER\n"
|
|
"#define LOWER\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(CUBE) || defined(SPOT)\n"
|
|
"varying vec4 vtexprojcoord;\n"
|
|
"uniform mat4 l_cubematrix;\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(CUBE)\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; //diffuse\n"
|
|
|
|
"#if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING)\n"
|
|
"uniform sampler2D s_t1; //normalmap\n"
|
|
"#endif\n"
|
|
"#ifdef SPECULAR\n"
|
|
"uniform sampler2D s_t2; //specular\n"
|
|
"#endif\n"
|
|
"#ifdef CUBE\n"
|
|
"uniform samplerCube s_t3; //projected cubemap\n"
|
|
"#endif\n"
|
|
"#ifdef PCF\n"
|
|
"#ifdef CUBESHADOW\n"
|
|
"uniform samplerCubeShadow s_t4; //shadowmap\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"
|
|
"#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"
|
|
|
|
|
|
"uniform float l_lightradius;\n"
|
|
"uniform vec3 l_lightcolour;\n"
|
|
"uniform vec3 l_lightcolourscale;\n"
|
|
"#ifdef PCF\n"
|
|
"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"
|
|
"{\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/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(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
|
|
"vec3 dir = abs(vtexprojcoord.xyz);\n"
|
|
//assume z is the major axis (ie: forward from the light)
|
|
"vec3 t = vtexprojcoord.xyz;\n"
|
|
"float ma = dir.z;\n"
|
|
"vec3 axis = vec3(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 + vec3(0.0, 0.0, l_shadowmapproj.w)) / -t.z);\n"
|
|
"#endif\n"
|
|
"}\n"
|
|
|
|
"float ShadowmapFilter(void)\n"
|
|
"{\n"
|
|
"vec3 shadowcoord = ShadowmapCoord();\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)*l_shadowmapscale.xyx)).r\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"
|
|
"#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"
|
|
"#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"
|
|
"#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 CUBE\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"
|
|
// diff = ShadowmapCoord();
|
|
"#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 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"
|
|
"sampler s_t0;\n"
|
|
"sampler s_t1;\n"
|
|
"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"
|
|
"float3 diff = tex2D(s_t0, inp.tc);\n"
|
|
"return float4(diff * col, 1);\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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
|
|
#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 vec4 e_rendertexturescale;\n"
|
|
"uniform float cvar_r_waterwarp;\n"
|
|
"void main ()\n"
|
|
"{\n"
|
|
"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"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#ifdef GLQUAKE
|
|
{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
|
|
{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 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"
|
|
|
|
|
|
|
|
|
|
|
|
"#ifdef VERTEX_SHADER\n"
|
|
|
|
"#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"
|
|
|
|
"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"
|
|
|
|
"#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"
|
|
// lightvector.x = dot(lightminusvertex, v_svector.xyz);
|
|
// 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;
|
|
// eyevector.x = dot(eyeminusvertex, v_svector.xyz);
|
|
// 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"
|
|
"}\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"
|
|
|
|
"#ifdef PCF\n"
|
|
"uniform sampler2DShadow s_t5;\n"
|
|
"#include \"sys/pcf.h\"\n"
|
|
"#endif\n"
|
|
"#ifdef CUBE\n"
|
|
"uniform samplerCube s_t6;\n"
|
|
"#endif\n"
|
|
|
|
//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"
|
|
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"vec4 r;\n"
|
|
"vec4 m = texture2D(s_t4, lm);\n"
|
|
|
|
"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"
|
|
|
|
"#ifdef CUBE\n"
|
|
"r.rgb *= textureCube(s_t6, vtexprojcoord.xyz).rgb;\n"
|
|
"#endif\n"
|
|
|
|
"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"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|
|
#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"
|
|
"float3 vtexprojcoord: TEXCOORD2;\n"
|
|
"float3 vtexprojcoord: 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.vcol = inp.vcol;\n"
|
|
"return outp;\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
|
|
"#ifdef FRAGMENT_SHADER\n"
|
|
"Texture2D shaderTexture[7];\n"
|
|
"SamplerState SampleType[7];\n"
|
|
|
|
"float4 main (v2f inp) : SV_TARGET\n"
|
|
"{\n"
|
|
"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"
|
|
|
|
"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; //fade light by distance\n"
|
|
|
|
"#ifdef CUBE\n"
|
|
"result.rgb *= cubemap.rgb; //fade by cubemap\n"
|
|
"#endif\n"
|
|
|
|
"return result;\n"
|
|
"}\n"
|
|
"#endif\n"
|
|
},
|
|
#endif
|