[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