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-29 23:03:57 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-05-29 23:04:30 +0300
commit5773f587622ebf58f6aa3bf4ae60431e8b0f39ef (patch)
treee7f22a4c51464dc443f68a964bc32b18c55e7e42 /source/blender/draw/engines/eevee/shaders
parent1fa216487d69c79ef81ccf679090e2bfea5b64fd (diff)
Eevee: Replace Cubemaps by octahedron maps for env. probes.
This enables us to use 2D texture arrays for multiple probes. There is a little artifact with very high roughness caused elongated pixel due to the projection (along every 90° meridian).
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders')
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl57
-rw-r--r--source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl39
2 files changed, 79 insertions, 17 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 bff7c05537a..ca3cec62bdb 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -4,7 +4,7 @@ uniform vec3 cameraPos;
uniform vec3 eye;
uniform mat4 ProjectionMatrix;
-uniform samplerCube probeFiltered;
+uniform sampler2D probeFiltered;
uniform float lodMax;
uniform vec3 shCoefs[9];
@@ -42,6 +42,44 @@ in vec3 viewNormal;
#define HEMI 3.0
#define AREA 4.0
+vec2 mapping_octahedron(vec3 cubevec, vec2 texel_size)
+{
+ /* 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);
+ }
+
+ /* mapping to [0;1]ˆ2 texture space */
+ vec2 uvs = cubevec.xy * (0.5) + 0.5;
+
+ /* edge filtering fix */
+ uvs *= 1.0 - 2.0 * texel_size;
+ uvs += texel_size;
+
+ return uvs;
+}
+
+vec4 textureLod_octahedron(sampler2D tex, vec3 cubevec, float lod)
+{
+ vec2 texelSize = 1.0 / vec2(textureSize(tex, int(lodMax)));
+
+ vec2 uvs = mapping_octahedron(cubevec, texelSize);
+
+ return textureLod(tex, uvs, lod);
+}
+
+vec4 texture_octahedron(sampler2DArray tex, vec4 cubevec)
+{
+ vec2 texelSize = 1.0 / vec2(textureSize(tex, 0));
+
+ vec2 uvs = mapping_octahedron(cubevec.xyz, texelSize);
+
+ return texture(tex, vec3(uvs, cubevec.w));
+}
+
void light_shade(
LightData ld, ShadingData sd, vec3 albedo, float roughness, vec3 f0,
out vec3 diffuse, out vec3 specular)
@@ -139,20 +177,7 @@ void light_visibility(LightData ld, ShadingData sd, out float vis)
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);
-
- /* 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 */
-
- float z = texture(shadowCubes, vec3(uvs, shid)).r;
+ float z = texture_octahedron(shadowCubes, vec4(cubevec, shid)).r;
float esm_test = min(1.0, exp(-5.0 * dist) * z);
float sh_test = step(0, z - dist);
@@ -194,7 +219,7 @@ vec3 eevee_surface_lit(vec3 world_normal, vec3 albedo, vec3 f0, float roughness,
/* Envmaps */
vec2 uv = lut_coords(dot(sd.N, sd.V), roughness);
vec3 brdf_lut = texture(brdfLut, uv).rgb;
- vec3 Li = textureLod(probeFiltered, spec_dir, roughness * lodMax).rgb;
+ vec3 Li = textureLod_octahedron(probeFiltered, spec_dir, roughness * lodMax).rgb;
indirect_radiance += Li * F_ibl(f0, brdf_lut.rg);
indirect_radiance += spherical_harmonics(sd.N, shCoefs) * albedo;
diff --git a/source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl b/source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl
index bee674e3e76..33714c5293c 100644
--- a/source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/probe_filter_frag.glsl
@@ -1,17 +1,54 @@
uniform samplerCube probeHdr;
uniform float roughnessSquared;
+uniform float texelSize;
uniform float lodFactor;
uniform float lodMax;
+uniform float paddingSize;
in vec3 worldPosition;
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() {
+ vec2 uvs = gl_FragCoord.xy * texelSize;
+
+ /* Add a N pixel border to ensure filtering is correct
+ * for N mipmap levels. */
+ uvs += uvs * texelSize * paddingSize * 2.0;
+ uvs -= texelSize * paddingSize;
+
+ /* 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 = 1.0 - uvs;
+ }
+
+ /* clamp to [0-1] */
+ uvs = fract(uvs);
+
+ /* get cubemap vector */
+ vec3 cubevec = octahedral_to_cubemap_proj(uvs);
+
vec3 N, T, B, V;
- vec3 R = normalize(worldPosition);
+ vec3 R = normalize(cubevec);
/* Isotropic assumption */
N = V = R;