[Bf-blender-cvs] [20572497a4d] blender2.8: Eevee: Add parallax correction to probe reflections

Clément Foucault noreply at git.blender.org
Fri Jun 9 23:28:33 CEST 2017


Commit: 20572497a4d2388d8d37663f340ce925ca3caf85
Author: Clément Foucault
Date:   Fri Jun 9 22:30:49 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB20572497a4d2388d8d37663f340ce925ca3caf85

Eevee: Add parallax correction to probe reflections

===================================================================

M	release/scripts/startup/bl_ui/properties_data_probe.py
M	source/blender/blenkernel/intern/probe.c
M	source/blender/draw/engines/eevee/eevee_private.h
M	source/blender/draw/engines/eevee/eevee_probes.c
M	source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
M	source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
M	source/blender/makesdna/DNA_probe_types.h
M	source/blender/makesrna/intern/rna_probe.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_probe.py b/release/scripts/startup/bl_ui/properties_data_probe.py
index b6f4b1ce30d..2f515d71ddf 100644
--- a/release/scripts/startup/bl_ui/properties_data_probe.py
+++ b/release/scripts/startup/bl_ui/properties_data_probe.py
@@ -62,22 +62,61 @@ class DATA_PT_probe(DataButtonsPanel, Panel):
 
         layout.prop(probe, "type", expand=True)
 
-        split = layout.split()
+        layout.label("Influence:")
+        layout.prop(probe, "influence_type", expand=True)
 
-        col = split.column(align=True)
-        col.label("Influence:")
-        col.prop(probe, "influence_distance", text="Distance")
-        col.prop(probe, "falloff")
+        if probe.influence_type == 'ELIPSOID':
+            layout.prop(probe, "influence_distance", "Radius")
+            layout.prop(probe, "falloff")
+        else:
+            split = layout.split()
+            col = split.column(align=True)
+            col.prop(probe, "influence_minimum", text="Min:")
+            col = split.column(align=True)
+            col.prop(probe, "influence_maximum", text="Max:")
 
-        col = split.column(align=True)
-        col.label("Clipping:")
-        col.prop(probe, "clip_start", text="Start")
-        col.prop(probe, "clip_end", text="End")
+            layout.prop(probe, "falloff")
+
+        layout.separator()
+
+        layout.label("Clipping:")
+        row = layout.row(align=True)
+        row.prop(probe, "clip_start", text="Start")
+        row.prop(probe, "clip_end", text="End")
+
+
+class DATA_PT_parallax(DataButtonsPanel, Panel):
+    bl_label = "Parallax"
+    COMPAT_ENGINES = {'BLENDER_CLAY', 'BLENDER_EEVEE'}
+
+    def draw(self, context):
+        layout = self.layout
+
+        ob = context.object
+        probe = context.probe
+
+        layout.prop(probe, "use_custom_parallax")
+
+        col = layout.column()
+        col.active = probe.use_custom_parallax
+
+        row = col.row()
+        row.prop(probe, "parallax_type", expand=True)
+
+        if probe.parallax_type == 'ELIPSOID':
+            col.prop(probe, "parallax_distance", "Radius")
+        else:
+            split = col.split()
+            col = split.column(align=True)
+            col.prop(probe, "parallax_minimum", text="Min:")
+            col = split.column(align=True)
+            col.prop(probe, "parallax_maximum", text="Max:")
 
 
 classes = (
     DATA_PT_context_probe,
     DATA_PT_probe,
+    DATA_PT_parallax,
 )
 
 if __name__ == "__main__":  # only for live edit.
diff --git a/source/blender/blenkernel/intern/probe.c b/source/blender/blenkernel/intern/probe.c
index edceaab1013..c5282e90366 100644
--- a/source/blender/blenkernel/intern/probe.c
+++ b/source/blender/blenkernel/intern/probe.c
@@ -44,12 +44,14 @@ void BKE_probe_init(Probe *probe)
 {
 	BLI_assert(MEMCMP_STRUCT_OFS_IS_ZERO(probe, id));
 
+	probe->distinf = 5.0f;
+	probe->distpar = 5.0f;
 	copy_v3_fl(probe->mininf, -5.0f);
 	copy_v3_fl(probe->maxinf, 5.0f);
 	copy_v3_fl(probe->minpar, -5.0f);
 	copy_v3_fl(probe->maxpar, 5.0f);
 	probe->falloff = 0.25f;
-	probe->clipsta = 0.5f;
+	probe->clipsta = 1.0f;
 	probe->clipend = 40.0f;
 }
 
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index eb89ee999f4..28683b0a40e 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -167,9 +167,13 @@ enum {
 
 /* ************ PROBE UBO ************* */
 typedef struct EEVEE_Probe {
-	float position[3], pad1;
+	float position[3], parallax_type;
 	float shcoefs[9][3], pad2;
-	float attenuation_bias, attenuation_scale, pad3[2];
+	float attenuation_fac;
+	float attenuation_type;
+	float pad3[2];
+	float attenuationmat[4][4];
+	float parallaxmat[4][4];
 } EEVEE_Probe;
 
 /* ************ PROBE DATA ************* */
diff --git a/source/blender/draw/engines/eevee/eevee_probes.c b/source/blender/draw/engines/eevee/eevee_probes.c
index cb20e14fe79..bdddcfffed3 100644
--- a/source/blender/draw/engines/eevee/eevee_probes.c
+++ b/source/blender/draw/engines/eevee/eevee_probes.c
@@ -29,6 +29,8 @@
 #include "DNA_probe_types.h"
 #include "DNA_view3d_types.h"
 
+#include "BKE_object.h"
+
 #include "BLI_dynstr.h"
 
 #include "ED_screen.h"
@@ -277,9 +279,64 @@ static void EEVEE_probes_updates(EEVEE_SceneLayerData *sldata)
 		Probe *probe = (Probe *)ob->data;
 		EEVEE_Probe *eprobe = &pinfo->probe_data[i];
 
-		float dist_minus_falloff = probe->distinf - (1.0f - probe->falloff) * probe->distinf;
-		eprobe->attenuation_bias = probe->distinf / max_ff(1e-8f, dist_minus_falloff);
-		eprobe->attenuation_scale = 1.0f / max_ff(1e-8f, dist_minus_falloff);
+
+		/* Attenuation */
+		eprobe->attenuation_type = probe->attenuation_type;
+		eprobe->attenuation_fac = 1.0f / max_ff(1e-8f, probe->falloff);
+
+		unit_m4(eprobe->attenuationmat);
+		if (probe->attenuation_type == PROBE_BOX) {
+			BoundBox bb;
+			float bb_center[3], bb_size[3];
+
+			BKE_boundbox_init_from_minmax(&bb, probe->mininf, probe->maxinf);
+			BKE_boundbox_calc_center_aabb(&bb, bb_center);
+			BKE_boundbox_calc_size_aabb(&bb, bb_size);
+
+			eprobe->attenuationmat[0][0] = bb_size[0];
+			eprobe->attenuationmat[1][1] = bb_size[1];
+			eprobe->attenuationmat[2][2] = bb_size[2];
+			copy_v3_v3(eprobe->attenuationmat[3], bb_center);
+			mul_m4_m4m4(eprobe->attenuationmat, ob->obmat, eprobe->attenuationmat);
+		}
+		else {
+			scale_m4_fl(eprobe->attenuationmat, probe->distinf);
+			mul_m4_m4m4(eprobe->attenuationmat, ob->obmat, eprobe->attenuationmat);
+		}
+		invert_m4(eprobe->attenuationmat);
+
+		/* Parallax */
+		BoundBox parbb;
+		float dist;
+		if ((probe->flag & PRB_CUSTOM_PARALLAX) != 0) {
+			eprobe->parallax_type = probe->parallax_type;
+			BKE_boundbox_init_from_minmax(&parbb, probe->minpar, probe->maxpar);
+			dist = probe->distpar;
+		}
+		else {
+			eprobe->parallax_type = probe->attenuation_type;
+			BKE_boundbox_init_from_minmax(&parbb, probe->mininf, probe->maxinf);
+			dist = probe->distinf;
+		}
+
+		unit_m4(eprobe->parallaxmat);
+		if (eprobe->parallax_type == PROBE_BOX) {
+			float bb_center[3], bb_size[3];
+
+			BKE_boundbox_calc_center_aabb(&parbb, bb_center);
+			BKE_boundbox_calc_size_aabb(&parbb, bb_size);
+
+			eprobe->parallaxmat[0][0] = bb_size[0];
+			eprobe->parallaxmat[1][1] = bb_size[1];
+			eprobe->parallaxmat[2][2] = bb_size[2];
+			copy_v3_v3(eprobe->parallaxmat[3], bb_center);
+			mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat);
+		}
+		else {
+			scale_m4_fl(eprobe->parallaxmat, dist);
+			mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat);
+		}
+		invert_m4(eprobe->parallaxmat);
 	}
 }
 
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index 124f1e2bdb5..4aa97780637 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -10,15 +10,22 @@
 /* ------- Structures -------- */
 
 struct ProbeData {
-	vec4 position;
+	vec4 position_type;
 	vec4 shcoefs[7];
-	vec4 attenuation;
+	vec4 attenuation_fac_type;
+	mat4 influencemat;
+	mat4 parallaxmat;
 };
 
+#define PROBE_PARALLAX_BOX    1.0
+#define PROBE_ATTENUATION_BOX 1.0
 
-#define p_position     position.xyz
-#define p_atten_bias   attenuation.x
-#define p_atten_scale  attenuation.y
+#define p_position      position_type.xyz
+#define p_parallax_type position_type.w
+#define p_atten_fac     attenuation_fac_type.x
+#define p_atten_type    attenuation_fac_type.y
+
+/* TODO remove sh once we have irradiance grid */
 #define shcoef0        shcoefs[0].rgb
 #define shcoef1        vec3(shcoefs[0].a, shcoefs[1].rg)
 #define shcoef2        vec3(shcoefs[1].ba, shcoefs[2].r)
@@ -99,6 +106,8 @@ struct ShadingData {
 vec3 mul(mat3 m, vec3 v) { return m * v; }
 mat3 mul(mat3 m1, mat3 m2) { return m1 * m2; }
 
+float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
+
 float saturate(float a) { return clamp(a, 0.0, 1.0); }
 vec2 saturate(vec2 a) { return clamp(a, 0.0, 1.0); }
 vec3 saturate(vec3 a) { return clamp(a, 0.0, 1.0); }
@@ -140,6 +149,31 @@ vec3 line_aligned_plane_intersect(vec3 lineorigin, vec3 linedirection, vec3 plan
 	return lineorigin + linedirection * dist;
 }
 
+float line_unit_sphere_intersect_dist(vec3 lineorigin, vec3 linedirection)
+{
+	float a = dot(linedirection, linedirection);
+	float b = dot(linedirection, lineorigin);
+	float c = dot(lineorigin, lineorigin) - 1;
+
+	float dist = 1e15;
+	float determinant = b * b - a * c;
+	if (determinant >= 0)
+		dist = (sqrt(determinant) - b) / a;
+
+	return dist;
+}
+
+float line_unit_box_intersect_dist(vec3 lineorigin, vec3 linedirection)
+{
+	/* https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ */
+	vec3 firstplane  = (vec3( 1.0) - lineorigin) / linedirection;
+	vec3 secondplane = (vec3(-1.0) - lineorigin) / linedirection;
+	vec3 furthestplane = max(firstplane, secondplane);
+
+	return min_v3(furthestplane);
+}
+
+
 /* Return texture coordinates to sample Surface LUT */
 vec2 lut_coords(float cosTheta, float roughness)
 {
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 83bcd919697..e2d92a31f72 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -198,12 +198,52 @@ void light_visibility(LightData ld, ShadingData sd, out float vis)
 
 vec3 probe_parallax_correction(vec3 W, vec3 spec_dir, ProbeData pd, inout float roughness)
 {
-	/* TODO */
-	return spec_dir;
+	vec3 localpos = (pd.parallaxmat * vec4(W, 1.0)).xyz;
+	vec3 localray = (pd.parallaxmat * vec4(spec_dir, 0.0)).xyz;
+
+	float dist;
+	if (pd.p_parallax_type == PROBE_PARALLAX_BOX) {
+		dist = line_unit_box_intersect_dist(localpos, localray);
+	}
+	else {
+		dist = line_unit_sphere_intersect_dist(localpos, localray);
+	}
+
+	/* Use Distance in WS directly to recover intersection */
+	vec3 intersection = W + spec_dir * dist - pd.p_position;
+
+	/* From Frostbite PBR

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list