Pixel-Composer/shaders/sh_shadow_cast/sh_shadow_cast.fsh

176 lines
3.9 KiB
Plaintext
Raw Normal View History

2023-01-17 08:11:55 +01:00
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform vec2 dimension;
uniform vec2 lightPos;
2023-01-25 06:49:00 +01:00
uniform int useSolid;
2023-01-17 08:11:55 +01:00
uniform sampler2D solid;
uniform float pointLightRadius;
uniform float lightRadius;
uniform float lightDensity;
uniform int lightType;
uniform int renderSolid;
2023-01-25 06:49:00 +01:00
uniform int bgUse;
uniform float bgThres;
uniform float lightBand;
uniform float lightAttn;
uniform float ao;
uniform float aoStr;
uniform int mask;
2023-01-17 08:11:55 +01:00
uniform vec4 lightAmb;
uniform vec4 lightClr;
2023-01-25 06:49:00 +01:00
uniform float lightInt;
#define TAU 6.283185307179586
2023-01-17 08:11:55 +01:00
void main() {
vec4 bg = texture2D( gm_BaseTexture, v_vTexcoord );
vec4 sl = texture2D( solid, v_vTexcoord );
2023-01-25 06:49:00 +01:00
if(useSolid == 1 && sl.a == 1.) {
if(mask == 0)
2023-03-05 07:16:44 +01:00
gl_FragColor = renderSolid == 1? sl : bg * lightAmb;
2023-01-25 06:49:00 +01:00
else if(mask == 1)
gl_FragColor = vec4(vec3(0.), bg.a);
2023-01-17 08:11:55 +01:00
return;
}
float bright = 1.;
2023-03-05 07:16:44 +01:00
vec2 tx = 1. / dimension;
vec2 aspect = vec2(dimension) / dimension.x;
2023-01-17 08:11:55 +01:00
2023-03-05 07:16:44 +01:00
vec2 pxPos = v_vTexcoord * dimension;
2023-01-17 08:11:55 +01:00
vec2 ang, lang;
vec2 lightPosTx = lightPos * tx;
float dst;
if(lightType == 0) {
2023-03-05 07:16:44 +01:00
ang = normalize(lightPos - pxPos) * tx;
lang = vec2(ang.y, -ang.x) * lightRadius * dimension;
dst = length(lightPos - pxPos);
2023-01-17 08:11:55 +01:00
} else if(lightType == 1) {
ang = normalize(lightPosTx - vec2(.5)) * tx;
lang = vec2(ang.y, -ang.x) * lightRadius;
dst = length(dimension);
}
float softlight = lightDensity - 1.;
float lightAmo = softlight * 2. + 1.;
2023-01-25 06:49:00 +01:00
int iLightAmo = int(lightAmo);
2023-01-17 08:11:55 +01:00
int lightCatch[33];
2023-01-25 06:49:00 +01:00
for(int i = 0; i < iLightAmo; i++)
2023-01-17 08:11:55 +01:00
lightCatch[i] = 1;
for(float i = 1.; i < dst; i++) {
2023-01-25 06:49:00 +01:00
for(int j = 0; j <= iLightAmo; j++) {
2023-01-17 08:11:55 +01:00
if(lightCatch[j] == 0) continue;
vec2 _lightPos, _ang;
if(lightType == 0) {
2023-03-05 07:16:44 +01:00
_lightPos = lightPos + lang * (float(j) - softlight);
_ang = normalize(_lightPos - pxPos) * tx;
2023-01-17 08:11:55 +01:00
} else if(lightType == 1) {
_lightPos = vec2(.5) + ang * dimension + lang * (float(j) - softlight);
_ang = normalize(_lightPos - vec2(.5)) * tx;
}
vec2 _pos = v_vTexcoord + _ang * i;
vec2 _posPx = _pos * dimension;
if(lightType == 0 && floor(abs(lightPos.x - _posPx.x)) + floor(abs(lightPos.y - _posPx.y)) < 1.)
continue;
if(_pos.x < 0. || _pos.y < 0. || _pos.x > 1. || _pos.y > 1.)
continue;
2023-01-25 06:49:00 +01:00
if(useSolid == 1) {
vec4 _sl = texture2D( solid, _pos );
if(_sl.a == 1.)
lightCatch[j] = 0;
}
if(bgUse == 1) {
vec4 hg = texture2D( gm_BaseTexture, _pos );
if(distance(bg, hg) >= bgThres)
lightCatch[j] = 0;
}
}
}
if(ao > 0.) {
float ambient = 0.;
2023-02-23 07:02:19 +01:00
for(float i = 0.; i < ao; i++) {
float base = 1.;
float top = 0.;
for(float j = 0.; j <= 64.; j++) {
float ang = top / base * TAU;
top += 2.;
if(top >= base) {
top = 1.;
base *= 2.;
}
vec2 _pos = v_vTexcoord + vec2(cos(ang), sin(ang)) * i * tx;
2023-01-25 06:49:00 +01:00
2023-02-23 07:02:19 +01:00
if(_pos.x < 0. || _pos.y < 0. || _pos.x > 1. || _pos.y > 1.)
continue;
2023-01-25 06:49:00 +01:00
2023-02-23 07:02:19 +01:00
if(useSolid == 1) {
vec4 _sl = texture2D( solid, _pos );
if(_sl.a == 1.)
ambient++;
}
2023-01-17 08:11:55 +01:00
2023-02-23 07:02:19 +01:00
if(bgUse == 1) {
vec4 hg = texture2D( gm_BaseTexture, _pos );
if(distance(bg, hg) >= bgThres)
ambient++;
}
2023-01-25 06:49:00 +01:00
}
2023-01-17 08:11:55 +01:00
}
2023-01-25 06:49:00 +01:00
2023-02-23 07:02:19 +01:00
lightAmo += ambient * aoStr * aoStr;
2023-01-17 08:11:55 +01:00
}
int lightCatched = 0;
2023-01-25 06:49:00 +01:00
for(int i = 0; i < iLightAmo; i++) {
2023-01-17 08:11:55 +01:00
if(lightCatch[i] == 1)
lightCatched++;
}
float shadow = float(lightCatched) / lightAmo;
if(lightType == 0) {
float dist = distance(v_vTexcoord * dimension, lightPos);
float prg = 1. - clamp(dist / pointLightRadius, 0., 1.);
2023-01-25 06:49:00 +01:00
2023-01-17 08:11:55 +01:00
shadow *= prg * prg;
}
2023-01-25 06:49:00 +01:00
if(lightAttn == 0.)
shadow = shadow * shadow;
else if(lightAttn == 1.)
shadow = 1. - (shadow - 1.) * (shadow - 1.);
else if(lightAttn == 2.)
shadow = shadow;
2023-01-17 08:11:55 +01:00
2023-01-25 06:49:00 +01:00
if(lightBand > 0.)
shadow = ceil(shadow * lightBand) / lightBand;
if(mask == 0)
2023-03-05 07:16:44 +01:00
gl_FragColor = vec4(bg.rgb * mix(lightClr * lightAmb, lightClr, shadow * lightInt).rgb, bg.a);
2023-01-25 06:49:00 +01:00
else if(mask == 1)
gl_FragColor = vec4(vec3(shadow * lightInt), bg.a);
2023-01-17 08:11:55 +01:00
}