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:
authorBrecht Van Lommel <brecht@blender.org>2021-02-12 17:22:21 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-02-12 17:22:21 +0300
commitdad32cbd17790cbd6d8fd30758a69315274fbb24 (patch)
treedf77bfd23bae33ae06f06135df1affbb2588ebcc
parent7db00556fa9a14f8617c2ec1e35ae834689f0da7 (diff)
parent9febda912b04559277d465b9610334c04a73d2ce (diff)
Merge branch 'blender-v2.92-release'
-rw-r--r--intern/cycles/kernel/kernel_bake.h3
-rw-r--r--source/blender/editors/object/object_bake_api.c90
-rw-r--r--source/blender/render/RE_bake.h1
-rw-r--r--source/blender/render/intern/bake.c3
-rw-r--r--source/blender/render/intern/engine.c2
5 files changed, 66 insertions, 33 deletions
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index ddcf94be1de..ded914c05d7 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -233,6 +233,7 @@ ccl_device void kernel_bake_evaluate(
ccl_global float *differential = buffer + kernel_data.film.pass_bake_differential;
ccl_global float *output = buffer + kernel_data.film.pass_combined;
+ int seed = __float_as_uint(primitive[0]);
int prim = __float_as_uint(primitive[1]);
if (prim == -1)
return;
@@ -240,7 +241,7 @@ ccl_device void kernel_bake_evaluate(
prim += kernel_data.bake.tri_offset;
/* Random number generator. */
- uint rng_hash = hash_uint2(x, y) ^ kernel_data.integrator.seed;
+ uint rng_hash = hash_uint(seed) ^ kernel_data.integrator.seed;
int num_samples = kernel_data.integrator.aa_samples;
float filter_x, filter_y;
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index b1ba856ff0f..9ec0c625f71 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -44,6 +44,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mesh.h"
+#include "BKE_mesh_mapping.h"
#include "BKE_modifier.h"
#include "BKE_node.h"
#include "BKE_object.h"
@@ -946,7 +947,7 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re
targets->num_materials = ob->totcol;
BakeImage *bk_image = &targets->images[0];
- bk_image->width = me->totvert;
+ bk_image->width = me->totloop;
bk_image->height = 1;
bk_image->offset = 0;
bk_image->image = NULL;
@@ -968,6 +969,7 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
pixel->primitive_id = -1;
pixel->object_id = 0;
+ pixel->seed = 0;
pixel->du_dx = 0.0f;
pixel->du_dy = 0.0f;
pixel->dv_dx = 0.0f;
@@ -986,8 +988,8 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
const MLoopTri *lt = &looptri[i];
for (int j = 0; j < 3; j++) {
- const unsigned int v = me->mloop[lt->tri[j]].v;
- BakePixel *pixel = &pixel_array[v];
+ const unsigned int l = lt->tri[j];
+ BakePixel *pixel = &pixel_array[l];
if (pixel->primitive_id != -1) {
continue;
@@ -995,6 +997,11 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
pixel->primitive_id = i;
+ /* Seed is the vertex, so that sampling noise is coherent for the same
+ * vertex, but different corners can still have different normals,
+ * materials and UVs. */
+ pixel->seed = me->mloop[l].v;
+
/* Barycentric coordinates, nudged a bit to avoid precision issues that
* may happen when exactly at the vertex coordinate. */
if (j == 0) {
@@ -1015,24 +1022,24 @@ static void bake_targets_populate_pixels_vertex_colors(BakeTargets *targets,
MEM_freeN(looptri);
}
-static void bake_result_to_rgba(float rgba[4], const float *result, const int num_channels)
+static void bake_result_add_to_rgba(float rgba[4], const float *result, const int num_channels)
{
if (num_channels == 4) {
- copy_v4_v4(rgba, result);
+ add_v4_v4(rgba, result);
}
else if (num_channels == 3) {
- copy_v3_v3(rgba, result);
- rgba[3] = 1.0f;
+ add_v3_v3(rgba, result);
+ rgba[3] += 1.0f;
}
else {
- rgba[0] = result[0];
- rgba[1] = result[0];
- rgba[2] = result[0];
- rgba[3] = 1.0f;
+ rgba[0] += result[0];
+ rgba[1] += result[0];
+ rgba[2] += result[0];
+ rgba[3] += 1.0f;
}
}
-static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
+static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob, Mesh *me_split)
{
Mesh *me = ob->data;
MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR);
@@ -1040,26 +1047,45 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
const int num_channels = targets->num_channels;
const float *result = targets->result;
+ /* We bake using a mesh with additional vertices for split normals, but the
+ * number of loops must match to be able to transfer the vertex colors. */
+ BLI_assert(me->totloop == me_split->totloop);
+ UNUSED_VARS_NDEBUG(me_split);
+
if (mcol) {
- /* Float vertex colors in scene linear color space. */
const int totvert = me->totvert;
- for (int i = 0; i < totvert; i++, mcol++) {
- bake_result_to_rgba(mcol->color, &result[i * num_channels], num_channels);
+ const int totloop = me->totloop;
+
+ /* Accumulate float vertex colors in scene linear color space. */
+ int *num_loops_for_vertex = MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex");
+ memset(mcol, 0, sizeof(MPropCol) * me->totvert);
+
+ MLoop *mloop = me->mloop;
+ for (int i = 0; i < totloop; i++, mloop++) {
+ const int v = mloop->v;
+ bake_result_add_to_rgba(mcol[v].color, &result[i * num_channels], num_channels);
+ num_loops_for_vertex[v]++;
}
+
+ /* Normalize for number of loops. */
+ for (int i = 0; i < totvert; i++) {
+ if (num_loops_for_vertex[i] > 0) {
+ mul_v4_fl(mcol[i].color, 1.0f / num_loops_for_vertex[i]);
+ }
+ }
+
+ MEM_SAFE_FREE(num_loops_for_vertex);
}
else {
- /* Byte loop colors in sRGB colors space.
- *
- * Note that colors have been baked per vertex and not per corner, which
- * could be useful to preserve material discontinuities. However this also
- * leads to unintended discontinuities due to sampling noise. */
+ /* Byte loop colors in sRGB colors space. */
MLoop *mloop = me->mloop;
const int totloop = me->totloop;
const bool is_noncolor = targets->is_noncolor;
for (int i = 0; i < totloop; i++, mloop++, mloopcol++) {
float rgba[4];
- bake_result_to_rgba(rgba, &result[mloop->v * num_channels], num_channels);
+ zero_v4(rgba);
+ bake_result_add_to_rgba(rgba, &result[i * num_channels], num_channels);
if (is_noncolor) {
unit_float_to_uchar_clamp_v4(&mloopcol->r, rgba);
@@ -1142,7 +1168,7 @@ static bool bake_targets_output(const BakeAPIRender *bkr,
}
}
else if (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) {
- return bake_targets_output_vertex_colors(targets, ob);
+ return bake_targets_output_vertex_colors(targets, ob, me);
}
return false;
@@ -1212,10 +1238,6 @@ static int bake(const BakeAPIRender *bkr,
}
}
- if (!bake_targets_init(bkr, &targets, ob_low, reports)) {
- goto cleanup;
- }
-
if (bkr->is_selected_to_active) {
CollectionPointerLink *link;
tot_highpoly = 0;
@@ -1245,9 +1267,6 @@ static int bake(const BakeAPIRender *bkr,
}
}
- pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels, "bake pixels low poly");
- pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels, "bake pixels high poly");
-
/* for multires bake, use linear UV subdivision to match low res UVs */
if (bkr->pass_type == SCE_PASS_NORMAL && bkr->normal_space == R_BAKE_SPACE_TANGENT &&
!bkr->is_selected_to_active) {
@@ -1265,11 +1284,17 @@ static int bake(const BakeAPIRender *bkr,
/* get the mesh as it arrives in the renderer */
me_low = bake_mesh_new_from_object(ob_low_eval);
- /* populate the pixel array with the face data */
+ /* Initialize bake targets. */
+ if (!bake_targets_init(bkr, &targets, ob_low_eval, reports)) {
+ goto cleanup;
+ }
+
+ /* Populate the pixel array with the face data. Except if we use a cage, then
+ * it is populated later with the cage mesh (smoothed version of the mesh). */
+ pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels, "bake pixels low poly");
if ((bkr->is_selected_to_active && (ob_cage == NULL) && bkr->is_cage) == false) {
bake_targets_populate_pixels(bkr, &targets, me_low, pixel_array_low);
}
- /* else populate the pixel array with the 'cage' mesh (the smooth version of the mesh) */
if (bkr->is_selected_to_active) {
CollectionPointerLink *link;
@@ -1358,6 +1383,9 @@ static int bake(const BakeAPIRender *bkr,
ob_low_eval->base_flag &= ~(BASE_VISIBLE_DEPSGRAPH | BASE_ENABLED_RENDER);
/* populate the pixel arrays with the corresponding face data for each high poly object */
+ pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.num_pixels,
+ "bake pixels high poly");
+
if (!RE_bake_pixels_populate_from_objects(me_low,
pixel_array_low,
pixel_array_high,
diff --git a/source/blender/render/RE_bake.h b/source/blender/render/RE_bake.h
index 3463362adb1..bb30b524b61 100644
--- a/source/blender/render/RE_bake.h
+++ b/source/blender/render/RE_bake.h
@@ -59,6 +59,7 @@ typedef struct BakeTargets {
typedef struct BakePixel {
int primitive_id, object_id;
+ int seed;
float uv[2];
float du_dx, du_dy;
float dv_dx, dv_dy;
diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c
index caf81870fac..7af6d3e234f 100644
--- a/source/blender/render/intern/bake.c
+++ b/source/blender/render/intern/bake.c
@@ -135,6 +135,7 @@ static void store_bake_pixel(void *handle, int x, int y, float u, float v)
pixel->dv_dx = bd->dv_dx;
pixel->dv_dy = bd->dv_dy;
pixel->object_id = 0;
+ pixel->seed = i;
}
void RE_bake_mask_fill(const BakePixel pixel_array[], const size_t num_pixels, char *mask)
@@ -383,6 +384,7 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData,
pixel_high->primitive_id = primitive_id_high;
pixel_high->object_id = hit_mesh;
+ pixel_high->seed = pixel_id;
/* ray direction in high poly object space */
float dir_high[3];
@@ -434,6 +436,7 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData,
else {
pixel_array[pixel_id].primitive_id = -1;
pixel_array[pixel_id].object_id = -1;
+ pixel_array[pixel_id].seed = 0;
}
MEM_freeN(hits);
diff --git a/source/blender/render/intern/engine.c b/source/blender/render/intern/engine.c
index 151d994dddf..b199b1b0743 100644
--- a/source/blender/render/intern/engine.c
+++ b/source/blender/render/intern/engine.c
@@ -194,7 +194,7 @@ static RenderResult *render_result_from_bake(RenderEngine *engine, int x, int y,
primitive[1] = int_as_float(-1);
}
else {
- primitive[0] = int_as_float(bake_pixel->object_id);
+ primitive[0] = int_as_float(bake_pixel->seed);
primitive[1] = int_as_float(bake_pixel->primitive_id);
primitive[2] = bake_pixel->uv[0];
primitive[3] = bake_pixel->uv[1];