update to tesseract rev 2425

This commit is contained in:
Daniel Kolesa 2020-09-11 02:54:14 +02:00
parent fa79385b82
commit 2be4ed0739
54 changed files with 1653 additions and 1035 deletions

16
README
View file

@ -18,6 +18,7 @@ It provides a bunch of new rendering features such as:
* HDR rendering with tonemapping and bloom
* real-time diffuse global illumination for sunlight (radiance hints)
* volumetric lighting
* transparent shadows
* screen-space ambient occlusion
* screen-space reflections and refractions for water and glass (use as many water planes as you want now!)
* screen-space refractive alpha cubes
@ -81,3 +82,18 @@ Set attribute 5 of a light entity to 4.
The intensity of the volumetric lighting medium can be controlled by volscale and the color can by controlled by volcolour.
To make transparent shadows:
This is toggled on a per-map basis by setting "alphashadow" to 0 (off), 1 (sunlight), or 2 (sunlight and point lights).
If set to 1, you must set attribute 5 of a light entity to 16 to enable transparent shadows for that point light.
If set to 2, all point lights automatically cast transparent shadows.
If a light is volumetric, regardless of "alphashadow" setting, the light entity's attribute 5 must be set to 20 (4 | 16) for it
to cast a volumetric transparent shadow.
To make a cube cast transparent shadows, use the "alpha" material. The texalpha/valpha commands can be then used to control the alpha
of the cube, which then is used to determine the intensity of the transparent shadow. This intensity can be further scaled by setting
the global map variable "alphashadowscale" (0..2).
If a texture slot has an alpha texture (slot "a"), this can be used to mask the alpha of the cube. This masked alpha will then be used
to further mask the transparent shadow.

View file

@ -1,5 +1,9 @@
# OctaCore
This is the upcoming engine part of the newly revived OctaForge project. For
now there is nothing much to see here, besides a plain Tesseract codebase
import. This is going to change in near future; stay tuned.
**Last Tesseract SVN import:** 2425
This is the work in progress engine part of the newly revived OctaForge
project.
Nothing much to see here yet, besides a stripped down, partially refactored
Tesseract codebase.

View file

@ -16,17 +16,15 @@ setdefaultenv = [
if $emptymap [setdefaultenv]
materialreset
loop+ i 1 4 [
texture [glass@i] "mat_glass/nieb/scratch2.png" // Glass Normals
texture [water@i] "mat_water/nieb/water.png" // Water (Unused)
texture 1 "mat_water/appleflap/water_normal.png" // Water Normals
texture 1 "mat_water/nieb/waterfall.png" // Waterfall Diffuse
texture 1 "mat_water/nieb/waterfall_normal.png" // Waterfall Normals
texture [lava@i] "mat_lava/nieb/lava.png" // Lava Diffuse
texture 1 "mat_lava/nieb/lava_normal.png" // Lava Normals
texture 1 "mat_lava/nieb/lava.png" // Lavafall Diffuse
texture 1 "mat_lava/nieb/lava_normal.png" // Lavafall Normals
]
texture glass "mat_glass/nieb/scratch2.png" // Glass Normals
texture water "mat_water/nieb/water.png" // Water (Unused)
texture 1 "mat_water/appleflap/water_normal.png" // Water Normals
texture 1 "mat_water/nieb/waterfall.png" // Waterfall Diffuse
texture 1 "mat_water/nieb/waterfall_normal.png" // Waterfall Normals
texture lava "mat_lava/nieb/lava.png" // Lava Diffuse
texture 1 "mat_lava/nieb/lava_normal.png" // Lava Normals
texture 1 "mat_lava/nieb/lava.png" // Lavafall Diffuse
texture 1 "mat_lava/nieb/lava_normal.png" // Lavafall Normals
decalreset

View file

@ -10,6 +10,7 @@ exec "config/glsl/gi.cfg"
exec "config/glsl/particle.cfg"
exec "config/glsl/stain.cfg"
exec "config/glsl/material.cfg"
exec "config/glsl/smfilter.cfg"
exec "config/glsl/deferred.cfg"
exec "config/glsl/tonemap.cfg"
exec "config/glsl/volumetric.cfg"

View file

@ -55,7 +55,9 @@ lazyshader 0 msaaedgedetect [
// deferredlighttype:
// p -> point-light shadow (default cubemap)
// P -> point-light color shadow
// c -> CSM
// C -> color CSM
// a -> AO
// A -> AO sun
// r -> radiance hints
@ -64,6 +66,7 @@ lazyshader 0 msaaedgedetect [
// E -> 5x5 weighted bilinear filter
// F -> 3x3 weighted bilinear filter
// f -> 4x rotated grid filter
// N -> no filtering
// m -> minimap
// M -> multisampled
// O -> sample 1
@ -116,8 +119,10 @@ deferredlightvariantshader = [
numlights = (+ $arg6 0)
baselight = (< (mod $arg2 4) 2)
spotlight = (>= (mod $arg2 8) 4)
transparent = (<= 8 $arg2 16)
avatar = (<= 17 $arg2 31)
transparent = (<= 8 $arg2 15)
avatar = (<= 24 $arg2 31)
local colorshadow
colorshadow = (|| (? (<= 16 $arg2 23) 2) [&& (dlopt "C") [! $transparent] [! $avatar]])
variantshader 0 $arg1 $arg2 (? (< $arg2 0) [
attribute vec4 vvertex;
uniform mat4 lightmatrix;
@ -173,6 +178,22 @@ deferredlightvariantshader = [
uniform sampler3D tex6, tex7, tex8, tex9;
]])
]])
@(? $colorshadow [
uniform sampler2DRect tex10;
#define sunshadowtype vec3
#define filtersunshadow(tc) (filtershadow(tc) * filtercolorshadow(tex10, tc))
] [
#define sunshadowtype float
#define filtersunshadow filtershadow
])
@(? (> $colorshadow 1) [
uniform sampler2DRect tex11;
#define lightshadowtype vec3
#define filterlightshadow(tc) (filtershadow(tc) * filtercolorshadow(tex11, tc))
] [
#define lightshadowtype float
#define filterlightshadow filtershadow
])
uniform vec3 camera;
uniform mat4 worldmatrix;
uniform vec4 fogdir;
@ -207,104 +228,19 @@ deferredlightvariantshader = [
])
@(if (|| (dlopt "p") [dlopt "c"]) [
cond [dlopt "G"] [result [
@(? (> $usetexgather 1) [
#define shadowgather(center, xoff, yoff) textureGatherOffset(tex4, center, shadowtc.z, ivec2(xoff, yoff))
] [
#define shadowgather(center, xoff, yoff) step(shadowtc.z, textureGatherOffset(tex4, center, ivec2(xoff, yoff)))
])
float filtershadow(vec3 shadowtc)
{
vec2 offset = fract(shadowtc.xy - 0.5), center = (shadowtc.xy - offset)*shadowatlasscale;
vec4 group1 = shadowgather(center, -2, -2);
vec4 group2 = shadowgather(center, 0, -2);
vec4 group3 = shadowgather(center, 2, -2);
vec4 group4 = shadowgather(center, -2, 0);
vec4 group5 = shadowgather(center, 0, 0);
vec4 group6 = shadowgather(center, 2, 0);
vec4 group7 = shadowgather(center, -2, 2);
vec4 group8 = shadowgather(center, 0, 2);
vec4 group9 = shadowgather(center, 2, 2);
vec4 locols = vec4(group1.ab, group3.ab);
vec4 hicols = vec4(group7.rg, group9.rg);
locols.yz += group2.ab;
hicols.yz += group8.rg;
vec4 midcols = vec4(group1.rg, group3.rg) + vec4(group7.ab, group9.ab) +
vec4(group4.rg, group6.rg) + vec4(group4.ab, group6.ab) +
mix(locols, hicols, offset.y);
vec4 cols = group5 + vec4(group2.rg, group8.ab);
cols.xyz += mix(midcols.xyz, midcols.yzw, offset.x);
return dot(cols, vec4(1.0/25.0));
}
]] [dlopt "g"] [result [
@(? (> $usetexgather 1) [
#define shadowgather(center, xoff, yoff) textureGatherOffset(tex4, center, shadowtc.z, ivec2(xoff, yoff))
] [
#define shadowgather(center, xoff, yoff) step(shadowtc.z, textureGatherOffset(tex4, center, ivec2(xoff, yoff)))
])
float filtershadow(vec3 shadowtc)
{
vec2 offset = fract(shadowtc.xy - 0.5), center = (shadowtc.xy - offset)*shadowatlasscale;
vec4 group1 = shadowgather(center, -1, -1);
vec4 group2 = shadowgather(center, 1, -1);
vec4 group3 = shadowgather(center, -1, 1);
vec4 group4 = shadowgather(center, 1, 1);
vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) + mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);
return dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));
}
]] [dlopt "E"] [result [
#define shadowval(xy, xoff, yoff) float(shadow2DRect(tex4, vec3(xy + vec2(xoff, yoff), shadowtc.z)))
float filtershadow(vec3 shadowtc)
{
vec2 offset = fract(shadowtc.xy - 0.5);
vec4 center = vec4(shadowtc.xy - offset + 0.5, shadowtc.xy - offset*0.5);
vec4 size = vec4(offset + 1.0, 2.0 - offset);
return (1.0/25.0)*dot(size.zxzx*size.wwyy,
vec4(shadowval(center.zw, -1.5, -1.5),
shadowval(center.zw, 2.0, -1.5),
shadowval(center.zw, -1.5, 2.0),
shadowval(center.zw, 2.0, 2.0))) +
(2.0/25.0)*dot(size,
vec4(shadowval(center.zy, 2.0, 0.0),
shadowval(center.xw, 0.0, 2.0),
shadowval(center.zy, -1.5, 0.0),
shadowval(center.xw, 0.0, -1.5))) +
(4.0/25.0)*shadowval(center.xy, 0.0, 0.0);
}
]] [dlopt "F"] [result [
#define shadowval(center, xoff, yoff) float(shadow2DRect(tex4, center + vec3(xoff, yoff, 0.0)))
float filtershadow(vec3 shadowtc)
{
vec2 offset = fract(shadowtc.xy - 0.5);
vec3 center = shadowtc;
//center.xy -= offset;
//vec4 size = vec4(offset + 1.0, 2.0 - offset), weight = vec4(2.0 - 1.0 / size.xy, 1.0 / size.zw - 1.0);
//return (1.0/9.0)*dot(size.zxzx*size.wwyy,
// vec4(shadowval(center, weight.zw),
// shadowval(center, weight.xw),
// shadowval(center, weight.zy),
// shadowval(center, weight.xy)));
center.xy -= offset*0.5;
vec4 size = vec4(offset + 1.0, 2.0 - offset);
return (1.0/9.0)*dot(size.zxzx*size.wwyy,
vec4(shadowval(center, -0.5, -0.5),
shadowval(center, 1.0, -0.5),
shadowval(center, -0.5, 1.0),
shadowval(center, 1.0, 1.0)));
}
]] [dlopt "f"] [result [
#define shadowval(center, xoff, yoff) float(shadow2DRect(tex4, center + vec3(xoff, yoff, 0.0)))
float filtershadow(vec3 shadowtc)
{
return dot(vec4(0.25),
vec4(shadowval(shadowtc, -0.4, 1.0),
shadowval(shadowtc, -1.0, -0.4),
shadowval(shadowtc, 0.4, -1.0),
shadowval(shadowtc, 1.0, 0.4)));
}
]] [result [
#define filtershadow(shadowtc) float(shadow2DRect(tex4, shadowtc))
]]
cond [dlopt "G"] [
smfilterg5 $colorshadow
] [dlopt "g"] [
smfilterg3 $colorshadow
] [dlopt "E"] [
smfilterb5 $colorshadow
] [dlopt "F"] [
smfilterb3 $colorshadow
] [dlopt "f"] [
smfilterrg $colorshadow
] [
smfilternone $colorshadow
]
])
@(if (dlopt "c") [result [
@ -495,7 +431,7 @@ deferredlightvariantshader = [
{
@(if (= (+ (? (dlopt "p") $numlights) (dlopt "c")) 1) [unpackdistbias])
vec3 csmtc = getcsmtc(pos.xyz, distbias);
float sunoccluded = filtershadow(csmtc);
sunshadowtype sunoccluded = filtersunshadow(csmtc);
@(if (dlopt "m") [result [
light += diffuse.rgb*sunfacing * sunlightcolor * sunoccluded;
]] [result [
@ -555,14 +491,16 @@ deferredlightvariantshader = [
@(if $spotlight [
if (dlopt "p") [result [
vec3 spot@[j]tc = getspottc(light@[j]dir, spot@[j]dist, spotparams[@@j], shadowparams[@@j], shadowoffset[@@j], distbias * lightpos[@@j].w);
light@[j]atten *= spot@[j]atten * filtershadow(spot@[j]tc);
lightshadowtype light@[j]shadow = light@[j]atten * spot@[j]atten * filterlightshadow(spot@[j]tc);
]] [result [
light@[j]atten *= spot@[j]atten;
float light@[j]shadow = light@[j]atten * spot@[j]atten;
]]
] [
if (dlopt "p") [result [
vec3 shadow@[j]tc = getshadowtc(light@[j]dir, shadowparams[@@j], shadowoffset[@@j], distbias * lightpos[@@j].w);
light@[j]atten *= filtershadow(shadow@[j]tc);
lightshadowtype light@[j]shadow = light@[j]atten * filterlightshadow(shadow@[j]tc);
]] [result [
#define light@[j]shadow light@[j]atten
]]
])
@(if (= (+ $numlights $baselight) 1) [result [
@ -574,14 +512,14 @@ deferredlightvariantshader = [
]])
light@[j]facing *= light@[j]invdist;
@(if (dlopt "m") [result [
light += diffuse.rgb*light@[j]facing * lightcolor[@@j].rgb * light@[j]atten;
light += diffuse.rgb*light@[j]facing * lightcolor[@@j].rgb * light@[j]shadow;
]] [result [
@(if (= (+ $numlights (dlopt "c")) 1) [unpackspec])
float light@[j]spec = pow(clamp(light@[j]facing*facing - light@[j]invdist*dot(camdir, light@[j]dir), 0.0, 1.0), gloss) * specscale;
@(if (dlopt "z") [result [
light@[j]spec *= lightcolor[@@j].a;
]])
light += (diffuse.rgb*light@[j]facing + light@[j]spec) * lightcolor[@@j].rgb * light@[j]atten;
light += (diffuse.rgb*light@[j]facing + light@[j]spec) * lightcolor[@@j].rgb * light@[j]shadow;
@(? (= (+ $numlights $baselight) 1) [
float foglerp = clamp(exp2(fogcoord*fogdensity.x)*fogdensity.y, 0.0, 1.0);
light *= foglerp;
@ -629,12 +567,14 @@ deferredlightshader = [
maxvariants = $basevariants
if (dlopt "t") [maxvariants = (+ $maxvariants $basevariants 1)]
if (dlopt "d") [maxvariants = (+ $maxvariants $basevariants 1)]
deferredlightvariantshader $shadername -1 (concatword $arg1 $arg3) $arg4 $arg5 0 $maxvariants // base shader, no points lights, sunlight
if (dlopt "P") [maxvariants = (+ $maxvariants (* (max $arg6 1) (? (dlopt "s") 2 1)))]
deferredlightvariantshader $shadername -1 $arg1 $arg4 $arg5 0 $maxvariants // null base shader
deferredlightvariantshader $shadername 0 (concatword $arg1 $arg3) $arg4 $arg5 0 $maxvariants // row 0, base shader, sunlight
if (dlopt "t") [
deferredlightvariantshader $shadername 16 (concatword $arg1 $arg3) $arg4 $arg5 0 $maxvariants // row 16, trasparency, base shader, no points lights, sunlight
deferredlightvariantshader $shadername 8 (concatword $arg1 $arg3) $arg4 $arg5 0 $maxvariants // row 8, transparency, base shader, sunlight
]
if (dlopt "d") [
deferredlightvariantshader $shadername 17 (concatword $arg1 $arg3) $arg4 $arg5 0 $maxvariants // row 17, avatar, base shader, no points lights, sunlight
deferredlightvariantshader $shadername 24 (concatword $arg1 $arg3) $arg4 $arg5 0 $maxvariants // row 24, avatar, base shader, sunlight
]
loop+ i 1 (max $arg6 1) [
if (dlopt "b") [
@ -667,6 +607,18 @@ deferredlightshader = [
deferredlightvariantshader $shadername 15 (concatword $arg1 $arg2) $arg4 $arg5 $i $maxvariants // row 15, transparent, shadowed spot lights
]
]
if (dlopt "P") [
if (dlopt "b") [
deferredlightvariantshader $shadername 17 (concatword $arg1 $arg2 $arg3) $arg4 $arg5 $i $maxvariants // row 17, color shadow, shadowed point lights, sunlight
]
deferredlightvariantshader $shadername 19 (concatword $arg1 $arg2) $arg4 $arg5 $i $maxvariants // row 19, color shadow, shadowed point lights
if (dlopt "s") [
if (dlopt "b") [
deferredlightvariantshader $shadername 21 (concatword $arg1 $arg2 $arg3) $arg4 $arg5 $i $maxvariants // row 21, color shadow, shadowed spot lights, sunlight
]
deferredlightvariantshader $shadername 23 (concatword $arg1 $arg2) $arg4 $arg5 $i $maxvariants // row 23, color shadow, shadowed spot lights
]
]
if (dlopt "d") [
if (dlopt "b") [
deferredlightvariantshader $shadername 24 (concatword $arg1 $arg3) $arg4 $arg5 $i $maxvariants // row 24, avatar, point lights, sunlight

View file

@ -15,16 +15,22 @@ grassvariantshader = [
variantshader 0 $arg1 (? (grassopt "b") 0 -1) [
attribute vec4 vvertex, vcolor;
attribute vec2 vtexcoord0;
attribute vec4 vtangent;
uniform mat4 camprojmatrix;
uniform vec3 camera;
uniform vec3 grassmargin;
@(ginterpvert)
varying vec2 texcoord0;
varying vec4 colorscale;
varying vec2 bounds;
@(? (grassopt "b") [uniform vec4 blendmapparams; varying vec2 texcoord1;])
void main(void)
{
gl_Position = camprojmatrix * vvertex;
colorscale = vcolor;
texcoord0 = vtexcoord0;
texcoord0 = vtexcoord0;
vec2 camdir = (camera.xy - vvertex.xy) * grassmargin.y;
bounds = vec2(dot(camdir, vtangent.xy), dot(camdir, vtangent.zw)) + grassmargin.z;
@(? (grassopt "b") [
texcoord1 = (vvertex.xy - blendmapparams.xy)*blendmapparams.zw;
])
@ -36,14 +42,18 @@ grassvariantshader = [
@(ginterpfrag)
varying vec2 texcoord0;
varying vec4 colorscale;
varying vec2 bounds;
@(? (grassopt "b") [uniform sampler2D tex1; varying vec2 texcoord1;])
void main(void)
{
vec4 color = texture2D(tex0, texcoord0) * colorscale;
color.a *= clamp(min(bounds.x, bounds.y), 0.0, 1.0);
@(? (grassopt "b") [
color.a *= texture2D(tex1, texcoord1).r;
])
if(color.a <= grasstest)
vec2 coords = fract((gl_FragCoord.xy - 0.5)*0.5);
float dither = coords.x + 1.5*coords.y - 4.0*coords.x*coords.y + 0.25;
if(color.a <= grasstest * dither)
discard;
gcolor = vec4(color.rgb, 0.0);
@(gnormpack [vec3(0.5, 0.5, 1.0)])

View file

@ -51,10 +51,11 @@ lazyshader 0 "waterminimap" [
watershader = [
lazyshader 0 $arg1 [
attribute vec4 vvertex;
attribute vec2 vtexcoord0;
uniform mat4 camprojmatrix;
uniform vec3 camera;
varying vec2 texcoord0, texcoord1;
uniform vec2 watertexgen;
uniform float millis;
varying vec2 texcoord0, texcoord1, texcoord2, texcoord3;
varying vec3 surface;
@(? (>= (strstr $arg1 "reflect") 0) [
uniform mat4 raymatrix;
@ -68,16 +69,20 @@ watershader = [
@(? (>= (strstr $arg1 "reflect") 0) [
esurface = (raymatrix * vvertex).xyz;
])
texcoord0 = vtexcoord0 * 0.18;
texcoord1 = vtexcoord0 * 0.08;
vec2 tc = vvertex.xy * watertexgen;
texcoord0 = tc * 0.18 + millis*vec2( 0.25, 0.75)*0.1250;
texcoord1 = tc * 0.18 + millis*vec2(-0.75, -0.25)*0.1450;
texcoord2 = tc * 0.08 + millis*vec2(-0.50, 0.50)*0.0805;
texcoord3 = tc * 0.08 + millis*vec2( 0.25, -0.75)*0.0825;
@(gdepthpackvert 1)
}
] [
@(gfetchdefs [tex7 tex8 tex9])
uniform float millis;
uniform vec3 camera;
uniform mat4 linearworldmatrix;
varying vec2 texcoord0, texcoord1;
varying vec2 texcoord0, texcoord1, texcoord2, texcoord3;
varying vec3 surface;
uniform sampler2D tex0, tex1;
uniform vec4 viewsize;
@ -102,10 +107,10 @@ watershader = [
void main(void)
{
vec3 camdir = camera - surface, camvec = normalize(camdir);
vec3 bump = texture2D(tex1, texcoord0 + millis*vec2( 0.25, 0.75)*0.1250).rgb;
vec3 bump2 = texture2D(tex1, texcoord0 + millis*vec2(-0.75, -0.25)*0.1450).rgb;
vec3 bump3 = texture2D(tex1, texcoord1 + millis*vec2(-0.50, 0.50)*0.0805).rgb;
vec3 bump4 = texture2D(tex1, texcoord1 + millis*vec2( 0.25, -0.75)*0.0825).rgb;
vec3 bump = texture2D(tex1, texcoord0).rgb;
vec3 bump2 = texture2D(tex1, texcoord1).rgb;
vec3 bump3 = texture2D(tex1, texcoord2).rgb;
vec3 bump4 = texture2D(tex1, texcoord3).rgb;
bump = normalize(bump + bump2 + bump3 + bump4 - 2.0);
vec2 rtc = bump.xy * waterrefract.w;
@ -248,18 +253,19 @@ waterfogshader waterfog
lazyshader 0 "lava" [
attribute vec4 vvertex;
attribute vec3 vnormal;
attribute vec2 vtexcoord0;
uniform mat4 camprojmatrix;
varying mat3 world;
uniform vec4 lavatexgen;
varying vec2 texcoord0;
@(ginterpvert)
void main(void)
{
gl_Position = camprojmatrix * vvertex;
texcoord0 = vtexcoord0;
vec3 tangent = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), abs(vnormal.x));
vec3 bitangent = mix(vec3(0.0, 0.0, -1.0), vec3(0.0, 1.0, 0.0), abs(vnormal.z));
world = mat3(tangent, bitangent, vnormal);
vec2 tc = vec2(dot(vvertex.xy, tangent.xy), dot(vvertex.yz, bitangent.yz));
texcoord0 = (tc + lavatexgen.zw) * lavatexgen.xy;
@(gdepthpackvert)
}
] [
@ -285,21 +291,22 @@ lazyshader 0 "lava" [
lazyshader 0 "waterfallenv" [
attribute vec4 vvertex;
attribute vec3 vnormal;
attribute vec2 vtexcoord0;
uniform mat4 camprojmatrix;
uniform vec4 camera;
varying vec3 camdir;
varying mat3 world;
uniform vec4 waterfalltexgen;
varying vec2 texcoord0;
@(ginterpvert 1)
void main(void)
{
gl_Position = camprojmatrix * vvertex;
texcoord0 = vtexcoord0;
camdir = camera.xyz - vvertex.xyz;
vec3 tangent = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), abs(vnormal.x));
vec3 bitangent = mix(vec3(0.0, 0.0, -1.0), vec3(0.0, 1.0, 0.0), abs(vnormal.z));
world = mat3(tangent, bitangent, vnormal);
vec2 tc = vec2(dot(vvertex.xy, tangent.xy), dot(vvertex.yz, bitangent.yz));
texcoord0 = (tc + waterfalltexgen.zw) * waterfalltexgen.xy;
@(gdepthpackvert 1)
}
] [
@ -342,18 +349,19 @@ lazyshader 0 "waterfallenv" [
lazyshader 0 "waterfall" [
attribute vec4 vvertex;
attribute vec3 vnormal;
attribute vec2 vtexcoord0;
uniform mat4 camprojmatrix;
varying mat3 world;
uniform vec4 waterfalltexgen;
varying vec2 texcoord0;
@(ginterpvert 1)
void main(void)
{
gl_Position = camprojmatrix * vvertex;
texcoord0 = vtexcoord0;
vec3 tangent = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), abs(vnormal.x));
vec3 bitangent = mix(vec3(0.0, 0.0, -1.0), vec3(0.0, 1.0, 0.0), abs(vnormal.z));
world = mat3(tangent, bitangent, vnormal);
vec2 tc = vec2(dot(vvertex.xy, tangent.xy), dot(vvertex.yz, bitangent.yz));
texcoord0 = (tc + waterfalltexgen.zw) * waterfalltexgen.xy;
@(gdepthpackvert 1)
}
] [
@ -389,21 +397,22 @@ lazyshader 0 "waterfall" [
lazyshader 0 "glassenv" [
attribute vec4 vvertex;
attribute vec3 vnormal;
attribute vec2 vtexcoord0;
uniform mat4 camprojmatrix;
uniform vec4 camera;
varying vec3 camdir;
varying mat3 world;
uniform vec2 glasstexgen;
varying vec2 texcoord0;
@(ginterpvert 1)
void main(void)
{
gl_Position = camprojmatrix * vvertex;
texcoord0 = vtexcoord0;
camdir = camera.xyz - vvertex.xyz;
vec3 tangent = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), abs(vnormal.x));
vec3 bitangent = mix(vec3(0.0, 0.0, -1.0), vec3(0.0, 1.0, 0.0), abs(vnormal.z));
world = mat3(tangent, bitangent, vnormal);
vec2 tc = vec2(dot(vvertex.xy, tangent.xy), dot(vvertex.yz, bitangent.yz));
texcoord0 = tc * glasstexgen;
@(gdepthpackvert 1)
}
] [
@ -445,18 +454,19 @@ lazyshader 0 "glassenv" [
lazyshader 0 "glass" [
attribute vec4 vvertex;
attribute vec3 vnormal;
attribute vec2 vtexcoord0;
uniform mat4 camprojmatrix;
varying mat3 world;
uniform vec2 glasstexgen;
varying vec2 texcoord0;
@(ginterpvert 1)
void main(void)
{
gl_Position = camprojmatrix * vvertex;
texcoord0 = vtexcoord0;
vec3 tangent = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), abs(vnormal.x));
vec3 bitangent = mix(vec3(0.0, 0.0, -1.0), vec3(0.0, 1.0, 0.0), abs(vnormal.z));
world = mat3(tangent, bitangent, vnormal);
vec2 tc = vec2(dot(vvertex.xy, tangent.xy), dot(vvertex.yz, bitangent.yz));
texcoord0 = tc * glasstexgen;
@(gdepthpackvert 1)
}
] [

View file

@ -139,6 +139,7 @@ shadowmodelshader "alphashadowmodel" "a"
// b -> dual-quat skeletal animation
// c -> disable cullface
// t -> transparent
// u -> dither
modelvertexshader = [
local modeltype
@ -226,9 +227,16 @@ modelfragmentshader = [
{
vec4 diffuse = texture2D(tex0, texcoord0);
@(? (mdlopt "a") [
if(diffuse.a <= alphatest)
discard;
@(if (mdlopt "a") [
? (mdlopt "u") [
vec2 coords = fract((gl_FragCoord.xy - 0.5)*0.5);
float dither = coords.x + 1.5*coords.y - 4.0*coords.x*coords.y + 0.25;
if(diffuse.a <= alphatest * dither)
discard;
] [
if(diffuse.a <= alphatest)
discard;
]
])
gcolor.rgb = diffuse.rgb*colorscale.rgb;

View file

@ -71,73 +71,55 @@ shader 0 "atmosphere" [
camvec = p.xyz / p.w;
}
] [
// adapted from http://blog.cloudparty.com/2013/09/25/stunning-procedural-skies-in-webgl-part-2/
uniform vec3 sunlight;
uniform vec4 sunlight;
uniform vec3 sundir;
uniform vec3 sundiskparams;
uniform vec3 atmoradius;
uniform float gm;
uniform vec3 betar, betam, betarm;
uniform vec3 sunweight;
uniform vec3 sundiskcolor;
uniform vec2 sundiskparams;
uniform vec4 opticaldepthparams;
uniform vec3 mieparams;
uniform vec3 betarayleigh, betamie, betaozone;
uniform vec2 hdrgamma;
uniform float atmoalpha;
varying vec3 camvec;
fragdata(0) vec4 fragcolor;
vec3 calcextinction(float dist)
{
return exp2(-dist * betarm);
}
vec3 calcscatter(float costheta)
{
float rphase = 1.0 + costheta*costheta;
float mphase = pow(1.0 + gm*(gm - 2.0*costheta), -1.5);
return betar*rphase + betam*mphase;
}
float baseopticaldepth(vec3 ray)
{
float a = atmoradius.x * max(ray.z, min(sundir.z, 0.0));
return sqrt(a*a + atmoradius.z) - a;
}
float opticaldepth(vec3 pos, vec3 ray)
{
pos.z = max(pos.z, 0.0) + atmoradius.x;
float a = dot(pos, ray);
return sqrt(a*a + atmoradius.y - dot(pos, pos)) - a;
}
void main(void)
{
vec3 camdir = normalize(camvec);
float costheta = dot(camdir, sundir);
// sun disk
float edgeoffset = max(1.0 - (1.0 - max(costheta, 0.0)*costheta)*sundiskparams.x, 0.0);
// limb darken with distance to edge
vec3 limbdarken = pow(vec3(edgeoffset), vec3(0.397, 0.503, 0.64));
// lighten edges for corona, but limit it to not interfere with limb darkening
float corona = min(edgeoffset * sundiskparams.y, 1.0);
corona = max(0.1725 / (1.15 - corona * corona) - 0.15, 0.0);
// apply limb darkening and corona to clamped sunlight color
vec3 sundisk = sundiskcolor * limbdarken * corona;
// optical depth along view ray
float raydist = baseopticaldepth(camdir);
float offset = camdir.z*opticaldepthparams.w;
vec3 depth = sqrt(offset*offset + opticaldepthparams.xyz) - offset;
vec3 rayleighweight = betarayleigh * depth.x;
vec3 mieweight = betamie * depth.y;
vec3 ozoneweight = betaozone * (depth.z - depth.x);
// extinction of light along view ray
vec3 extinction = calcextinction(raydist);
vec3 viewweight = sunweight - (rayleighweight + mieweight + ozoneweight);
vec3 extinction = (exp2(viewweight) - 1.0) / viewweight;
// calculate in-scattering
float rphase = (1.5 + 0.5*costheta*costheta) * (3.0 / (16.0 * 3.14159265));
float mphase = inversesqrt(mieparams.x + mieparams.y*min(costheta, mieparams.z));
vec3 scatter = rayleighweight * rphase + mieweight * (mphase * mphase * mphase);
// optical depth for incoming light hitting the view ray
float lightraydist = opticaldepth(camdir * (raydist * max(0.15 + 0.75 * sundir.z, 0.0)), sundir);
// combine scattering and extinction with sundisk
vec3 inscatter = (sunlight.rgb * scatter + sundisk) * extinction;
// cast a ray towards the sun and calculate the incoming extincted light
vec3 incominglight = calcextinction(lightraydist);
// calculate the in-scattering
vec3 scattering = calcscatter(costheta) * (1.0 - extinction);
// combine
vec3 inscatter = incominglight * scattering;
// sun disk
vec3 sundisk = sundiskparams.z * extinction * pow(clamp(costheta*sundiskparams.x + sundiskparams.y, 0.0, 1.0), 8.0);
inscatter += sundisk;
@(hdrgammaencode inscatter)
fragcolor = vec4(sunlight * inscatter, atmoalpha);
fragcolor = vec4(inscatter, sunlight.a);
}
]

172
config/glsl/smfilter.cfg Normal file
View file

@ -0,0 +1,172 @@
// shadow map filters, arg1 enables color sampling
smfiltercolor = [result [
#define filtercolorshadow(tex, tc) texture2DRect(tex, tc.xy @(if $numargs [result [* @arg1]])).rgb
]]
smfilterg5 = [result [
@(? (> $usetexgather 1) [
#define shadowgather(center, xoff, yoff) textureGatherOffset(tex4, center, shadowtc.z, ivec2(xoff, yoff))
] [
#define shadowgather(center, xoff, yoff) step(shadowtc.z, textureGatherOffset(tex4, center, ivec2(xoff, yoff)))
])
float filtershadow(vec3 shadowtc)
{
vec2 offset = fract(shadowtc.xy - 0.5);
vec2 center = (shadowtc.xy - offset) * shadowatlasscale;
vec4 group1 = shadowgather(center, -2, -2);
vec4 group2 = shadowgather(center, 0, -2);
vec4 group3 = shadowgather(center, 2, -2);
vec4 group4 = shadowgather(center, -2, 0);
vec4 group5 = shadowgather(center, 0, 0);
vec4 group6 = shadowgather(center, 2, 0);
vec4 group7 = shadowgather(center, -2, 2);
vec4 group8 = shadowgather(center, 0, 2);
vec4 group9 = shadowgather(center, 2, 2);
vec4 locols = vec4(group1.ab, group3.ab);
vec4 hicols = vec4(group7.rg, group9.rg);
locols.yz += group2.ab;
hicols.yz += group8.rg;
vec4 midcols = vec4(group1.rg, group3.rg) + vec4(group7.ab, group9.ab) +
vec4(group4.rg, group6.rg) + vec4(group4.ab, group6.ab) +
mix(locols, hicols, offset.y);
vec4 cols = group5 + vec4(group2.rg, group8.ab);
cols.xyz += mix(midcols.xyz, midcols.yzw, offset.x);
return dot(cols, vec4(1.0/25.0));
}
@(if $arg1 [smfiltercolor 0.5])
]]
smfilterg3 = [result [
@(? (> $usetexgather 1) [
#define shadowgather(center, xoff, yoff) textureGatherOffset(tex4, center, shadowtc.z, ivec2(xoff, yoff))
] [
#define shadowgather(center, xoff, yoff) step(shadowtc.z, textureGatherOffset(tex4, center, ivec2(xoff, yoff)))
])
float filtershadow(vec3 shadowtc)
{
vec2 offset = fract(shadowtc.xy - 0.5);
vec2 center = (shadowtc.xy - offset) * shadowatlasscale;
vec4 group1 = shadowgather(center, -1, -1);
vec4 group2 = shadowgather(center, 1, -1);
vec4 group3 = shadowgather(center, -1, 1);
vec4 group4 = shadowgather(center, 1, 1);
vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) + mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);
return dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));
}
@(if $arg1 [smfiltercolor 0.5])
]]
smfilterb5 = [result [
#define shadowval(xy, xoff, yoff) float(shadow2DRect(tex4, vec3(xy + vec2(xoff, yoff), shadowtc.z)))
float filtershadow(vec3 shadowtc)
{
vec2 offset = fract(shadowtc.xy - 0.5);
vec4 center = vec4(shadowtc.xy - offset + 0.5, shadowtc.xy - offset*0.5);
vec4 size = vec4(offset + 1.0, 2.0 - offset);
return (1.0/25.0)*dot(size.zxzx*size.wwyy,
vec4(shadowval(center.zw, -1.5, -1.5),
shadowval(center.zw, 2.0, -1.5),
shadowval(center.zw, -1.5, 2.0),
shadowval(center.zw, 2.0, 2.0))) +
(2.0/25.0)*dot(size,
vec4(shadowval(center.zy, 2.0, 0.0),
shadowval(center.xw, 0.0, 2.0),
shadowval(center.zy, -1.5, 0.0),
shadowval(center.xw, 0.0, -1.5))) +
(4.0/25.0)*shadowval(center.xy, 0.0, 0.0);
}
@(if $arg1 [smfiltercolor 0.5])
]]
smfilterb3 = [result [
#define shadowval(center, xoff, yoff) float(shadow2DRect(tex4, center + vec3(xoff, yoff, 0.0)))
float filtershadow(vec3 shadowtc)
{
vec2 offset = fract(shadowtc.xy - 0.5);
vec3 center = shadowtc;
//center.xy -= offset;
//vec4 size = vec4(offset + 1.0, 2.0 - offset), weight = vec4(2.0 - 1.0 / size.xy, 1.0 / size.zw - 1.0);
//return (1.0/9.0)*dot(size.zxzx*size.wwyy,
// vec4(shadowval(center, weight.zw),
// shadowval(center, weight.xw),
// shadowval(center, weight.zy),
// shadowval(center, weight.xy)));
center.xy -= offset*0.5;
vec4 size = vec4(offset + 1.0, 2.0 - offset);
return (1.0/9.0)*dot(size.zxzx*size.wwyy,
vec4(shadowval(center, -0.5, -0.5),
shadowval(center, 1.0, -0.5),
shadowval(center, -0.5, 1.0),
shadowval(center, 1.0, 1.0)));
}
@(if $arg1 [smfiltercolor 0.5])
]]
smfilterrg = [result [
#define shadowval(center, xoff, yoff) float(shadow2DRect(tex4, center + vec3(xoff, yoff, 0.0)))
float filtershadow(vec3 shadowtc)
{
return dot(vec4(0.25),
vec4(shadowval(shadowtc, -0.4, 1.0),
shadowval(shadowtc, -1.0, -0.4),
shadowval(shadowtc, 0.4, -1.0),
shadowval(shadowtc, 1.0, 0.4)));
}
@(if $arg1 [smfiltercolor 0.5])
]]
smfilternone = [result [
float filtershadow(vec3 shadowtc)
{
return float(shadow2DRect(tex4, shadowtc));
}
@(if $arg1 [smfiltercolor])
]]
lazyshader 0 "smalphaclear" [
attribute vec4 vvertex;
uniform vec2 shadowatlasscale;
void main(void)
{
gl_Position = vec4(vvertex.xy * shadowatlasscale * 2.0 - 1.0, 0.0, 1.0);
}
] [
fragdata(0) vec4 fragcolor;
void main(void)
{
fragcolor = vec4(1.0);
}
]
loop i 2 [
lazyshader 0 (? $i "smalphablur2d" "smalphablurrect") [
attribute vec4 vvertex;
attribute vec4 vtexcoord0;
uniform vec2 shadowatlasscale;
flat varying vec4 smbounds;
varying vec4 texcoord0;
void main(void)
{
gl_Position = vec4(vvertex.xy * shadowatlasscale * 2.0 - 1.0, 0.0, 1.0);
smbounds = (vtexcoord0 + vec4(0.5, 0.5, -0.5, -0.5)) @(? $i [* shadowatlasscale.xyxy]);
texcoord0 = (vvertex.xyxy + vec4(-1.0, -1.0, 1.0, 1.0)) @(? $i [* shadowatlasscale.xyxy]);
}
] [
@(? $i [
uniform sampler2D tex0;
#define texval(tc) texture2D(tex0, tc)
] [
uniform sampler2DRect tex0;
#define texval(tc) texture2DRect(tex0, tc)
])
flat varying vec4 smbounds;
varying vec4 texcoord0;
fragdata(0) vec4 fragcolor;
void main(void)
{
vec4 tc = vec4(max(texcoord0.xy, smbounds.xy), min(texcoord0.zw, smbounds.zw));
fragcolor = 0.25 * (texval(tc.xy) + texval(tc.zy) + texval(tc.xw) + texval(tc.zw));
}
]
]

View file

@ -275,7 +275,7 @@ shader 0 "hdrbloom" [
gl_Position = vvertex;
texcoord0 = vtexcoord0;
float avglum = 4.0 * @(? (>= $hwvtexunits 4) [texture2D(tex2, vec2(0.5, 0.5)).r] [vcolor]);
lumscale = hdrparams.x * -log2(1.0 - clamp(avglum, 0.03, 0.3))/(avglum + 1e-4);
lumscale = hdrparams.x * -log2(1.0 - clamp(avglum, @hdrminexposure, @hdrmaxexposure))/(avglum + 1e-4);
lumthreshold = -log2(1.0 - hdrparams.z);
}
] [
@ -307,15 +307,16 @@ hdrtonemapvertexshader = [
])
uniform vec4 hdrparams;
varying vec2 texcoord0, texcoord1;
flat varying float lumscale, lumsaturate;
flat varying float lumscale;
flat varying vec2 lumsaturate;
void main(void)
{
gl_Position = vvertex;
texcoord0 = vtexcoord0;
texcoord1 = vtexcoord1;
float avglum = 4.0 * @(? (>= $hwvtexunits 4) [texture2D(tex2, vec2(0.5, 0.5)).r] [vcolor]);
lumscale = hdrparams.x * -log2(1.0 - clamp(avglum, 0.03, 0.3))/(avglum + 1e-4);
lumsaturate = -log2(1.0 - hdrparams.y) / lumscale;
lumscale = hdrparams.x * -log2(1.0 - clamp(avglum, @hdrminexposure, @hdrmaxexposure))/(avglum + 1e-4);
lumsaturate = vec2(1.0, -hdrparams.y) * 2.0 / max(1.0 - hdrparams.y, 1e-4f);
}
]
]
@ -323,9 +324,8 @@ hdrtonemapvertexshader = [
hdrtonemapfrag = [
result [{
// color = 1.0 - exp2(-color*lumscale);
float lum = dot(@arg1, vec3(@lumweights));
@arg1 = min(@arg1, lumsaturate);
@arg1 *= (1.0 - exp2(-lum*lumscale)) / (dot(@arg1, vec3(@lumweights)) + 1e-4);
float lum = dot(@arg1, vec3(@lumweights)), target = 1.0 - exp2(-lum*lumscale), excess = max(target*lumsaturate.x + lumsaturate.y, 0.0);
@arg1 = (@arg1 + excess) * target / (lum + excess + 1e-4);
}]
]
@ -334,7 +334,8 @@ hdrtonemapdefs = [
uniform vec4 hdrparams;
uniform vec2 hdrgamma;
varying vec2 texcoord0, texcoord1;
flat varying float lumscale, lumsaturate;
flat varying float lumscale;
flat varying vec2 lumsaturate;
]
]

View file

@ -4,7 +4,8 @@ volumetricvariantshader = [
local volumetrictype
volumetrictype = $arg3
maxsteps = $arg4
spotlight = (>= $arg2 1)
spotlight = (>= $arg2 2)
colorshadow = (>= (mod (+ $arg2 1) 3) 2)
variantshader 0 $arg1 $arg2 (? (< $arg2 0) [
attribute vec4 vvertex;
uniform mat4 lightmatrix;
@ -23,6 +24,13 @@ volumetricvariantshader = [
uniform sampler2DRectShadow tex4;
]]
])
@(if $colorshadow [result [
uniform sampler2DRect tex11;
#define filtercolorshadow(tc) texture2DRect(tex11, tc.xy @(? (! (volopt "N")) [* 0.5])).rgb
#define lightshadowtype vec3
]] [result [
#define lightshadowtype float
]])
uniform vec4 lightpos;
uniform vec3 lightcolor;
@(? $spotlight [
@ -92,7 +100,7 @@ volumetricvariantshader = [
ray *= invdist;
vec3 camlight = lightpos.xyz - camera * lightpos.w;
float camlight2 = dot(camlight, camlight), v = dot(camlight, ray), d = v*v + 1.0 - camlight2;
float light = 0.0;
lightshadowtype light = lightshadowtype(0.0);
if(d > 0)
{
d = sqrt(d);
@ -136,7 +144,7 @@ volumetricvariantshader = [
vec3 spottc = getspottc(lightdir, spotdist);
lightatten *= filtershadow(spottc);
])
light += lightatten;
light += lightatten @(? $colorshadow [* filtercolorshadow(spottc)]);
}
]] [result [
float lightatten = clamp(1.0 - length(lightdir), 0.0, 1.0);
@ -144,7 +152,7 @@ volumetricvariantshader = [
vec3 shadowtc = getshadowtc(lightdir);
lightatten *= filtershadow(shadowtc);
])
light += lightatten;
light += lightatten @(? $colorshadow [* filtercolorshadow(shadowtc)]);
]])
space -= stepdist;
if(space <= 0) break;
@ -172,9 +180,15 @@ volumetricshader = [
shadername = (concatword "volumetric" $volumetrictype $arg3)
volumetricvariantshader $shadername -1 $arg1 $arg3
volumetricvariantshader $shadername 0 (concatword $arg1 $arg2) $arg3
if (volopt "P") [
volumetricvariantshader $shadername 1 (concatword $arg1 $arg2) $arg3
]
if (volopt "s") [
volumetricvariantshader $shadername 1 $arg1 $arg3
volumetricvariantshader $shadername 2 (concatword $arg1 $arg2) $arg3
volumetricvariantshader $shadername 2 $arg1 $arg3
volumetricvariantshader $shadername 3 (concatword $arg1 $arg2) $arg3
if (volopt "P") [
volumetricvariantshader $shadername 4 (concatword $arg1 $arg2) $arg3
]
]
]

View file

@ -178,15 +178,20 @@ worldvariantshader = [
]])
@(if (wtopt "a") [
? (wtopt "A") [
if (wtopt "A") [result [
vec3 rlight = gfetch(refractlight, gl_FragCoord.xy).rgb;
gglow.rgb += rlight * refractparams.xyz;
] (? (wtopt "m") [
@(? (wtopt "m") [
gcolor.rgb *= diffuse.a;
gglow.rgb += rlight * refractparams.xyz * (1.0 - colorparams.a * diffuse.a);
] [
gglow.rgb += rlight * refractparams.xyz * (1.0 - colorparams.a);
])
]] [? (wtopt "m") [
gcolor.rgb *= diffuse.a;
#define packnorm diffuse.a * colorparams.a
] [
#define packnorm colorparams.a
])
]]
])
@(gnormpackdef normal packnorm)
@ -443,7 +448,7 @@ bumpvariantshader = [
vec4 diffuse = texture2D(diffusemap, dtc);
@(? (&& (btopt "a") [! (btopt "A")] [btopt "m"]) [
@(? (&& (btopt "a") [btopt "m"]) [
vec4 normal = texture2D(normalmap, dtc);
#define bump normal.rgb
] [
@ -485,17 +490,22 @@ bumpvariantshader = [
]])
@(if (btopt "a") [
? (btopt "A") [
if (btopt "A") [result [
vec2 rtc = bump.xy*refractparams.w;
float rmask = clamp(refractdepth*(lineardepth - dot(gfetch(refractmask, gl_FragCoord.xy + rtc).rgb, gdepthunpackparams)), 0.0, 1.0);
vec3 rlight = gfetch(refractlight, gl_FragCoord.xy + rtc*rmask).rgb;
gglow.rgb += rlight * refractparams.xyz;
] (? (btopt "m") [
@(? (btopt "m") [
gcolor.rgb *= normal.a;
gglow.rgb += rlight * refractparams.xyz * (1.0 - colorparams.a * normal.a);
] [
gglow.rgb += rlight * refractparams.xyz * (1.0 - colorparams.a);
])
]] [? (btopt "m") [
gcolor.rgb *= normal.a;
#define packnorm normal.a * colorparams.a
] [
#define packnorm colorparams.a
])
]]
])
@(gnormpackdef bumpw packnorm)
@ -596,7 +606,7 @@ bumpshader "triplanardetailbumpparallaxworld" "Tdp"
bumpshader "triplanardetailbumpspecparallaxworld" "Tdps"
bumpshader "triplanardetailbumpspecmapparallaxworld" "TdpsS"
shader 0 shadowmapworld [
shader 0 "smworld" [
attribute vec4 vvertex;
uniform mat4 shadowmatrix;
void main(void)
@ -609,6 +619,87 @@ shader 0 shadowmapworld [
}
]
// shadowmaptype:
// a -> transparent
// m -> alpha-mask
// n -> normalmap
smtopt = [ >= (strstr $shadowmaptype $arg1) 0 ]
shadowmapworldvariantshader = [
local shadowmaptype
shadowmaptype = $arg2
srow = -1
if (smtopt "m") [
srow = 0
]
if (smtopt "n") [
srow = 1
]
variantshader 1 $arg1 $srow [
attribute vec4 vvertex;
attribute vec2 vtexcoord0;
uniform vec2 texgenscroll;
uniform vec4 colorparams;
varying vec2 texcoord0;
uniform mat4 shadowmatrix;
void main(void)
{
gl_Position = shadowmatrix * vvertex;
texcoord0 = vtexcoord0 + texgenscroll;
}
] [
uniform vec4 colorparams;
uniform sampler2D diffusemap;
varying vec2 texcoord0;
@(? (smtopt "n") [
uniform sampler2D normalmap;
])
fragdata(0) vec4 gcolor;
void main(void)
{
vec4 diffuse = texture2D(diffusemap, texcoord0);
@(if (smtopt "a") [result [
float alpha = colorparams.a;
@(if (smtopt "m") [result [
@(? (smtopt "n") [
alpha *= texture2D(normalmap, texcoord0).a;
] [
alpha *= diffuse.a;
])
#define mask alpha
]] [result [
#define mask 0.0
]])
]] [result [
#define alpha 1.0
#define mask 1.0
]])
gcolor.rgb = mix(vec3(1.0), diffuse.rgb*colorparams.rgb, alpha) * (1.0 - mask);
gcolor.a = alpha;
}
]
]
shadowmapshader = [
defershader 1 $arg1 [
shadowmapworldvariantshader @arg1 @arg2
shadowmapworldvariantshader @arg1 @(concatword $arg2 "m")
shadowmapworldvariantshader @arg1 @(concatword $arg2 "mn")
]
]
shadowmapshader "smalphaworld" "a"
defershader 1 "rsmworld" [
loop i 2 [
variantshader 1 "rsmworld" (- $i 1) [

View file

@ -110,18 +110,24 @@ struct animmodel : model
struct skin : shaderparams
{
enum
{
DITHER = 1<<0
};
part *owner;
Texture *tex, *decal, *masks, *envmap, *normalmap;
Shader *shader, *rsmshader;
int cullface;
int cullface, flags;
shaderparamskey *key;
skin() : owner(0), tex(notexture), decal(nullptr), masks(notexture), envmap(nullptr), normalmap(nullptr), shader(nullptr), rsmshader(nullptr), cullface(1), key(nullptr) {}
skin() : owner(0), tex(notexture), decal(nullptr), masks(notexture), envmap(nullptr), normalmap(nullptr), shader(nullptr), rsmshader(nullptr), cullface(1), flags(0), key(nullptr) {}
bool masked() const { return masks != notexture; }
bool envmapped() const { return envmapmax>0; }
bool bumpmapped() const { return normalmap != nullptr; }
bool alphatested() const { return alphatest > 0 && tex->type&Texture::ALPHA; }
bool dithered() const { return (flags&DITHER) != 0; }
bool decaled() const { return decal != nullptr; }
void setkey()
@ -187,7 +193,11 @@ struct animmodel : model
string opts;
int optslen = 0;
if(alphatested()) opts[optslen++] = 'a';
if(alphatested())
{
opts[optslen++] = 'a';
if(dithered()) opts[optslen++] = 'u';
}
if(decaled()) opts[optslen++] = decal->type&Texture::ALPHA ? 'D' : 'd';
if(bumpmapped()) opts[optslen++] = 'n';
if(envmapped()) { opts[optslen++] = 'm'; opts[optslen++] = 'e'; }
@ -1060,7 +1070,7 @@ struct animmodel : model
if(animpart<0 || animpart>=MAXANIMPARTS || num<0 || num>=NUM_ANIMS) return;
if(frame<0 || range<=0 || !meshes || !meshes->hasframes(frame, range))
{
conoutf("invalid frame %d, range %d in model %s", frame, range, model->name);
conoutf(CON_ERROR, "invalid frame %d, range %d in model %s", frame, range, model->name);
return;
}
if(!anims[animpart]) anims[animpart] = new vector<animspec>[NUM_ANIMS];
@ -1564,6 +1574,17 @@ struct animmodel : model
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].alphatest = alphatest;
}
void setdither(bool val)
{
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins)
{
skin &s = parts[i]->skins[j];
if(val) s.flags |= skin::DITHER;
else s.flags &= ~skin::DITHER;
}
}
void setfullbright(float fullbright)
{
if(parts.empty()) loaddefaultparts();
@ -1745,12 +1766,12 @@ template<class MDL, class MESH> struct modelcommands
static void setdir(char *name)
{
if(!MDL::loading) { conoutf("not loading an %s", MDL::formatname()); return; }
if(!MDL::loading) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
formatstring(MDL::dir, "media/model/%s", name);
}
#define loopmeshes(meshname, m, body) do { \
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf("not loading an %s", MDL::formatname()); return; } \
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; } \
part &mdl = *MDL::loading->parts.last(); \
if(!mdl.meshes) return; \
loopv(mdl.meshes->meshes) \
@ -1801,6 +1822,11 @@ template<class MDL, class MESH> struct modelcommands
loopskins(meshname, s, s.alphatest = std::max(0.0f, std::min(1.0f, *cutoff)));
}
static void setdither(char *meshname, int *dither)
{
loopskins(meshname, s, { if(*dither) s.flags |= skin::DITHER; else s.flags &= ~skin::DITHER; });
}
static void setcullface(char *meshname, int *cullface)
{
loopskins(meshname, s, s.cullface = *cullface);
@ -1861,9 +1887,9 @@ template<class MDL, class MESH> struct modelcommands
static void setlink(int *parent, int *child, char *tagname, float *x, float *y, float *z)
{
if(!MDL::loading) { conoutf("not loading an %s", MDL::formatname()); return; }
if(!MDL::loading->parts.inrange(*parent) || !MDL::loading->parts.inrange(*child)) { conoutf("no models loaded to link"); return; }
if(!MDL::loading->parts[*parent]->link(MDL::loading->parts[*child], tagname, vec(*x, *y, *z))) conoutf("could not link model %s", MDL::loading->name);
if(!MDL::loading) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
if(!MDL::loading->parts.inrange(*parent) || !MDL::loading->parts.inrange(*child)) { conoutf(CON_ERROR, "no models loaded to link"); return; }
if(!MDL::loading->parts[*parent]->link(MDL::loading->parts[*child], tagname, vec(*x, *y, *z))) conoutf(CON_ERROR, "could not link model %s", MDL::loading->name);
}
template<class F> void modelcommand(F *fun, const char *suffix, const char *args)
@ -1882,6 +1908,7 @@ template<class MDL, class MESH> struct modelcommands
modelcommand(setgloss, "gloss", "si");
modelcommand(setglow, "glow", "sfff");
modelcommand(setalphatest, "alphatest", "sf");
modelcommand(setdither, "dither", "si");
modelcommand(setcullface, "cullface", "si");
modelcommand(setcolor, "color", "sfff");
modelcommand(setenvmap, "envmap", "ss");

View file

@ -16,7 +16,7 @@ bool BIH::triintersect(const mesh &m, int tidx, const vec &mo, const vec &mray,
float det = mray.dot(n), v, w, f;
if(det >= 0)
{
if(!(mode&RAY_SHADOW) && m.flags&MESH_CULLFACE) return false;
if(m.flags&MESH_CULLFACE) return false;
v = e.dot(c);
if(v < 0 || v > det) return false;
w = -e.dot(b);
@ -42,7 +42,7 @@ bool BIH::triintersect(const mesh &m, int tidx, const vec &mo, const vec &mray,
ti = std::clamp(int(m.tex->ys * at.y), 0, m.tex->ys-1);
if(!(m.tex->alphamask[ti*((m.tex->xs+7)/8) + si/8] & (1<<(si%8)))) return false;
}
if(!(mode&RAY_SHADOW)) hitsurface = m.xformnorm.transform(n).normalize();
hitsurface = m.xformnorm.transform(n).normalize();
dist = f*invdet;
return true;
}
@ -134,7 +134,7 @@ inline bool BIH::traverse(const vec &o, const vec &ray, float maxdist, float &di
loopi(nummeshes)
{
mesh &m = meshes[i];
if(!(m.flags&MESH_RENDER) || (!(mode&RAY_SHADOW) && m.flags&MESH_NOCLIP)) continue;
if(!(m.flags&MESH_RENDER) || m.flags&MESH_NOCLIP) continue;
float t1 = (m.bbmin.x - o.x)*invray.x,
t2 = (m.bbmax.x - o.x)*invray.x,
tmin, tmax;
@ -318,11 +318,7 @@ bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist
{
model *m = loadmapmodel(e.attr1);
if(!m) return false;
if(mode&RAY_SHADOW)
{
if(!m->shadow || e.flags&EF_NOSHADOW) return false;
}
else if((mode&RAY_ENTS)!=RAY_ENTS && (!m->collide || e.flags&EF_NOCOLLIDE)) return false;
if((mode&RAY_ENTS)!=RAY_ENTS && (!m->collide || e.flags&EF_NOCOLLIDE)) return false;
if(!m->bih && !m->setBIH()) return false;
float scale = e.attr5 ? 100.0f/e.attr5 : 1.0f;
vec mo = vec(o).sub(e.o).mul(scale), mray(ray);
@ -350,12 +346,9 @@ bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist
if(m->bih->traverse(mo, mray, maxdist ? maxdist*scale : 1e16f, dist, mode))
{
dist /= scale;
if(!(mode&RAY_SHADOW))
{
if(roll != 0) hitsurface.rotate_around_y(sincosmod360(-roll));
if(pitch != 0) hitsurface.rotate_around_x(sincosmod360(pitch));
if(yaw != 0) hitsurface.rotate_around_z(sincosmod360(yaw));
}
if(roll != 0) hitsurface.rotate_around_y(sincosmod360(-roll));
if(pitch != 0) hitsurface.rotate_around_x(sincosmod360(pitch));
if(yaw != 0) hitsurface.rotate_around_z(sincosmod360(yaw));
return true;
}
return false;

View file

@ -691,6 +691,11 @@ int getvarmax(const char *name)
GETVAR(id, name, 0);
return id->maxval;
}
float getfvar(const char *name)
{
_GETVAR(id, ID_FVAR, name, 0);
return *id->storage.f;
}
float getfvarmin(const char *name)
{
_GETVAR(id, ID_FVAR, name, 0);
@ -4200,7 +4205,7 @@ CMPSCMD(>s, >);
CMPSCMD(<=s, <=);
CMPSCMD(>=s, >=);
ICOMMAND(echo, "C", (char *s), conoutf("\f1%s", s));
ICOMMAND(echo, "C", (char *s), conoutf(CON_ECHO, "\f1%s", s));
ICOMMAND(error, "C", (char *s), conoutf(CON_ERROR, "%s", s));
ICOMMAND(strstr, "ss", (char *a, char *b), { char *s = strstr(a, b); intret(s ? s-a : -1); });
ICOMMAND(strlen, "s", (char *s), intret(strlen(s)));

View file

@ -147,49 +147,3 @@ bool getdynlight(int n, vec &o, float &radius, vec &color, vec &dir, int &spot,
flags = d.flags & 0xFF;
return true;
}
void dynlightreaching(const vec &target, vec &color, vec &dir, bool hud)
{
vec dyncolor(0, 0, 0);//, dyndir(0, 0, 0);
loopv(dynlights)
{
dynlight &d = dynlights[i];
if(d.curradius<=0) continue;
vec ray(target);
ray.sub(hud ? d.hud : d.o);
float mag = ray.squaredlen();
if(mag >= d.curradius*d.curradius) continue;