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:
authorPhoenix Katsch <phoenixkatsch>2022-10-03 20:26:02 +0300
committerBrecht Van Lommel <brecht@blender.org>2022-10-03 22:59:31 +0300
commitb475506cfbd35fe2d356ce43a6a3e1f93bd6602b (patch)
tree030ef0c4eafbb9443ae5c6ed9b8d105dd5a82974 /intern/cycles/kernel
parentaf51e4b41c9e591bd0640623d5314508f8e6a8ea (diff)
Cycles: add option to bake specular from active camera viewpoint
Previously it would bake viewed from above the surface. The new option can be useful when the baked result is meant to be viewed from a fixed viewpoint or with limited camera motion. Some effort is made to give a continuous reflection on parts of the surface invisible to the camera, but this is necessarily only a rough approximation. Differential Revision: https://developer.blender.org/D15921
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/integrator/init_from_bake.h47
-rw-r--r--intern/cycles/kernel/types.h2
2 files changed, 46 insertions, 3 deletions
diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h
index eca2c0b9ffb..15968670ac2 100644
--- a/intern/cycles/kernel/integrator/init_from_bake.h
+++ b/intern/cycles/kernel/integrator/init_from_bake.h
@@ -210,8 +210,51 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
/* Setup ray. */
Ray ray ccl_optional_struct_init;
- ray.P = P + N;
- ray.D = -N;
+
+ if (kernel_data.bake.use_camera) {
+ float3 D = camera_direction_from_point(kg, P);
+
+ const float DN = dot(D, N);
+
+ /* Nudge camera direction, so that the faces facing away from the camera still have
+ * somewhat usable shading. (Otherwise, glossy faces would be simply black.)
+ *
+ * The surface normal offset affects smooth surfaces. Lower values will make
+ * smooth surfaces more faceted, but higher values may show up from the camera
+ * at grazing angles.
+ *
+ * This value can actually be pretty high before it's noticeably wrong. */
+ const float surface_normal_offset = 0.2f;
+
+ /* Keep the ray direction at least `surface_normal_offset` "above" the smooth normal. */
+ if (DN <= surface_normal_offset) {
+ D -= N * (DN - surface_normal_offset);
+ D = normalize(D);
+ }
+
+ /* On the backside, just lerp towards the surface normal for the ray direction,
+ * as DN goes from 0.0 to -1.0. */
+ if (DN <= 0.0f) {
+ D = normalize(mix(D, N, -DN));
+ }
+
+ /* We don't want to bake the back face, so make sure the ray direction never
+ * goes behind the geometry (flat) normal. This is a failsafe, and should rarely happen. */
+ const float true_normal_epsilon = 0.00001f;
+
+ if (dot(D, Ng) <= true_normal_epsilon) {
+ D -= Ng * (dot(D, Ng) - true_normal_epsilon);
+ D = normalize(D);
+ }
+
+ ray.P = P + D;
+ ray.D = -D;
+ }
+ else {
+ ray.P = P + N;
+ ray.D = -N;
+ }
+
ray.tmin = 0.0f;
ray.tmax = FLT_MAX;
ray.time = 0.5f;
diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h
index f81e7843629..1469d915d15 100644
--- a/intern/cycles/kernel/types.h
+++ b/intern/cycles/kernel/types.h
@@ -1160,7 +1160,7 @@ typedef struct KernelBake {
int use;
int object_index;
int tri_offset;
- int pad1;
+ int use_camera;
} KernelBake;
static_assert_align(KernelBake, 16);