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:
-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
-rw-r--r--source/blender/makesdna/DNA_scene_types.h9
-rw-r--r--source/blender/makesrna/intern/rna_scene.c19
8 files changed, 99 insertions, 4 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
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 80b1049ca23..2db81693f51 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -559,7 +559,8 @@ typedef struct BakeData {
char target;
char save_mode;
char margin_type;
- char _pad[5];
+ char view_from;
+ char _pad[4];
struct Object *cage_object;
} BakeData;
@@ -592,6 +593,12 @@ typedef enum eBakeSaveMode {
R_BAKE_SAVE_EXTERNAL = 1,
} eBakeSaveMode;
+/** #BakeData.view_from (char) */
+typedef enum eBakeViewFrom {
+ R_BAKE_VIEW_FROM_ABOVE_SURFACE = 0,
+ R_BAKE_VIEW_FROM_ACTIVE_CAMERA = 1,
+} eBakeViewFrom;
+
/** #BakeData.pass_filter */
typedef enum eBakePassFilter {
R_BAKE_PASS_FILTER_NONE = 0,
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index da30b7f2136..fdf8be9cb33 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -476,6 +476,20 @@ const EnumPropertyItem rna_enum_bake_save_mode_items[] = {
{0, NULL, 0, NULL, NULL},
};
+const EnumPropertyItem rna_enum_bake_view_from_items[] = {
+ {R_BAKE_VIEW_FROM_ABOVE_SURFACE,
+ "ABOVE_SURFACE",
+ 0,
+ "Above Surface",
+ "Cast rays from above the surface"},
+ {R_BAKE_VIEW_FROM_ACTIVE_CAMERA,
+ "ACTIVE_CAMERA",
+ 0,
+ "Active Camera",
+ "Use the active camera's position to cast rays"},
+ {0, NULL, 0, NULL, NULL},
+};
+
#define R_IMF_VIEWS_ENUM_IND \
{R_IMF_VIEWS_INDIVIDUAL, \
"INDIVIDUAL", \
@@ -5413,6 +5427,11 @@ static void rna_def_bake_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Save Mode", "Where to save baked image textures");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ prop = RNA_def_property(srna, "view_from", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, rna_enum_bake_view_from_items);
+ RNA_def_property_ui_text(prop, "View From", "Source of reflection ray directions");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
/* flags */
prop = RNA_def_property(srna, "use_selected_to_active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", R_BAKE_TO_ACTIVE);