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
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')
-rw-r--r--intern/cycles/blender/addon/ui.py6
-rw-r--r--intern/cycles/blender/camera.cpp6
-rw-r--r--intern/cycles/kernel/integrator/init_from_bake.h47
-rw-r--r--intern/cycles/kernel/types.h2
-rw-r--r--intern/cycles/scene/bake.cpp11
-rw-r--r--intern/cycles/scene/bake.h3
6 files changed, 72 insertions, 3 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 7036e58f6fb..f763fe0eb0b 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1880,6 +1880,12 @@ class CYCLES_RENDER_PT_bake(CyclesButtonsPanel, Panel):
layout.prop(rd, "use_bake_multires")
layout.prop(cscene, "bake_type")
+ if not rd.use_bake_multires and cscene.bake_type not in {
+ "AO", "POSITION", "NORMAL", "UV", "ROUGHNESS", "ENVIRONMENT"}:
+ row = layout.row()
+ row.prop(cbk, "view_from")
+ row.active = scene.camera is not None
+
class CYCLES_RENDER_PT_bake_influence(CyclesButtonsPanel, Panel):
bl_label = "Influence"
diff --git a/intern/cycles/blender/camera.cpp b/intern/cycles/blender/camera.cpp
index 6926c833096..d7def9fdb7c 100644
--- a/intern/cycles/blender/camera.cpp
+++ b/intern/cycles/blender/camera.cpp
@@ -2,6 +2,7 @@
* Copyright 2011-2022 Blender Foundation */
#include "scene/camera.h"
+#include "scene/bake.h"
#include "scene/scene.h"
#include "blender/sync.h"
@@ -592,6 +593,11 @@ void BlenderSync::sync_camera(BL::RenderSettings &b_render,
blender_camera_from_object(&bcam, b_engine, b_ob);
b_engine.camera_model_matrix(b_ob, bcam.use_spherical_stereo, b_ob_matrix);
bcam.matrix = get_transform(b_ob_matrix);
+ scene->bake_manager->set_use_camera(b_render.bake().view_from() ==
+ BL::BakeSettings::view_from_ACTIVE_CAMERA);
+ }
+ else {
+ scene->bake_manager->set_use_camera(false);
}
/* sync */
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);
diff --git a/intern/cycles/scene/bake.cpp b/intern/cycles/scene/bake.cpp
index 1947b9d71a4..768e723b587 100644
--- a/intern/cycles/scene/bake.cpp
+++ b/intern/cycles/scene/bake.cpp
@@ -16,6 +16,7 @@ CCL_NAMESPACE_BEGIN
BakeManager::BakeManager()
{
need_update_ = true;
+ use_camera_ = false;
}
BakeManager::~BakeManager()
@@ -38,6 +39,14 @@ void BakeManager::set(Scene *scene, const std::string &object_name_)
need_update_ = true;
}
+void BakeManager::set_use_camera(const bool use_camera)
+{
+ if (use_camera_ != use_camera) {
+ use_camera_ = use_camera;
+ need_update_ = true;
+ }
+}
+
void BakeManager::device_update(Device * /*device*/,
DeviceScene *dscene,
Scene *scene,
@@ -49,6 +58,8 @@ void BakeManager::device_update(Device * /*device*/,
KernelBake *kbake = &dscene->data.bake;
memset(kbake, 0, sizeof(*kbake));
+ kbake->use_camera = use_camera_;
+
if (!object_name.empty()) {
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
diff --git a/intern/cycles/scene/bake.h b/intern/cycles/scene/bake.h
index 0d90ece5628..e3f3911ab05 100644
--- a/intern/cycles/scene/bake.h
+++ b/intern/cycles/scene/bake.h
@@ -20,6 +20,8 @@ class BakeManager {
void set(Scene *scene, const std::string &object_name);
bool get_baking() const;
+ void set_use_camera(bool use_camera);
+
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene);
@@ -30,6 +32,7 @@ class BakeManager {
private:
bool need_update_;
std::string object_name;
+ bool use_camera_;
};
CCL_NAMESPACE_END