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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h3
-rw-r--r--source/blender/render/intern/source/multires_bake.c149
-rw-r--r--source/blender/render/intern/source/rendercore.c49
3 files changed, 90 insertions, 111 deletions
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index 8818aa67c32..d686de21517 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -186,7 +186,6 @@ typedef struct ShadeInput {
typedef struct BakeImBufuserData {
float *displacement_buffer;
- float displacement_min, displacement_max;
char *mask_buffer;
} BakeImBufuserData;
@@ -212,7 +211,7 @@ struct Object;
int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob, short *do_update, float *progress);
struct Image *RE_bake_shade_get_image(void);
void RE_bake_ibuf_filter(struct ImBuf *ibuf, char *mask, const int filter);
-void RE_bake_ibuf_normalize_displacement(struct ImBuf *ibuf, float *displacement, char *mask, float global_displacement_min, float global_displacement_max);
+void RE_bake_ibuf_normalize_displacement(struct ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max);
#define BAKE_RESULT_OK 0
#define BAKE_RESULT_NO_OBJECTS 1
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index a86c78ce259..13c9e6e88bd 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -60,14 +60,17 @@
#include "rayobject.h"
#include "rendercore.h"
-typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float tangmat[3][3], const int x, const int y);
+typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *thread_data,
+ void *bake_data, ImBuf *ibuf, const int face_index, const int lvl,
+ const float st[2], float tangmat[3][3], const int x, const int y);
typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
-typedef void (*MApplyBakeData)(void *bake_data);
typedef void (*MFreeBakeData)(void *bake_data);
+typedef struct MultiresBakeResult {
+ float height_min, height_max;
+} MultiresBakeResult;
+
typedef struct {
MVert *mvert;
MFace *mface;
@@ -79,6 +82,7 @@ typedef struct {
int i0, i1, i2;
DerivedMesh *lores_dm, *hires_dm;
int lvl;
+ void *thread_data;
void *bake_data;
ImBuf *ibuf;
MPassKnownData pass_data;
@@ -95,7 +99,6 @@ typedef struct {
typedef struct {
float *heights;
- float height_min, height_max;
Image *ima;
DerivedMesh *ssdm;
const int *orig_index_mf_to_mpoly;
@@ -161,9 +164,11 @@ static void multiresbake_get_normal(const MResolvePixelData *data, float norm[],
static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
{
+ BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata;
+
memset(bake_rast, 0, sizeof(MBakeRast));
- bake_rast->texels = ibuf->userdata;
+ bake_rast->texels = userdata->mask_buffer;
bake_rast->w = ibuf->x;
bake_rast->h = ibuf->y;
bake_rast->data = data;
@@ -222,7 +227,7 @@ static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
zero_m3(to_tang);
}
- data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
+ data->pass_data(data->lores_dm, data->hires_dm, data->thread_data, data->bake_data,
data->ibuf, data->face_index, data->lvl, st, to_tang, x, y);
}
@@ -348,6 +353,9 @@ typedef struct MultiresBakeThread {
/* thread-specific data */
MBakeRast bake_rast;
MResolvePixelData data;
+
+ /* displacement-specific data */
+ float height_min, height_max;
} MultiresBakeThread;
static int multires_bake_queue_next_face(MultiresBakeQueue *queue)
@@ -450,7 +458,7 @@ static void init_ccgdm_arrays(DerivedMesh *dm)
}
static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_tangent, MPassKnownData passKnownData,
- MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
+ MInitBakeData initBakeData, MFreeBakeData freeBakeData, MultiresBakeResult *result)
{
DerivedMesh *dm = bkr->lores_dm;
const int lvl = bkr->lvl;
@@ -514,9 +522,13 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_ta
handle->data.hires_dm = bkr->hires_dm;
handle->data.lvl = lvl;
handle->data.pass_data = passKnownData;
+ handle->data.thread_data = handle;
handle->data.bake_data = bake_data;
handle->data.ibuf = ibuf;
+ handle->height_min = FLT_MAX;
+ handle->height_max = -FLT_MAX;
+
init_bake_rast(&handle->bake_rast, ibuf, &handle->data, flush_pixel);
if (tot_thread > 1)
@@ -529,12 +541,18 @@ static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, int require_ta
else
do_multires_bake_thread(&handles[0]);
+ /* construct bake result */
+ result->height_min = handles[0].height_min;
+ result->height_max = handles[0].height_max;
+
+ for (i = 1; i < tot_thread; i++) {
+ result->height_min = min_ff(result->height_min, handles[i].height_min);
+ result->height_max = max_ff(result->height_max, handles[i].height_max);
+ }
+
BLI_spin_end(&queue.spin);
/* finalize baking */
- if (applyBakeData)
- applyBakeData(bake_data);
-
if (freeBakeData)
freeBakeData(bake_data);
@@ -676,13 +694,15 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
MHeightBakeData *height_data;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
DerivedMesh *lodm = bkr->lores_dm;
+ BakeImBufuserData *userdata = ibuf->userdata;
+
+ if (userdata->displacement_buffer == NULL)
+ userdata->displacement_buffer = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights");
height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
height_data->ima = ima;
- height_data->heights = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights");
- height_data->height_max = -FLT_MAX;
- height_data->height_min = FLT_MAX;
+ height_data->heights = userdata->displacement_buffer;
if (!bkr->use_lores_mesh) {
SubsurfModifierData smd = {{NULL}};
@@ -710,48 +730,6 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
return (void *)height_data;
}
-static void apply_heights_data(void *bake_data)
-{
- MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL);
- int x, y, i;
- float height, *heights = height_data->heights;
- float min = height_data->height_min, max = height_data->height_max;
-
- for (x = 0; x < ibuf->x; x++) {
- for (y = 0; y < ibuf->y; y++) {
- i = ibuf->x * y + x;
-
- if (((char *)ibuf->userdata)[i] != FILTER_MASK_USED)
- continue;
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + i * 4;
-
- if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
- else height = 0;
-
- rrgbf[0] = rrgbf[1] = rrgbf[2] = height;
- }
- else {
- char *rrgb = (char *)ibuf->rect + i * 4;
-
- if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
- else height = 0;
-
- rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(height);
- }
- }
- }
-
- if (ibuf->rect_float)
- ibuf->userflags |= IB_RECT_INVALID;
-
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
-
- BKE_image_release_ibuf(height_data->ima, ibuf, NULL);
-}
-
static void free_heights_data(void *bake_data)
{
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
@@ -759,7 +737,6 @@ static void free_heights_data(void *bake_data)
if (height_data->ssdm)
height_data->ssdm->release(height_data->ssdm);
- MEM_freeN(height_data->heights);
MEM_freeN(height_data);
}
@@ -769,13 +746,14 @@ static void free_heights_data(void *bake_data)
* - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
* mesh to make texture smoother) let's call this point p0 and n.
* - height wound be dot(n, p1-p0) */
-static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
+static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *thread_data_v, void *bake_data,
ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
float UNUSED(tangmat[3][3]), const int x, const int y)
{
MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
MFace mface;
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
+ MultiresBakeThread *thread_data = (MultiresBakeThread *) thread_data_v;
float uv[2], *st0, *st1, *st2, *st3;
int pixel = ibuf->x * y + x;
float vec[3], p0[3], p1[3], n[3], len;
@@ -822,15 +800,18 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm,
len = dot_v3v3(n, vec);
height_data->heights[pixel] = len;
- if (len < height_data->height_min) height_data->height_min = len;
- if (len > height_data->height_max) height_data->height_max = len;
+
+ thread_data->height_min = min_ff(thread_data->height_min, len);
+ thread_data->height_max = max_ff(thread_data->height_max, len);
if (ibuf->rect_float) {
float *rrgbf = ibuf->rect_float + pixel * 4;
+ rrgbf[0] = rrgbf[1] = rrgbf[2] = len;
rrgbf[3] = 1.0f;
}
else {
char *rrgb = (char *)ibuf->rect + pixel * 4;
+ rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(len);
rrgb[3] = 255;
}
}
@@ -862,9 +843,9 @@ static void free_normal_data(void *bake_data)
* - find coord and normal of point with specified UV in hi-res mesh
* - multiply it by tangmat
* - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
-static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float tangmat[3][3], const int x, const int y)
+static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *UNUSED(thread_data),
+ void *bake_data, ImBuf *ibuf, const int face_index, const int lvl,
+ const float st[2], float tangmat[3][3], const int x, const int y)
{
MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
MFace mface;
@@ -1099,9 +1080,9 @@ static int trace_ao_ray(MAOBakeData *ao_data, float ray_start[3], float ray_dire
return RE_rayobject_raycast(ao_data->raytree, &isect);
}
-static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
- ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
- float UNUSED(tangmat[3][3]), const int x, const int y)
+static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void *UNUSED(thread_data),
+ void *bake_data, ImBuf *ibuf, const int face_index, const int lvl,
+ const float st[2], float UNUSED(tangmat[3][3]), const int x, const int y)
{
MAOBakeData *ao_data = (MAOBakeData *) bake_data;
MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
@@ -1231,7 +1212,7 @@ static void count_images(MultiresBakeRender *bkr)
mtface[a].tpage->id.flag &= ~LIB_DOIT;
}
-static void bake_images(MultiresBakeRender *bkr)
+static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
{
LinkData *link;
@@ -1240,18 +1221,19 @@ static void bake_images(MultiresBakeRender *bkr)
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf->x > 0 && ibuf->y > 0) {
- ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
+ BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData), "MultiresBake userdata");
+ userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
+ ibuf->userdata = userdata;
switch (bkr->mode) {
case RE_BAKE_NORMALS:
- do_multires_bake(bkr, ima, TRUE, apply_tangmat_callback, init_normal_data, NULL, free_normal_data);
+ do_multires_bake(bkr, ima, TRUE, apply_tangmat_callback, init_normal_data, free_normal_data, result);
break;
case RE_BAKE_DISPLACEMENT:
- do_multires_bake(bkr, ima, FALSE, apply_heights_callback, init_heights_data,
- apply_heights_data, free_heights_data);
+ do_multires_bake(bkr, ima, FALSE, apply_heights_callback, init_heights_data, free_heights_data, result);
break;
case RE_BAKE_AO:
- do_multires_bake(bkr, ima, FALSE, apply_ao_callback, init_ao_data, NULL, free_ao_data);
+ do_multires_bake(bkr, ima, FALSE, apply_ao_callback, init_ao_data, free_ao_data, result);
break;
}
}
@@ -1262,18 +1244,25 @@ static void bake_images(MultiresBakeRender *bkr)
}
}
-static void finish_images(MultiresBakeRender *bkr)
+static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
{
LinkData *link;
+ int use_displacement_buffer = bkr->mode == RE_BAKE_DISPLACEMENT;
for (link = bkr->image.first; link; link = link->next) {
Image *ima = (Image *)link->data;
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+ BakeImBufuserData *userdata = (BakeImBufuserData *) ibuf->userdata;
if (ibuf->x <= 0 || ibuf->y <= 0)
continue;
- RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);
+ RE_bake_ibuf_filter(ibuf, userdata->mask_buffer, bkr->bake_filter);
+
+ if (use_displacement_buffer) {
+ RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
+ result->height_min, result->height_max);
+ }
ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
@@ -1286,7 +1275,11 @@ static void finish_images(MultiresBakeRender *bkr)
}
if (ibuf->userdata) {
- MEM_freeN(ibuf->userdata);
+ if (userdata->displacement_buffer)
+ MEM_freeN(userdata->displacement_buffer);
+
+ MEM_freeN(userdata->mask_buffer);
+ MEM_freeN(userdata);
ibuf->userdata = NULL;
}
@@ -1296,7 +1289,9 @@ static void finish_images(MultiresBakeRender *bkr)
void RE_multires_bake_images(MultiresBakeRender *bkr)
{
+ MultiresBakeResult result;
+
count_images(bkr);
- bake_images(bkr);
- finish_images(bkr);
+ bake_images(bkr, &result);
+ finish_images(bkr, &result);
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index e4e6c9f7594..acb4fe062cf 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -2020,7 +2020,7 @@ typedef struct BakeShade {
/* displacement buffer used for normalization with unknown maximal distance */
int use_displacement_buffer;
float *displacement_buffer;
- float *displacement_min, *displacement_max;
+ float displacement_min, displacement_max;
int use_mask;
char *rect_mask; /* bake pixel mask */
@@ -2270,8 +2270,8 @@ static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist,
if (bs->displacement_buffer) {
float *displacement = bs->displacement_buffer + (bs->rectx * y + x);
*displacement = disp;
- *bs->displacement_min = min_ff(*bs->displacement_min, disp);
- *bs->displacement_max = max_ff(*bs->displacement_max, disp);
+ bs->displacement_min = min_ff(bs->displacement_min, disp);
+ bs->displacement_max = max_ff(bs->displacement_max, disp);
}
if (bs->rect_float && !bs->vcol) {
@@ -2670,8 +2670,8 @@ static void shade_verts(BakeShade *bs)
bs->rect = NULL;
bs->rect_float = NULL;
bs->displacement_buffer = NULL;
- bs->displacement_min = NULL;
- bs->displacement_max = NULL;
+ bs->displacement_min = FLT_MAX;
+ bs->displacement_max = -FLT_MAX;
bs->quad = 0;
@@ -2735,8 +2735,6 @@ static void shade_tface(BakeShade *bs)
bs->quad= 0;
bs->rect_mask = NULL;
bs->displacement_buffer = NULL;
- bs->displacement_min = NULL;
- bs->displacement_max = NULL;
if (bs->use_mask || bs->use_displacement_buffer) {
BakeImBufuserData *userdata = bs->ibuf->userdata;
@@ -2749,11 +2747,8 @@ static void shade_tface(BakeShade *bs)
if (bs->use_mask)
userdata->mask_buffer = MEM_callocN(sizeof(char) * bs->rectx * bs->recty, "BakeMask");
- if (bs->use_displacement_buffer) {
+ if (bs->use_displacement_buffer)
userdata->displacement_buffer = MEM_callocN(sizeof(float) * bs->rectx * bs->recty, "BakeDisp");
- userdata->displacement_min = FLT_MAX;
- userdata->displacement_max = -FLT_MAX;
- }
bs->ibuf->userdata = userdata;
@@ -2762,8 +2757,6 @@ static void shade_tface(BakeShade *bs)
bs->rect_mask = userdata->mask_buffer;
bs->displacement_buffer = userdata->displacement_buffer;
- bs->displacement_min = &userdata->displacement_min;
- bs->displacement_max = &userdata->displacement_max;
}
/* get pixel level vertex coordinates */
@@ -2837,14 +2830,14 @@ void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter)
}
}
-void RE_bake_ibuf_normalize_displacement(ImBuf *ibuf, float *displacement, char *mask, float global_displacement_min, float global_displacement_max)
+void RE_bake_ibuf_normalize_displacement(ImBuf *ibuf, float *displacement, char *mask, float displacement_min, float displacement_max)
{
int i;
float *current_displacement = displacement;
char *current_mask = mask;
float max_distance;
- max_distance = max_ff(fabsf(global_displacement_min), fabsf(global_displacement_max));
+ max_distance = max_ff(fabsf(displacement_min), fabsf(displacement_max));
for (i = 0; i < ibuf->x * ibuf->y; i++) {
if (*current_mask == FILTER_MASK_USED) {
@@ -2853,7 +2846,7 @@ void RE_bake_ibuf_normalize_displacement(ImBuf *ibuf, float *displacement, char
if (max_distance > 1e-5f)
normalized_displacement = (*current_displacement + max_distance) / (max_distance * 2);
else
- normalized_displacement = 0.0f;
+ normalized_displacement = 0.5f;
if (ibuf->rect_float) {
/* currently baking happens to RGBA only */
@@ -2948,6 +2941,9 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
handles[a].do_update = do_update; /* use to tell the view to update */
+ handles[a].displacement_min = FLT_MAX;
+ handles[a].displacement_max = -FLT_MAX;
+
BLI_insert_thread(&threads, &handles[a]);
}
@@ -2970,23 +2966,12 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
/* filter and refresh images */
if ((R.r.bake_flag & R_BAKE_VCOL) == 0) {
- float global_displacement_min = FLT_MAX, global_displacement_max = -FLT_MAX;
+ float displacement_min = FLT_MAX, displacement_max = -FLT_MAX;
if (use_displacement_buffer) {
- for (ima = G.main->image.first; ima; ima = ima->id.next) {
- if ((ima->id.flag & LIB_DOIT)==0) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- BakeImBufuserData *userdata;
-
- if (!ibuf)
- continue;
-
- userdata = (BakeImBufuserData *) ibuf->userdata;
- global_displacement_min = min_ff(global_displacement_min, userdata->displacement_min);
- global_displacement_max = max_ff(global_displacement_max, userdata->displacement_max);
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
+ for (a = 0; a < re->r.threads; a++) {
+ displacement_min = min_ff(displacement_min, handles[a].displacement_min);
+ displacement_max = max_ff(displacement_max, handles[a].displacement_max);
}
}
@@ -3006,7 +2991,7 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
if (use_displacement_buffer) {
RE_bake_ibuf_normalize_displacement(ibuf, userdata->displacement_buffer, userdata->mask_buffer,
- global_displacement_min, global_displacement_max);
+ displacement_min, displacement_max);
}
ibuf->userflags |= IB_BITMAPDIRTY;