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-06-28 17:31:25 +0300
committerClément Foucault <foucault.clem@gmail.com>2017-06-28 17:32:08 +0300
commit1982e724f4958913bfc274e845e639cd23d012af (patch)
treee1c226a27672dd3b2382d5544da9f6555bc2d68c /source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
parent0782c9f8dc4c9ab64321af27e1a64b5eb3523ffc (diff)
Eevee: Refactor of shading code to be more modular.
This will enable creating shading models more easily.
Diffstat (limited to 'source/blender/draw/engines/eevee/shaders/lamps_lib.glsl')
-rw-r--r--source/blender/draw/engines/eevee/shaders/lamps_lib.glsl193
1 files changed, 193 insertions, 0 deletions
diff --git a/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
new file mode 100644
index 00000000000..b031b45d1c4
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/lamps_lib.glsl
@@ -0,0 +1,193 @@
+
+uniform sampler2DArray shadowCubes;
+uniform sampler2DArrayShadow shadowCascades;
+
+layout(std140) uniform shadow_block {
+ ShadowCubeData shadows_cube_data[MAX_SHADOW_CUBE];
+ ShadowMapData shadows_map_data[MAX_SHADOW_MAP];
+ ShadowCascadeData shadows_cascade_data[MAX_SHADOW_CASCADE];
+};
+
+layout(std140) uniform probe_block {
+ CubeData probes_data[MAX_PROBE];
+};
+
+layout(std140) uniform grid_block {
+ GridData grids_data[MAX_GRID];
+};
+
+layout(std140) uniform planar_block {
+ PlanarData planars_data[MAX_PLANAR];
+};
+
+layout(std140) uniform light_block {
+ LightData lights_data[MAX_LIGHT];
+};
+
+/* type */
+#define POINT 0.0
+#define SUN 1.0
+#define SPOT 2.0
+#define HEMI 3.0
+#define AREA 4.0
+
+float shadow_cubemap(float shid, vec3 l_vector, vec3 W)
+{
+ ShadowCubeData scd = shadows_cube_data[int(shid)];
+
+ vec3 cubevec = W - l_vector;
+ float dist = length(cubevec) - scd.sh_cube_bias;
+
+ float z = texture_octahedron(shadowCubes, vec4(cubevec, shid)).r;
+
+ float esm_test = saturate(exp(scd.sh_cube_exp * (z - dist)));
+ // float sh_test = step(0, z - dist);
+
+ return esm_test;
+}
+
+float shadow_cascade(float shid, vec3 W)
+{
+ /* Shadow Cascade */
+ shid -= (MAX_SHADOW_CUBE + MAX_SHADOW_MAP);
+ ShadowCascadeData smd = shadows_cascade_data[int(shid)];
+
+ /* Finding Cascade index */
+ vec4 z = vec4(-dot(cameraPos - W, cameraForward));
+ vec4 comp = step(z, smd.split_distances);
+ float cascade = dot(comp, comp);
+ mat4 shadowmat;
+ float bias;
+
+ /* Manual Unrolling of a loop for better performance.
+ * Doing fetch directly with cascade index leads to
+ * major performance impact. (0.27ms -> 10.0ms for 1 light) */
+ if (cascade == 0.0) {
+ shadowmat = smd.shadowmat[0];
+ bias = smd.bias[0];
+ }
+ else if (cascade == 1.0) {
+ shadowmat = smd.shadowmat[1];
+ bias = smd.bias[1];
+ }
+ else if (cascade == 2.0) {
+ shadowmat = smd.shadowmat[2];
+ bias = smd.bias[2];
+ }
+ else {
+ shadowmat = smd.shadowmat[3];
+ bias = smd.bias[3];
+ }
+
+ vec4 shpos = shadowmat * vec4(W, 1.0);
+ shpos.z -= bias * shpos.w;
+ shpos.xyz /= shpos.w;
+
+ return texture(shadowCascades, vec4(shpos.xy, shid * float(MAX_CASCADE_NUM) + cascade, shpos.z));
+}
+
+float light_visibility(LightData ld, vec3 W, vec3 l_vector)
+{
+ float vis = 1.0;
+
+ if (ld.l_type == SPOT) {
+ float z = dot(ld.l_forward, l_vector);
+ vec3 lL = l_vector / z;
+ float x = dot(ld.l_right, lL) / ld.l_sizex;
+ float y = dot(ld.l_up, lL) / ld.l_sizey;
+
+ float ellipse = 1.0 / sqrt(1.0 + x * x + y * y);
+
+ float spotmask = smoothstep(0.0, 1.0, (ellipse - ld.l_spot_size) / ld.l_spot_blend);
+
+ vis *= spotmask;
+ vis *= step(0.0, -dot(l_vector, ld.l_forward));
+ }
+ else if (ld.l_type == AREA) {
+ vis *= step(0.0, -dot(l_vector, ld.l_forward));
+ }
+
+ /* shadowing */
+ if (ld.l_shadowid >= (MAX_SHADOW_MAP + MAX_SHADOW_CUBE)) {
+ vis *= shadow_cascade(ld.l_shadowid, W);
+ }
+ else if (ld.l_shadowid >= 0.0) {
+ vis *= shadow_cubemap(ld.l_shadowid, l_vector, W);
+ }
+
+ return vis;
+}
+
+float light_diffuse(LightData ld, ShadingData sd, vec4 l_vector)
+{
+#ifdef USE_LTC
+ if (ld.l_type == SUN) {
+ /* TODO disk area light */
+ return direct_diffuse_sun(ld, sd);
+ }
+ else if (ld.l_type == AREA) {
+ return direct_diffuse_rectangle(ld, sd, l_vector);
+ }
+ else {
+ return direct_diffuse_sphere(ld, sd, l_vector);
+ }
+#else
+ if (ld.l_type == SUN) {
+ return direct_diffuse_sun(ld, sd);
+ }
+ else {
+ return direct_diffuse_point(sd, l_vector);
+ }
+#endif
+}
+
+vec3 light_specular(LightData ld, ShadingData sd, vec4 l_vector, float roughness, vec3 f0)
+{
+#ifdef USE_LTC
+ if (ld.l_type == SUN) {
+ /* TODO disk area light */
+ return direct_ggx_sun(ld, sd, roughness, f0);
+ }
+ else if (ld.l_type == AREA) {
+ return direct_ggx_rectangle(ld, sd, l_vector, roughness, f0);
+ }
+ else {
+ return direct_ggx_sphere(ld, sd, l_vector, roughness, f0);
+ }
+#else
+ if (ld.l_type == SUN) {
+ return direct_ggx_sun(ld, sd, roughness, f0);
+ }
+ else {
+ return direct_ggx_point(sd, l_vector, roughness, f0);
+ }
+#endif
+}
+
+#ifdef HAIR_SHADER
+void light_hair_common(
+ LightData ld, ShadingData sd, vec4 l_vector, vec3 norm_view,
+ out float occlu_trans, out float occlu,
+ out vec3 norm_lamp, out vec3 view_vec)
+{
+ const float transmission = 0.3; /* Uniform internal scattering factor */
+
+ vec3 lamp_vec;
+
+ if (ld.l_type == SUN || ld.l_type == AREA) {
+ lamp_vec = ld.l_forward;
+ }
+ else {
+ lamp_vec = -l_vector.xyz;
+ }
+
+ norm_lamp = cross(lamp_vec, sd.N);
+ norm_lamp = normalize(cross(sd.N, norm_lamp)); /* Normal facing lamp */
+
+ /* Rotate view vector onto the cross(tangent, light) plane */
+ view_vec = normalize(norm_lamp * dot(norm_view, sd.V) + sd.N * dot(sd.N, sd.V));
+
+ float occlusion = (dot(norm_view, norm_lamp) * 0.5 + 0.5);
+ float occltrans = transmission + (occlusion * (1.0 - transmission)); /* Includes transmission component */
+}
+#endif