This is Eukara's attempt to parse vmt files better.

This commit is contained in:
Shpoike 2021-05-03 03:12:59 +01:00
parent 804ff3f5b2
commit 93ee065acf
9 changed files with 805 additions and 15 deletions

View File

@ -7307,6 +7307,10 @@ typedef struct
char name[MAX_QPATH];
} tex[5];
char envmap[MAX_QPATH];
char envmapmask[MAX_QPATH];
char envfrombase;
char halflambert;
float alphatestref;
char *blendfunc;
qboolean alphatest;
@ -7372,8 +7376,11 @@ static char *VMT_ParseBlock(const char *fname, vmtstate_t *st, char *line)
;
else if (!Q_strcasecmp(key, "$basetexturetransform"))
;
else if (!Q_strcasecmp(key, "$bumpmap"))
;
else if (!Q_strcasecmp(key, "$bumpmap")) // same as normalmap ~eukara
{
Q_strncpyz(st->normalmap, value, sizeof(st->normalmap));
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
}
else if (!Q_strcasecmp(key, "$ssbump"))
;
else if (!Q_strcasecmp(key, "$ssbumpmathfix"))
@ -7412,6 +7419,8 @@ static char *VMT_ParseBlock(const char *fname, vmtstate_t *st, char *line)
st->blendfunc = "src_one one_minus_src_alpha\n";
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
}
else if (!Q_strcasecmp(key, "$halflambert"))
st->halflambert = 1;
else if (!Q_strcasecmp(key, "$color"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
else if (!Q_strcasecmp(key, "$vertexcolor"))
@ -7426,10 +7435,8 @@ static char *VMT_ParseBlock(const char *fname, vmtstate_t *st, char *line)
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
else if (!Q_strcasecmp(key, "$envmap"))
Q_strncpyz(st->envmap, value, sizeof(st->envmap));
else if (!Q_strcasecmp(key, "$envmaptint"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
else if (!Q_strcasecmp(key, "$envmapmask"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
Q_strncpyz(st->envmapmask, value, sizeof(st->envmapmask));
else if (!Q_strcasecmp(key, "$envmapcontrast"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
else if (!Q_strcasecmp(key, "$envmaptint"))
@ -7437,9 +7444,9 @@ static char *VMT_ParseBlock(const char *fname, vmtstate_t *st, char *line)
else if (!Q_strcasecmp(key, "$envmapsaturation"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
else if (!Q_strcasecmp(key, "$basealphaenvmapmask"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
st->envfrombase=1;
else if (!Q_strcasecmp(key, "$normalmapalphaenvmapmask"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
st->envfrombase=0;
else if (!Q_strcasecmp(key, "$crackmaterial"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
else if (!Q_strcasecmp(key, "$selfillum"))
@ -7473,6 +7480,8 @@ static char *VMT_ParseBlock(const char *fname, vmtstate_t *st, char *line)
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
//water/reflection stuff
else if (!Q_strcasecmp(key, "$refracttinttexture"))
Q_strncpyz(st->tex[0].name, value, sizeof(st->tex[0].name));
else if (!Q_strcasecmp(key, "$refracttexture"))
Con_DPrintf("%s: %s \"%s\"\n", fname, key, value);
else if (!Q_strcasecmp(key, "$refractamount"))
@ -7544,31 +7553,92 @@ static void Shader_GenerateFromVMT(parsestate_t *ps, vmtstate_t *st, const char
Q_strlcatfz(script, &offset, sizeof(script), "\n");
if (!Q_strcasecmp(st->type, "WorldVertexTransition"))
{ //attempt to do terrain blending
Q_strncpyz(st->type, "defaultwall#TWOWAY", sizeof(st->type));
Q_strncpyz(st->type, "vmt_transition#TWOWAY", sizeof(st->type));
Q_strlcatfz(script, &offset, sizeof(script), "\tprogram \"%s%s\"\n", st->type, progargs);
Q_strlcatfz(script, &offset, sizeof(script), "\tdiffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
Q_strlcatfz(script, &offset, sizeof(script), "\tuppermap \"%s%s.vtf\"\n", strcmp(st->tex[1].name, "materials/")?"materials/":"", st->tex[1].name);
}
else if (!Q_strcasecmp(st->type, "Decal"))
{
Q_strncpyz(st->type, "vmt_vertexlit", sizeof(st->type));
Q_strlcatfz(script, &offset, sizeof(script), "\tprogram \"%s%s\"\n", st->type, progargs);
Q_strlcatfz(script, &offset, sizeof(script), "\tdiffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
Q_strlcatfz(script, &offset, sizeof(script), "\tpolygonOffset 1\n");
}
else if (!Q_strcasecmp(st->type, "DecalModulate"))
{
Q_strncpyz(st->type, "vmt_vertexlit", sizeof(st->type));
Q_strlcatfz(script, &offset, sizeof(script), "\tprogram \"%s%s\"\n", st->type, progargs);
Q_strlcatfz(script, &offset, sizeof(script), "\tdiffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
Q_strlcatfz(script, &offset, sizeof(script), "\tpolygonOffset 1\n");
//Q_strncpyz(st->blendfunc, "dst_color one_minus_src_alpha", sizeof(st->blendfunc));
st->blendfunc = "dst_color one_minus_src_alpha\n";
}
else if (!Q_strcasecmp(st->type, "UnlitGeneric"))
{
Q_strncpyz(st->type, "vmt_unlit", sizeof(st->type));
Q_strlcatfz(script, &offset, sizeof(script), "\tprogram \"%s%s\"\n", st->type, progargs);
Q_strlcatfz(script, &offset, sizeof(script), "\tdiffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
}
else if (!Q_strcasecmp(st->type, "Water"))
{
Q_strlcatfz(script, &offset, sizeof(script),
"\t{\n"
"\tprogram \"altwater%s#FRESNEL=4\"\n"
"\t\tprogram \"vmt_water\"\n"
"\t\tmap $refraction\n"
"\t\tmap $null\n"
"\t\tmap $null\n"//$ripplemap
"\t\tmap $null\n"//$refractiondepth
"\t\tmap $reflection\n"
"\t}\n", progargs);
Q_strlcatfz(script, &offset, sizeof(script), "\tdiffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
Q_strlcatfz(script, &offset, sizeof(script), "\tnormalmap \"%s%s.vtf\"\n", strcmp(st->normalmap, "materials/")?"materials/":"", st->normalmap);
}
else
else if (!Q_strcasecmp(st->type, "Refract"))
{
Q_strncpyz(st->type, "defaultwall", sizeof(st->type)); //FIXME
Q_strlcatfz(script, &offset, sizeof(script),
"\t{\n"
"\t\tprogram \"vmt_refract\"\n"
"\t\tmap $refraction\n"
"\t}\n", progargs);
Q_strlcatfz(script, &offset, sizeof(script), "\tdiffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
Q_strlcatfz(script, &offset, sizeof(script), "\tnormalmap \"%s%s.vtf\"\n", strcmp(st->normalmap, "materials/")?"materials/":"", st->normalmap);
}
else if (!Q_strcasecmp(st->type, "VertexlitGeneric"))
{
if (*st->envmap && st->envfrombase) {
if (st->halflambert)
Q_strncpyz(st->type, "vmt_vertexlit#ENVFROMBASE#HALFLAMBERT", sizeof(st->type));
else
Q_strncpyz(st->type, "vmt_vertexlit#ENVFROMBASE", sizeof(st->type));
} else {
if (st->halflambert)
Q_strncpyz(st->type, "vmt_vertexlit#HALFLAMBERT", sizeof(st->type));
else
Q_strncpyz(st->type, "vmt_vertexlit", sizeof(st->type));
}
Q_strlcatfz(script, &offset, sizeof(script), "\tprogram \"%s%s\"\n", st->type, progargs);
Q_strlcatfz(script, &offset, sizeof(script), "\tdiffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
if (*st->normalmap)
Q_strlcatfz(script, &offset, sizeof(script), "\tnormalmap \"%s%s.vtf\"\n", strcmp(st->normalmap, "materials/")?"materials/":"", st->normalmap);
}
else
{
/* reflectmask from diffuse map alpha */
if (*st->envmap && st->envfrombase)
Q_strncpyz(st->type, "vmt_lightmapped#ENVFROMBASE", sizeof(st->type));
else if (*st->envmap && *st->envmapmask) /* dedicated reflectmask */
Q_strncpyz(st->type, "vmt_lightmapped#ENVFROMMASK", sizeof(st->type));
else /* take from normalmap */
Q_strncpyz(st->type, "vmt_lightmapped", sizeof(st->type));
Q_strlcatfz(script, &offset, sizeof(script), "\tprogram \"%s%s\"\n", st->type, progargs);
Q_strlcatfz(script, &offset, sizeof(script), "\tdiffusemap \"%s%s.vtf\"\n", strcmp(st->tex[0].name, "materials/")?"materials/":"", st->tex[0].name);
if (*st->normalmap)
Q_strlcatfz(script, &offset, sizeof(script), "\tnormalmap \"%s%s.vtf\"\n", strcmp(st->normalmap, "materials/")?"materials/":"", st->normalmap);
}
if (*st->envmapmask)
Q_strlcatfz(script, &offset, sizeof(script), "\treflectmask \"%s%s.vtf\"\n", strcmp(st->envmapmask, "materials/")?"materials/":"", st->envmapmask);
if (*st->envmap)
Q_strlcatfz(script, &offset, sizeof(script), "\treflectcube \"%s%s.vtf\"\n", strcmp(st->envmap, "materials/")?"materials/":"", st->envmap);
if (st->alphatest)
@ -7579,6 +7649,7 @@ static void Shader_GenerateFromVMT(parsestate_t *ps, vmtstate_t *st, const char
Q_strlcatfz(script, &offset, sizeof(script), "\tnodepth\n");
if (st->blendfunc)
Q_strlcatfz(script, &offset, sizeof(script), "\tprogblendfunc %s\n", st->blendfunc);
Q_strlcatfz(script, &offset, sizeof(script), "}\n");
Shader_Reset(ps->s);

View File

@ -6,7 +6,7 @@ VKSDKPATH ?= ~/VulkanSDK/1.1.73.0/x86_64/bin/
all:
NAMES= fixedemu fixedemu_flat altwater bloom_blur bloom_filter bloom_final colourtint crepuscular_opaque crepuscular_rays crepuscular_sky depthonly default2d defaultadditivesprite defaultskin defaultsky defaultskybox defaultfill defaultsprite defaultwall defaultwarp defaultgammacb drawflat_wall lpp_depthnorm lpp_light lpp_wall postproc_fisheye postproc_panorama postproc_laea postproc_stereographic postproc_equirectangular fxaa underwaterwarp menutint terrain rtlight
NAMES= fixedemu fixedemu_flat altwater bloom_blur bloom_filter bloom_final colourtint crepuscular_opaque crepuscular_rays crepuscular_sky depthonly default2d defaultadditivesprite defaultskin defaultsky defaultskybox defaultfill defaultsprite defaultwall defaultwarp defaultgammacb drawflat_wall lpp_depthnorm lpp_light lpp_wall postproc_fisheye postproc_panorama postproc_laea postproc_stereographic postproc_equirectangular fxaa underwaterwarp menutint terrain rtlight vmt_lightmapped vmt_refract vmt_unlit vmt_vertexlit vmt_water vmt_transition
ALLNAMES+=$(foreach v,$(NAMES),glsl/$v.glsl)

View File

@ -44,6 +44,12 @@ char shaders[][64] =
"menutint",
"terrain",
"rtlight",
"vmt_lightmapped",
"vmt_refract",
"vmt_transition",
"vmt_unlit",
"vmt_vertexlit",
"vmt_water",
""
};

View File

@ -0,0 +1,166 @@
!!ver 110
!!permu FOG
!!permu BUMP
!!permu LIGHTSTYLED
!!permu REFLECTCUBEMASK
!!samps diffuse
!!samps lightmap
!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3
!!samps =BUMP normalmap
// envmaps only
!!samps =REFLECTCUBEMASK reflectmask reflectcube
!!permu FAKESHADOWS
!!cvardf r_glsl_pcf
!!samps =FAKESHADOWS shadowmap
#include "sys/defs.h"
varying vec2 tex_c;
varying vec2 lm0;
#ifdef LIGHTSTYLED
varying vec2 lm1, lm2, lm3;
#endif
#ifdef FAKESHADOWS
varying vec4 vtexprojcoord;
#endif
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
varying vec3 eyevector;
varying mat3 invsurface;
#endif
#ifdef VERTEX_SHADER
void lightmapped_init(void)
{
lm0 = v_lmcoord;
#ifdef LIGHTSTYLED
lm1 = v_lmcoord2;
lm2 = v_lmcoord3;
lm3 = v_lmcoord4;
#endif
}
void main ()
{
lightmapped_init();
tex_c = v_texcoord;
gl_Position = ftetransform();
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
invsurface = mat3(v_svector, v_tvector, v_normal);
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
#ifdef FAKESHADOWS
vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0));
#endif
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
#ifdef FAKESHADOWS
#include "sys/pcf.h"
#endif
#ifdef LIGHTSTYLED
#define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb
#define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb
#define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb
#define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb
#else
#define LIGHTMAP texture2D(s_lightmap, lm0).rgb
#endif
vec3 lightmap_fragment()
{
vec3 lightmaps;
#ifdef LIGHTSTYLED
lightmaps = LIGHTMAP0 * e_lmscale[0].rgb;
lightmaps += LIGHTMAP1 * e_lmscale[1].rgb;
lightmaps += LIGHTMAP2 * e_lmscale[2].rgb;
lightmaps += LIGHTMAP3 * e_lmscale[3].rgb;
#else
lightmaps = LIGHTMAP * e_lmscale.rgb;
#endif
/* the light we're getting is always too bright */
lightmaps *= 0.75;
/* clamp at 1.5 */
if (lightmaps.r > 1.5)
lightmaps.r = 1.5;
if (lightmaps.g > 1.5)
lightmaps.g = 1.5;
if (lightmaps.b > 1.5)
lightmaps.b = 1.5;
return lightmaps;
}
void main (void)
{
vec4 diffuse_f;
diffuse_f = texture2D(s_diffuse, tex_c);
#ifdef MASKLT
if (diffuse_f.a < float(MASK))
discard;
#endif
#ifdef FAKESHADOWS
diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord);
#endif
/* deluxemapping isn't working on Source BSP yet */
diffuse_f.rgb *= lightmap_fragment();
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
/* We currently only use the normal/bumpmap for cubemap warping. move this block out once we do proper radiosity normalmapping */
#ifdef BUMP
/* Source's normalmaps are in the DX format where the green channel is flipped */
vec4 normal_f = texture2D(s_normalmap, tex_c);
normal_f.g *= -1.0;
normal_f.rgb = normalize(normal_f.rgb - 0.5);
#else
vec4 normal_f = vec4(0.0,0.0,1.0,0.0);
#endif
#if defined(ENVFROMMASK)
/* We have a dedicated reflectmask */
#define refl texture2D(s_reflectmask, tex_c).r
#else
/* when ENVFROMBASE is set or a normal isn't present, we're getting the reflectivity info from the diffusemap's alpha channel */
#if defined(ENVFROMBASE) || !defined(BUMP)
#define refl 1.0 - diffuse_f.a
#else
#define refl normal_f.a * 0.5
#endif
#endif
vec3 cube_c = reflect(normalize(-eyevector), normal_f.rgb);
cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2];
cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz;
diffuse_f.rgb += (textureCube(s_reflectcube, cube_c).rgb * vec3(refl,refl,refl));
#endif
gl_FragColor = fog4(diffuse_f);
}
#endif

View File

@ -0,0 +1,47 @@
!!ver 110
!!samps diffuse
!!samps =BUMP normalmap
!!samps =REFLECTCUBEMASK reflectmask reflectcube
!!samps refraction=0
#include "sys/defs.h"
varying vec2 tex_c;
varying mat3 invsurface;
varying vec4 tf_c;
varying vec3 eyeminusvertex;
#ifdef VERTEX_SHADER
void main ()
{
invsurface[0] = v_svector;
invsurface[1] = v_tvector;
invsurface[2] = v_normal;
tf_c = ftetransform();
tex_c = v_texcoord;
gl_Position = tf_c;
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
void main ( void )
{
vec2 refl_c;
vec3 refr_f;
vec3 norm_f;
vec4 out_f = vec4( 1.0, 1.0, 1.0, 1.0 );
norm_f = ( texture2D( s_normalmap, tex_c).xyz);
norm_f.g *= -1.0f;
norm_f = normalize( norm_f );
// Reflection/View coordinates
refl_c = ( 1.0 + ( tf_c.xy / tf_c.w ) ) * 0.5;
refr_f = texture2D(s_refraction, refl_c + (norm_f.st) ).rgb;
out_f.rgb = refr_f * texture2D(s_diffuse, tex_c).rgb;
gl_FragColor = out_f;
}
#endif

View File

@ -0,0 +1,160 @@
!!ver 110
!!permu FOG
!!permu BUMP
!!permu LIGHTSTYLED
!!permu REFLECTCUBEMASK
!!permu UPPERLOWER
!!samps diffuse upper
!!samps lightmap
!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3
!!samps =BUMP normalmap
// envmaps only
!!samps =REFLECTCUBEMASK reflectmask reflectcube
!!permu FAKESHADOWS
!!cvardf r_glsl_pcf
!!samps =FAKESHADOWS shadowmap
#include "sys/defs.h"
varying vec2 tex_c;
varying vec4 vex_color;
varying vec2 lm0;
#ifdef LIGHTSTYLED
varying vec2 lm1, lm2, lm3;
#endif
#ifdef FAKESHADOWS
varying vec4 vtexprojcoord;
#endif
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
varying vec3 eyevector;
varying mat3 invsurface;
#endif
#ifdef VERTEX_SHADER
void lightmapped_init(void)
{
lm0 = v_lmcoord;
#ifdef LIGHTSTYLED
lm1 = v_lmcoord2;
lm2 = v_lmcoord3;
lm3 = v_lmcoord4;
#endif
}
void main ()
{
lightmapped_init();
tex_c = v_texcoord;
gl_Position = ftetransform();
vex_color = v_colour;
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
invsurface = mat3(v_svector, v_tvector, v_normal);
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
#ifdef FAKESHADOWS
vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0));
#endif
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
#ifdef FAKESHADOWS
#include "sys/pcf.h"
#endif
#ifdef LIGHTSTYLED
#define LIGHTMAP0 texture2D(s_lightmap0, lm0).rgb
#define LIGHTMAP1 texture2D(s_lightmap1, lm1).rgb
#define LIGHTMAP2 texture2D(s_lightmap2, lm2).rgb
#define LIGHTMAP3 texture2D(s_lightmap3, lm3).rgb
#else
#define LIGHTMAP texture2D(s_lightmap, lm0).rgb
#endif
vec3 lightmap_fragment()
{
vec3 lightmaps;
#ifdef LIGHTSTYLED
lightmaps = LIGHTMAP0 * e_lmscale[0].rgb;
lightmaps += LIGHTMAP1 * e_lmscale[1].rgb;
lightmaps += LIGHTMAP2 * e_lmscale[2].rgb;
lightmaps += LIGHTMAP3 * e_lmscale[3].rgb;
#else
lightmaps = LIGHTMAP * e_lmscale.rgb;
#endif
/* the light we're getting is always too bright */
lightmaps *= 0.75;
/* clamp at 1.5 */
if (lightmaps.r > 1.5)
lightmaps.r = 1.5;
if (lightmaps.g > 1.5)
lightmaps.g = 1.5;
if (lightmaps.b > 1.5)
lightmaps.b = 1.5;
return lightmaps;
}
void main (void)
{
vec4 diffuse_f;
diffuse_f.rgb = mix(texture2D(s_diffuse, tex_c).rgb, texture2D(s_upper, tex_c).rgb, vex_color.a);
diffuse_f.a = 1.0;
/* deluxemapping isn't working on Source BSP yet, FIXME */
diffuse_f.rgb *= lightmap_fragment();
#ifdef FAKESHADOWS
diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord);
#endif
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
/* We currently only use the normal/bumpmap for cubemap warping. move this block out once we do proper radiosity normalmapping */
#ifdef BUMP
/* Source's normalmaps are in the DX format where the green channel is flipped */
vec4 normal_f = texture2D(s_normalmap, tex_c);
normal_f.g *= -1.0;
normal_f.rgb = normalize(normal_f.rgb - 0.5);
#else
vec4 normal_f = vec4(0.0,0.0,1.0,0.0);
#endif
/* when ENVFROMBASE is set or a normal isn't present, we're getting the reflectivity info from the diffusemap's alpha channel */
#if defined(ENVFROMBASE) || !defined(BUMP)
/* since we're sampling from the diffuse = 1.0 fully visible, 0.0 = fully reflective */
#define refl 1.0 - diffuse_f.a
#else
#define refl normal_f.a * 0.5
#endif
vec3 cube_c = reflect(normalize(-eyevector), normal_f.rgb);
cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2];
cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz;
diffuse_f.rgb += (textureCube(s_reflectcube, cube_c).rgb * vec3(refl,refl,refl));
#endif
gl_FragColor = fog4(diffuse_f);
}
#endif

View File

@ -0,0 +1,30 @@
!!ver 110
!!permu FOG
!!samps diffuse
#include "sys/defs.h"
#include "sys/fog.h"
varying vec2 tex_c;
#ifdef VERTEX_SHADER
void main ()
{
tex_c = v_texcoord;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
void main ()
{
vec4 diffuse_f = texture2D( s_diffuse, tex_c );
#ifdef MASKLT
if (diffuse_f.a < float(MASK))
discard;
#endif
gl_FragColor = fog4( diffuse_f );
}
#endif

View File

@ -0,0 +1,132 @@
!!ver 110
!!permu FRAMEBLEND
!!permu BUMP
!!permu FOG
!!permu SKELETAL
!!samps diffuse fullbright normalmap
!!permu FAKESHADOWS
!!cvardf r_glsl_pcf
!!samps =FAKESHADOWS shadowmap
// envmaps only
!!samps =REFLECTCUBEMASK reflectmask reflectcube
!!cvardf r_skipDiffuse
#include "sys/defs.h"
varying vec2 tex_c;
varying vec3 norm;
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
varying vec3 eyevector;
varying mat3 invsurface;
#endif
#ifdef FAKESHADOWS
varying vec4 vtexprojcoord;
#endif
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
void main (void)
{
vec3 n, s, t, w;
tex_c = v_texcoord;
gl_Position = skeletaltransform_wnst(w,n,s,t);
norm = n;
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
invsurface = mat3(v_svector, v_tvector, v_normal);
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
#ifdef FAKESHADOWS
vtexprojcoord = (l_cubematrix*vec4(v_position.xyz, 1.0));
#endif
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
#include "sys/pcf.h"
float lambert(vec3 normal, vec3 dir)
{
return max(dot(normal, dir), 0.0);
}
float halflambert(vec3 normal, vec3 dir)
{
return (lambert(normal, dir) * 0.5) + 0.5;
}
void main (void)
{
vec4 diffuse_f = texture2D(s_diffuse, tex_c);
vec3 light;
#ifdef MASKLT
if (diffuse_f.a < float(MASK))
discard;
#endif
/* Normal/Bumpmap Shenanigans */
#ifdef BUMP
/* Source's normalmaps are in the DX format where the green channel is flipped */
vec3 normal_f = texture2D(s_normalmap, tex_c).rgb;
normal_f.g *= -1.0;
normal_f = normalize(normal_f.rgb - 0.5);
#else
vec3 normal_f = vec3(0.0,0.0,1.0);
#endif
/* CUBEMAPS ONLY */
#ifdef REFLECTCUBEMASK
/* when ENVFROMBASE is set or a normal isn't present, we're getting the reflectivity info from the diffusemap's alpha channel */
#if defined(ENVFROMBASE) || !defined(BUMP)
#define refl 1.0 - diffuse_f.a
#else
#define refl texture2D(s_normalmap, tex_c).a
#endif
vec3 cube_c = reflect(normalize(-eyevector), normal_f.rgb);
cube_c = cube_c.x * invsurface[0] + cube_c.y * invsurface[1] + cube_c.z * invsurface[2];
cube_c = (m_model * vec4(cube_c.xyz, 0.0)).xyz;
diffuse_f.rgb += (textureCube(s_reflectcube, cube_c).rgb * vec3(refl,refl,refl));
#endif
#ifdef HALFLAMBERT
light = e_light_ambient + (e_light_mul * halflambert(norm, e_light_dir));
#else
light = e_light_ambient + (e_light_mul * lambert(norm, e_light_dir));
#endif
/* the light we're getting is always too bright */
light *= 0.75;
/* clamp at 1.5 */
if (light.r > 1.5)
light.r = 1.5;
if (light.g > 1.5)
light.g = 1.5;
if (light.b > 1.5)
light.b = 1.5;
diffuse_f.rgb *= light;
#ifdef FAKESHADOWS
diffuse_f.rgb *= ShadowmapFilter(s_shadowmap, vtexprojcoord);
#endif
gl_FragColor = fog4(diffuse_f * e_colourident) * e_lmscale;
}
#endif

View File

@ -0,0 +1,178 @@
!!cvardf r_glsl_turbscale_reflect=1 //simpler scaler
!!cvardf r_glsl_turbscale_refract=1 //simpler scaler
!!samps diffuse normalmap
!!samps refract=0 //always present
!!samps reflect=1
!!permu FOG
#include "sys/defs.h"
//modifier: REFLECT (s_t2 is a reflection instead of diffusemap)
//modifier: STRENGTH_REFL (distortion strength - 0.1 = fairly gentle, 0.2 = big waves)
//modifier: STRENGTH_REFL (distortion strength - 0.1 = fairly gentle, 0.2 = big waves)
//modifier: FRESNEL_EXP (5=water)
//modifier: TXSCALE (wave size - 0.2)
//modifier: RIPPLEMAP (s_t3 contains a ripplemap
//modifier: TINT_REFR (some colour value)
//modifier: TINT_REFL (some colour value)
//modifier: ALPHA (mix in the normal water texture over the top)
//modifier: USEMODS (use single-texture scrolling via tcmods - note, also forces the engine to actually use tcmod etc)
//a few notes on DP compat:
//'dpwater' makes numerous assumptions about DP internals
//by default there is a single pass that uses the pass's normal tcmods
//the fresnel has a user-supplied min+max rather than an exponent
//both parts are tinted individually
//if alpha is enabled, the regular water texture is blended over the top, again using the same crappy tcmods...
//legacy crap
#ifndef FRESNEL
#define FRESNEL 5.0
#endif
#ifndef TINT
#define TINT 0.7,0.8,0.7
#endif
#ifndef STRENGTH
#define STRENGTH 0.1
#endif
#ifndef TXSCALE
#define TXSCALE 1
#endif
//current values (referring to legacy defaults where needed)
#ifndef FRESNEL_EXP
#define FRESNEL_EXP 4.0
#endif
#ifndef FRESNEL_MIN
#define FRESNEL_MIN 0.0
#endif
#ifndef FRESNEL_RANGE
#define FRESNEL_RANGE 1.0
#endif
#ifndef STRENGTH_REFL
#define STRENGTH_REFL STRENGTH
#endif
#ifndef STRENGTH_REFR
#define STRENGTH_REFR STRENGTH
#endif
#ifndef TXSCALE1
#define TXSCALE1 TXSCALE
#endif
#ifndef TXSCALE2
#define TXSCALE2 TXSCALE
#endif
#ifndef TINT_REFR
#define TINT_REFR TINT
#endif
#ifndef TINT_REFL
#define TINT_REFL 1.0,1.0,1.0
#endif
#ifndef FOGTINT
#define FOGTINT 0.2,0.3,0.2
#endif
varying vec2 tc;
varying vec4 tf;
varying vec3 norm;
varying vec3 eye;
#ifdef VERTEX_SHADER
void main (void)
{
tc = v_texcoord.st;
tf = ftetransform();
norm = v_normal;
eye = e_eyepos - v_position.xyz;
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
void main (void)
{
vec2 stc; //screen tex coords
vec2 ntc; //normalmap/diffuse tex coords
vec3 n, refr, refl;
float fres;
float depth;
stc = (1.0 + (tf.xy / tf.w)) * 0.5;
//hack the texture coords slightly so that there are less obvious gaps
stc.t -= 1.5*norm.z/1080.0;
#if 0//def USEMODS
ntc = tc;
n = texture2D(s_normalmap, ntc).xyz - 0.5;
#else
//apply q1-style warp, just for kicks
ntc.s = tc.s + sin(tc.t+e_time)*0.125;
ntc.t = tc.t + sin(tc.s+e_time)*0.125;
//generate the two wave patterns from the normalmap
n = (texture2D(s_normalmap, vec2(TXSCALE1)*tc + vec2(e_time*0.1, 0.0)).xyz);
n += (texture2D(s_normalmap, vec2(TXSCALE2)*tc - vec2(0, e_time*0.097)).xyz);
n -= 1.0 - 4.0/256.0;
#endif
#ifdef RIPPLEMAP
n += texture2D(s_ripplemap, stc).rgb*3.0;
#endif
n = normalize(n);
//the fresnel term decides how transparent the water should be
fres = pow(1.0-abs(dot(n, normalize(eye))), float(FRESNEL_EXP)) * float(FRESNEL_RANGE) + float(FRESNEL_MIN);
#ifdef DEPTH
float far = #include "cvar/gl_maxdist";
float near = #include "cvar/gl_mindist";
//get depth value at the surface
float sdepth = gl_FragCoord.z;
sdepth = (2.0*near) / (far + near - sdepth * (far - near));
sdepth = mix(near, far, sdepth);
//get depth value at the ground beyond the surface.
float gdepth = texture2D(s_refractdepth, stc).x;
gdepth = (2.0*near) / (far + near - gdepth * (far - near));
if (gdepth >= 0.5)
{
gdepth = sdepth;
depth = 0.0;
}
else
{
gdepth = mix(near, far, gdepth);
depth = gdepth - sdepth;
}
//reduce the normals in shallow water (near walls, reduces the pain of linear sampling)
if (depth < 100.0)
n *= depth/100.0;
#else
depth = 1.0;
#endif
//refraction image (and water fog, if possible)
refr = texture2D(s_refract, stc + n.st*float(STRENGTH_REFR)*float(r_glsl_turbscale_refract)).rgb * vec3(TINT_REFR);
#ifdef DEPTH
refr = mix(refr, vec3(FOGTINT), min(depth/4096.0, 1.0));
#endif
//reflection/diffuse
refl = texture2D(s_reflect, stc - n.st*float(STRENGTH_REFL)*float(r_glsl_turbscale_reflect)).rgb * vec3(TINT_REFL);
//interplate by fresnel
refr = mix(refr, refl, fres);
#ifdef ALPHA
vec4 ts = texture2D(s_diffuse, ntc);
vec4 surf = fog4blend(vec4(ts.rgb, float(ALPHA)*ts.a));
refr = mix(refr, surf.rgb, surf.a);
#else
refr = fog3(refr);
#endif
//done
gl_FragColor = vec4(refr, 1.0);
}
#endif