Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2017-05-20 14:16:14 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-05-20 17:58:07 +0300
commitd9d65a06d3db36efd5848cf7ae3e08c72c2c296b (patch)
tree74157d860a6191d92b70df8c8b3f667bc9302ca4 /source/blender/draw/engines/eevee/shaders
parent4c3382d55f98c721f6116919acce4abba8f01f11 (diff)
Eevee: Move cube shadows to octahedron shadowmaps.
We render linear distance to the light in a R32 texture and store it into an octahedron projection inside a 2D texture array. This render the sampling function much more simpler and without edge artifacts.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl78
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_frag.glsl5
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_geom.glsl15
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl47
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl22
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl8
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_vert.glsl9
7 files changed, 117 insertions, 67 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 1e29aed739d..1c124c06744 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -11,8 +11,7 @@ uniform vec3 shCoefs[9];
#ifndef USE_LTC
uniform sampler2D brdfLut;
#endif
-uniform sampler2DArrayShadow shadowCubes;
-uniform sampler2DArrayShadow shadowMaps;
+uniform sampler2DArray shadowCubes;
uniform sampler2DArrayShadow shadowCascades;
layout(std140) uniform light_block {
@@ -130,75 +129,30 @@ float light_visibility(LightData ld, ShadingData sd)
vis *= texture(shadowCascades, vec4(shpos.xy, shid * float(MAX_CASCADE_NUM) + cascade, shpos.z));
}
- else if (ld.l_shadowid >= MAX_SHADOW_CUBE) {
- /* Shadow Map */
- float shid = ld.l_shadowid - MAX_SHADOW_CUBE;
- ShadowMapData smd = shadows_map_data[int(shid)];
- vec4 shpos = smd.shadowmat * vec4(sd.W, 1.0);
- shpos.z -= smd.sh_map_bias * shpos.w;
- shpos.xyz /= shpos.w;
-
- if (shpos.w > 0.0 && min(shpos.x, shpos.y) > 0.0 && max(shpos.x, shpos.y) < 1.0) {
- vis *= texture(shadowMaps, vec4(shpos.xy, shid, shpos.z));
- }
- }
else {
/* Shadow Cube */
float shid = ld.l_shadowid;
ShadowCubeData scd = shadows_cube_data[int(shid)];
- float face;
- vec2 uvs;
- vec3 Linv = sd.L;
- vec3 Labs = abs(Linv);
- vec3 maj_axis;
-
- if (max(Labs.y, Labs.z) < Labs.x) {
- if (Linv.x > 0.0) {
- face = 1.0;
- uvs = vec2(1.0, -1.0) * Linv.zy / -Linv.x;
- maj_axis = vec3(1.0, 0.0, 0.0);
- }
- else {
- face = 0.0;
- uvs = -Linv.zy / Linv.x;
- maj_axis = vec3(-1.0, 0.0, 0.0);
- }
- }
- else if (max(Labs.x, Labs.z) < Labs.y) {
- if (Linv.y > 0.0) {
- face = 2.0;
- uvs = vec2(-1.0, 1.0) * Linv.xz / Linv.y;
- maj_axis = vec3(0.0, 1.0, 0.0);
- }
- else {
- face = 3.0;
- uvs = -Linv.xz / -Linv.y;
- maj_axis = vec3(0.0, -1.0, 0.0);
- }
- }
- else {
- if (Linv.z > 0.0) {
- face = 5.0;
- uvs = Linv.xy / Linv.z;
- maj_axis = vec3(0.0, 0.0, 1.0);
- }
- else {
- face = 4.0;
- uvs = vec2(-1.0, 1.0) * Linv.xy / -Linv.z;
- maj_axis = vec3(0.0, 0.0, -1.0);
- }
+ vec3 cubevec = sd.W - ld.l_position;
+ float dist = length(cubevec);
+
+ /* projection onto octahedron */
+ cubevec /= dot( vec3(1), abs(cubevec) );
+
+ /* out-folding of the downward faces */
+ if ( cubevec.z < 0.0 ) {
+ cubevec.xy = (1.0 - abs(cubevec.yx)) * sign(cubevec.xy);
}
+ vec2 texelSize = vec2(1.0 / 512.0);
- uvs = uvs * 0.5 + 0.5;
+ /* mapping to [0;1]ˆ2 texture space */
+ vec2 uvs = cubevec.xy * (0.5) + 0.5;
+ uvs = uvs * (1.0 - 2.0 * texelSize) + 1.0 * texelSize; /* edge filtering fix */
- /* Depth in lightspace to compare against shadow map */
- float w = dot(maj_axis, sd.l_vector);
- w -= scd.sh_map_bias * w;
- bool is_persp = (ProjectionMatrix[3][3] == 0.0);
- float shdepth = buffer_depth(is_persp, w, scd.sh_cube_far, scd.sh_cube_near);
+ float sh_test = step(0, texture(shadowCubes, vec3(uvs, shid)).r - dist);
- vis *= texture(shadowCubes, vec4(uvs, shid * 6.0 + face, shdepth));
+ vis *= sh_test;
}
return vis;
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
index 29335207851..0b7356d812b 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_frag.glsl
@@ -1,3 +1,8 @@
+in float linearDistance;
+
+out vec4 FragColor;
+
void main() {
+ FragColor = vec4(linearDistance, 0.0, 0.0, 1.0);
}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
index bac6a10eee1..c4738de2f31 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_geom.glsl
@@ -1,21 +1,26 @@
-layout(triangles) in;
-layout(triangle_strip, max_vertices=3) out;
-
layout(std140) uniform shadow_render_block {
mat4 ShadowMatrix[6];
- int Layer;
+ vec4 lampPosition;
+ int layer;
};
+layout(triangles) in;
+layout(triangle_strip, max_vertices=3) out;
+
in vec4 vPos[];
+in float lDist[];
flat in int face[];
+out float linearDistance;
+
void main() {
int f = face[0];
- gl_Layer = Layer + f;
+ gl_Layer = f;
for (int v = 0; v < 3; ++v) {
gl_Position = ShadowMatrix[f] * vPos[v];
+ linearDistance = lDist[v];
EmitVertex();
}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
new file mode 100644
index 00000000000..08453080ed2
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_frag.glsl
@@ -0,0 +1,47 @@
+
+uniform samplerCube shadowCube;
+
+out vec4 FragColor;
+
+vec3 octahedral_to_cubemap_proj(vec2 co)
+{
+ co = co * 2.0 - 1.0;
+
+ vec2 abs_co = abs(co);
+ vec3 v = vec3(co, 1.0 - (abs_co.x + abs_co.y));
+
+ if ( abs_co.x + abs_co.y > 1.0 ) {
+ v.xy = (abs(co.yx) - 1.0) * -sign(co.xy);
+ }
+
+ return v;
+}
+
+void main() {
+ const vec2 texelSize = vec2(1.0 / 512.0);
+
+ vec2 uvs = gl_FragCoord.xy * texelSize;
+
+ /* add a 2 pixel border to ensure filtering is correct */
+ uvs.xy *= 1.0 + texelSize * 2.0;
+ uvs.xy -= texelSize;
+
+ float pattern = 1.0;
+
+ /* edge mirroring : only mirror if directly adjacent
+ * (not diagonally adjacent) */
+ vec2 m = abs(uvs - 0.5) + 0.5;
+ vec2 f = floor(m);
+ if (f.x - f.y != 0.0) {
+ uvs.xy = 1.0 - uvs.xy;
+ }
+
+ /* clamp to [0-1] */
+ uvs.xy = fract(uvs.xy);
+
+ /* get cubemap vector */
+ vec3 cubevec = octahedral_to_cubemap_proj(uvs.xy);
+
+ /* get cubemap vector */
+ FragColor = texture(shadowCube, cubevec).rrrr;
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl
new file mode 100644
index 00000000000..f14354ad4cd
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_geom.glsl
@@ -0,0 +1,22 @@
+
+layout(std140) uniform shadow_render_block {
+ mat4 ShadowMatrix[6];
+ vec4 lampPosition;
+ int layer;
+};
+
+layout(triangles) in;
+layout(triangle_strip, max_vertices=3) out;
+
+in vec4 vPos[];
+
+void main() {
+ gl_Layer = layer;
+
+ for (int v = 0; v < 3; ++v) {
+ gl_Position = vPos[v];
+ EmitVertex();
+ }
+
+ EndPrimitive();
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl
new file mode 100644
index 00000000000..dee020f19b4
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_store_vert.glsl
@@ -0,0 +1,8 @@
+
+in vec3 pos;
+
+out vec4 vPos;
+
+void main() {
+ vPos = vec4(pos, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
index ffb99f1b35c..323cf4d2a99 100644
--- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
+++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl
@@ -1,12 +1,21 @@
+layout(std140) uniform shadow_render_block {
+ mat4 ShadowMatrix[6];
+ vec4 lampPosition;
+ int layer;
+};
+
uniform mat4 ShadowModelMatrix;
in vec3 pos;
out vec4 vPos;
+out float lDist;
+
flat out int face;
void main() {
vPos = ShadowModelMatrix * vec4(pos, 1.0);
+ lDist = distance(lampPosition.xyz, vPos.xyz);
face = gl_InstanceID;
} \ No newline at end of file