summaryrefslogtreecommitdiff
path: root/servers/visual/rasterizer/shaders
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2019-07-07 01:49:40 -0300
committerJuan Linietsky <reduzio@gmail.com>2020-02-11 11:53:28 +0100
commitf04359e70f87a6ffa0522f2b62319d605cd65792 (patch)
tree9e3168f03d68dc2d934b92ea7e56bcb59aaeffdc /servers/visual/rasterizer/shaders
parenta7b2ac7bb1b5f9155866382f14138e86e52efded (diff)
2D lighting seems more or less complete.
Diffstat (limited to 'servers/visual/rasterizer/shaders')
-rw-r--r--servers/visual/rasterizer/shaders/canvas.glsl65
-rw-r--r--servers/visual/rasterizer/shaders/canvas_occlusion.glsl8
-rw-r--r--servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl53
-rw-r--r--servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl9
4 files changed, 126 insertions, 9 deletions
diff --git a/servers/visual/rasterizer/shaders/canvas.glsl b/servers/visual/rasterizer/shaders/canvas.glsl
index 6b1485c86b..eb5bdbe46e 100644
--- a/servers/visual/rasterizer/shaders/canvas.glsl
+++ b/servers/visual/rasterizer/shaders/canvas.glsl
@@ -491,6 +491,71 @@ FRAGMENT_SHADER_CODE
light_color.a = 0.0;
}
+ if (bool(light_array.data[light_base].flags&LIGHT_FLAGS_HAS_SHADOW)) {
+
+ vec2 shadow_pos = (vec4(vertex,0.0,1.0) * mat4(light_array.data[light_base].shadow_matrix[0],light_array.data[light_base].shadow_matrix[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
+
+ vec2 pos_norm = normalize(shadow_pos);
+ vec2 pos_abs = abs(pos_norm);
+ vec2 pos_box = pos_norm / max(pos_abs.x,pos_abs.y);
+ vec2 pos_rot = pos_norm * mat2(vec2(0.7071067811865476,-0.7071067811865476),vec2(0.7071067811865476,0.7071067811865476)); //is there a faster way to 45 degrees rot?
+ float tex_ofs;
+ float distance;
+ if (pos_rot.y>0) {
+ if (pos_rot.x>0) {
+ tex_ofs=pos_box.y*0.125+0.125;
+ distance=shadow_pos.x;
+ } else {
+ tex_ofs=pos_box.x*-0.125+(0.25+0.125);
+ distance=shadow_pos.y;
+ }
+ } else {
+ if (pos_rot.x<0) {
+ tex_ofs=pos_box.y*-0.125+(0.5+0.125);
+ distance=-shadow_pos.x;
+ } else {
+ tex_ofs=pos_box.x*0.125+(0.75+0.125);
+ distance=-shadow_pos.y;
+ }
+ }
+
+ //float distance = length(shadow_pos);
+ float shadow;
+ uint shadow_mode = light_array.data[light_base].flags&LIGHT_FLAGS_FILTER_MASK;
+ if (shadow_mode==LIGHT_FLAGS_SHADOW_NEAREST) {
+ shadow = step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs,0.0)).x,distance);
+ } else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF5) {
+ float shadow_pixel_size = light_array.data[light_base].shadow_pixel_size;
+ shadow = 0.0;
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*2.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*2.0,0.0)).x,distance);
+ shadow/=5.0;
+ } else if (shadow_mode==LIGHT_FLAGS_SHADOW_PCF13) {
+ float shadow_pixel_size = light_array.data[light_base].shadow_pixel_size;
+ shadow = 0.0;
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*6.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*5.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*4.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*3.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size*2.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs-shadow_pixel_size,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*2.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*3.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*4.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*5.0,0.0)).x,distance);
+ shadow += step(texture(sampler2D(shadow_textures[texture_idx],texture_sampler),vec2(tex_ofs+shadow_pixel_size*6.0,0.0)).x,distance);
+ shadow/=13.0;
+ }
+
+ light_color = mix(light_color,light_array.data[light_base].shadow_color,shadow);
+
+ }
+
uint blend_mode = light_array.data[light_base].flags&LIGHT_FLAGS_BLEND_MASK;
switch(blend_mode) {
diff --git a/servers/visual/rasterizer/shaders/canvas_occlusion.glsl b/servers/visual/rasterizer/shaders/canvas_occlusion.glsl
index fb35f16971..01e87411d3 100644
--- a/servers/visual/rasterizer/shaders/canvas_occlusion.glsl
+++ b/servers/visual/rasterizer/shaders/canvas_occlusion.glsl
@@ -8,16 +8,18 @@ layout(location = 0) in highp vec3 vertex;
layout(push_constant, binding = 0, std430) uniform Constants {
- mat4 modelview;
mat4 projection;
+ mat2x4 modelview;
+ vec2 direction;
+ vec2 pad;
} constants;
layout(location = 0) out highp float depth;
void main() {
- highp vec4 vtx = (constants.modelview * vec4(vertex, 1.0));
- depth = length(vtx.xy);
+ highp vec4 vtx = vec4(vertex, 1.0) * mat4(constants.modelview[0],constants.modelview[1],vec4(0.0,0.0,1.0,0.0),vec4(0.0,0.0,0.0,1.0));
+ depth = dot(constants.direction,vtx.xy);
gl_Position = constants.projection * vtx;
diff --git a/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl b/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl
index 48757bb68a..7c9651201e 100644
--- a/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl
+++ b/servers/visual/rasterizer/shaders/canvas_occlusion_fix.glsl
@@ -35,22 +35,65 @@ layout(set=0, binding=0) uniform sampler2D textures[4];
layout(location = 0) in highp float u;
layout(location = 0) out highp float distance;
+layout(push_constant, binding = 0, std430) uniform Constants {
+ mat4 projection;
+ float far;
+ float pad[3];
+} constants;
+
void main() {
//0-1 in the texture we are writing to represents a circle, 0-2PI)
//obtain the quarter circle from the source textures
- highp float sub_angle = ((mod(u,0.25)/0.25)*2.0-1.0)*(PI/4.0);
- highp float x=tan(sub_angle)*0.5+0.5;
+ float angle=fract(u+1.0-0.125);
float depth;
- if (u<0.25) {
+#if 0
+ if (angle<0.25) {
+ highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0);
+ highp float x=tan(sub_angle)*0.5+0.5;
depth=texture(textures[0],vec2(x,0.0)).x;
- } else if (u<0.50) {
+ } else if (angle<0.50) {
+ highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0);
+ highp float x=tan(sub_angle)*0.5+0.5;
depth=texture(textures[1],vec2(x,0.0)).x;
- } else if (u<0.75) {
+ } else if (angle<0.75) {
+ highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0);
+ highp float x=tan(sub_angle)*0.5+0.5;
depth=texture(textures[2],vec2(x,0.0)).x;
} else {
+ highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0);
+ highp float x=tan(sub_angle)*0.5+0.5;
depth=texture(textures[3],vec2(x,0.0)).x;
}
+#else
+ if (angle<0.25) {
+ highp float sub_angle = ((angle/0.25)*2.0-1.0)*(PI/4.0);
+ vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
+ vec4 proj = constants.projection * vec4(pos,0.0,1.0);
+ float coord = (proj.x/proj.w)*0.5+0.5;
+ depth=texture(textures[0],vec2(coord,0.0)).x;
+ } else if (angle<0.50) {
+ highp float sub_angle = (((angle-0.25)/0.25)*2.0-1.0)*(PI/4.0);
+ vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
+ vec4 proj = constants.projection * vec4(pos,0.0,1.0);
+ float coord = (proj.x/proj.w)*0.5+0.5;
+ depth=texture(textures[1],vec2(coord,0.0)).x;
+ } else if (angle<0.75) {
+ highp float sub_angle = (((angle-0.5)/0.25)*2.0-1.0)*(PI/4.0);
+ vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
+ vec4 proj = constants.projection * vec4(pos,0.0,1.0);
+ float coord = (proj.x/proj.w)*0.5+0.5;
+ depth=texture(textures[2],vec2(coord,0.0)).x;
+ } else {
+ highp float sub_angle = (((angle-0.75)/0.25)*2.0-1.0)*(PI/4.0);
+ vec2 pos = vec2(cos(sub_angle),sin(sub_angle))*constants.far;
+ vec4 proj = constants.projection * vec4(pos,0.0,1.0);
+ float coord = (proj.x/proj.w)*0.5+0.5;
+ depth=texture(textures[3],vec2(coord,0.0)).x;
+ }
+
+
+#endif
distance=depth;
}
diff --git a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl b/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl
index cf8a17ce1e..7f55be051c 100644
--- a/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl
+++ b/servers/visual/rasterizer/shaders/canvas_uniforms_inc.glsl
@@ -93,10 +93,17 @@ layout(set = 3, binding = 0, std140) uniform CanvasData {
#define LIGHT_FLAGS_BLEND_MODE_SUB (1<<16)
#define LIGHT_FLAGS_BLEND_MODE_MIX (2<<16)
#define LIGHT_FLAGS_BLEND_MODE_MASK (3<<16)
+#define LIGHT_FLAGS_HAS_SHADOW (1<<20)
+#define LIGHT_FLAGS_FILTER_SHIFT 22
+#define LIGHT_FLAGS_FILTER_MASK (3<<22)
+#define LIGHT_FLAGS_SHADOW_NEAREST (0<<22)
+#define LIGHT_FLAGS_SHADOW_PCF5 (1<<22)
+#define LIGHT_FLAGS_SHADOW_PCF13 (2<<22)
struct Light {
- mat2x4 matrix; //light to texture coordinate matrix
+ mat2x4 matrix; //light to texture coordinate matrix (transposed)
+ mat2x4 shadow_matrix; //light to shadow coordinate matrix (transposed)
vec4 color;
vec4 shadow_color;
vec2 position;