Index: source/blender/render/intern/source/convertblender.c =================================================================== --- source/blender/render/intern/source/convertblender.c (revision 12984) +++ source/blender/render/intern/source/convertblender.c (working copy) @@ -4706,6 +4706,7 @@ RE_BAKE_NORMALS:for baking, no lamps and only selected objects RE_BAKE_AO: for baking, no lamps, but all objects RE_BAKE_TEXTURE:for baking, no lamps, only selected objects + RE_BAKE_DISPLACEMENT:for baking, no lamps, only selected objects */ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) { @@ -4724,7 +4725,7 @@ if(type==RE_BAKE_NORMALS && re->r.bake_normal_space==R_BAKE_SPACE_TANGENT) re->flag |= R_NEED_TANGENT; - if(!actob && ELEM3(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE)) { + if(!actob && ELEM4(type, RE_BAKE_LIGHT, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT)) { re->r.mode &= ~R_SHADOW; re->r.mode &= ~R_RAYTRACE; } @@ -4767,7 +4768,7 @@ /* MAKE RENDER DATA */ nolamps= !ELEM(type, RE_BAKE_LIGHT, RE_BAKE_ALL); - onlyselected= ELEM(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE); + onlyselected= ELEM3(type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_DISPLACEMENT); database_init_objects(re, lay, nolamps, onlyselected, actob, 0); Index: source/blender/render/intern/source/rendercore.c =================================================================== --- source/blender/render/intern/source/rendercore.c (revision 12984) +++ source/blender/render/intern/source/rendercore.c (working copy) @@ -1870,6 +1870,27 @@ } } +static void bake_displacement(void *handle, ShadeInput *shi, Isect *isec, int dir, int x, int y) +{ + BakeShade *bs= handle; + float disp, mult; + + mult = 0.5f * -dir; + disp = 0.5 + (isec->labda * mult); + + if(bs->rect_float) { + float *col= bs->rect_float + 4*(bs->rectx*y + x); + col[0] = col[1] = col[2] = disp; + col[3]= 1.0f; + } else { + char *col= (char *)(bs->rect + bs->rectx*y + x); + col[0]= FTOCHAR(disp); + col[1]= FTOCHAR(disp); + col[2]= FTOCHAR(disp); + col[3]= 255; + } +} + static int bake_check_intersect(Isect *is, RayFace *face) { VlakRen *vlr = (VlakRen*)face; @@ -1956,7 +1977,7 @@ if(bs->actob) { Isect isec, minisec; float co[3], minco[3]; - int hit, sign; + int hit, sign, dir; /* intersect with ray going forward and backward*/ hit= 0; @@ -1978,10 +1999,16 @@ minisec= isec; VECCOPY(minco, co); hit= 1; + dir = sign; } } } + if (hit && bs->type==RE_BAKE_DISPLACEMENT) {; + bake_displacement(handle, shi, &minisec, dir, x, y); + return; + } + /* if hit, we shade from the new point, otherwise from point one starting face */ if(hit) { vlr= (VlakRen*)minisec.face; @@ -1993,6 +2020,8 @@ v= -minisec.v; bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v); } + + } if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) Index: source/blender/render/extern/include/RE_pipeline.h =================================================================== --- source/blender/render/extern/include/RE_pipeline.h (revision 12984) +++ source/blender/render/extern/include/RE_pipeline.h (working copy) @@ -206,11 +206,12 @@ void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect); /* shaded view or baking options */ -#define RE_BAKE_LIGHT 0 -#define RE_BAKE_ALL 1 -#define RE_BAKE_AO 2 -#define RE_BAKE_NORMALS 3 -#define RE_BAKE_TEXTURE 4 +#define RE_BAKE_LIGHT 0 +#define RE_BAKE_ALL 1 +#define RE_BAKE_AO 2 +#define RE_BAKE_NORMALS 3 +#define RE_BAKE_TEXTURE 4 +#define RE_BAKE_DISPLACEMENT 5 void RE_Database_Baking(struct Render *re, struct Scene *scene, int type, struct Object *actob); void RE_DataBase_GetView(struct Render *re, float mat[][4]); Index: source/blender/python/api2_2x/Image.c =================================================================== --- source/blender/python/api2_2x/Image.c (revision 12984) +++ source/blender/python/api2_2x/Image.c (working copy) @@ -1,5 +1,5 @@ /* - * $Id: Image.c 11241 2007-07-12 11:51:21Z campbellbarton $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -243,7 +243,7 @@ if (width > 5000 || height > 5000 || width < 1 || height < 1) return ( EXPP_ReturnPyObjError( PyExc_TypeError, "Image width and height must be between 1 and 5000" ) ); - image = BKE_add_image_size(width, height, name, 0, color); + image = BKE_add_image_size(width, height, name, 0, 0, color); if( !image ) return ( EXPP_ReturnPyObjError( PyExc_MemoryError, "couldn't create PyObject Image_Type" ) ); Index: source/blender/python/api2_2x/bpy_data.c =================================================================== --- source/blender/python/api2_2x/bpy_data.c (revision 12984) +++ source/blender/python/api2_2x/bpy_data.c (working copy) @@ -1,5 +1,5 @@ /* - * $Id: bpy_data.c 12056 2007-09-17 06:11:06Z aligorith $ + * $Id$ * * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** * @@ -538,7 +538,7 @@ break; case ID_IM: { - id = (ID *)BKE_add_image_size(img_width, img_height, name?name:"Image", 0, color); + id = (ID *)BKE_add_image_size(img_width, img_height, name?name:"Image", 0, 0, color); if( !id ) return ( EXPP_ReturnPyObjError( PyExc_MemoryError, "couldn't create PyObject Image_Type" ) ); Index: source/blender/blenkernel/intern/image.c =================================================================== --- source/blender/blenkernel/intern/image.c (revision 12984) +++ source/blender/blenkernel/intern/image.c (working copy) @@ -378,20 +378,27 @@ return ima; } -static ImBuf *add_ibuf_size(int width, int height, char *name, short uvtestgrid, float color[4]) +static ImBuf *add_ibuf_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4]) { ImBuf *ibuf; float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b; unsigned char *rect; + float *rect_float; int x, y; int checkerwidth=21, dark=1; - ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0); + if (floatbuf) { + ibuf= IMB_allocImBuf(width, height, 24, IB_rectfloat, 0); + rect_float= (float*)ibuf->rect_float; + } + else { + ibuf= IMB_allocImBuf(width, height, 24, IB_rect, 0); + rect= (unsigned char*)ibuf->rect; + } + strcpy(ibuf->name, "Untitled"); ibuf->userflags |= IB_BITMAPDIRTY; - rect= (unsigned char*)ibuf->rect; - if (uvtestgrid) { /* these two passes could be combined into one, but it's more readable and * easy to tweak like this, speed isn't really that much of an issue in this situation... */ @@ -400,26 +407,40 @@ for(y=0; yy; y++) { dark = pow(-1, floor(y / checkerwidth)); - for(x=0; xx; x++, rect+=4) { + for(x=0; xx; x++) { if (x % checkerwidth == 0) dark *= -1; - if (dark > 0) { - rect[0] = rect[1] = rect[2] = 64; - rect[3] = 255; - } else { - rect[0] = rect[1] = rect[2] = 150; - rect[3] = 255; + if (floatbuf) { + if (dark > 0) { + rect_float[0] = rect_float[1] = rect_float[2] = 0.25; + rect_float[3] = 1.0; + } else { + rect_float[0] = rect_float[1] = rect_float[2] = 0.58; + rect_float[3] = 1.0; + } + rect_float+=4; } + else { + if (dark > 0) { + rect[0] = rect[1] = rect[2] = 64; + rect[3] = 255; + } else { + rect[0] = rect[1] = rect[2] = 150; + rect[3] = 255; + } + rect += 4; + } } } /* 2nd pass, colored + */ - rect= (unsigned char*)ibuf->rect; + if (floatbuf) rect_float= (float*)ibuf->rect_float; + else rect= (unsigned char*)ibuf->rect; for(y=0; yy; y++) { hoffs = 0.125 * floor(y / checkerwidth); - for(x=0; xx; x++, rect+=4) { + for(x=0; xx; x++) { h = 0.125 * floor(x / checkerwidth); if ((fabs((x % checkerwidth) - (checkerwidth / 2)) < 4) && @@ -431,10 +452,20 @@ hue = fmod(fabs(h-hoffs), 1.0); hsv_to_rgb(hue, s, v, &r, &g, &b); - rect[0]= (char)(r * 255.0); - rect[1]= (char)(g * 255.0); - rect[2]= (char)(b * 255.0); - rect[3]= 255; + if (floatbuf) { + rect_float[0]= r; + rect_float[1]= g; + rect_float[2]= b; + rect_float[3]= 1.0; + rect_float+=4; + } + else { + rect[0]= (char)(r * 255.0); + rect[1]= (char)(g * 255.0); + rect[2]= (char)(b * 255.0); + rect[3]= 255; + rect+=4; + } } } @@ -442,11 +473,21 @@ } } else { /* blank image */ for(y=0; yy; y++) { - for(x=0; xx; x++, rect+=4) { - rect[0]= (char)(color[0] * 255.0); - rect[1]= (char)(color[1] * 255.0); - rect[2]= (char)(color[2] * 255.0); - rect[3]= (char)(color[3] * 255.0); + for(x=0; xx; x++) { + if (floatbuf) { + rect_float[0]= color[0]; + rect_float[1]= color[1]; + rect_float[2]= color[2]; + rect_float[3]= color[3]; + rect_float+=4; + } + else { + rect[0]= (char)(color[0] * 255.0); + rect[1]= (char)(color[1] * 255.0); + rect[2]= (char)(color[2] * 255.0); + rect[3]= (char)(color[3] * 255.0); + rect+=4; + } } } } @@ -454,7 +495,7 @@ } /* adds new image block, creates ImBuf and initializes color */ -Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid, float color[4]) +Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4]) { Image *ima; @@ -469,7 +510,7 @@ ima->gen_y= height; ima->gen_type= uvtestgrid; - ibuf= add_ibuf_size(width, height, name, uvtestgrid, color); + ibuf= add_ibuf_size(width, height, name, floatbuf, uvtestgrid, color); image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); ima->ok= IMA_OK_LOADED; @@ -1678,6 +1719,7 @@ { ImBuf *ibuf= NULL; float color[] = {0, 0, 0, 1}; + int floatbuf; /* quick reject tests */ if(ima==NULL) @@ -1755,7 +1797,7 @@ /* UV testgrid or black or solid etc */ if(ima->gen_x==0) ima->gen_x= 256; if(ima->gen_y==0) ima->gen_y= 256; - ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, ima->gen_type, color); + ibuf= add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, floatbuf, ima->gen_type, color); image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); ima->ok= IMA_OK_LOADED; } Index: source/blender/blenkernel/BKE_image.h =================================================================== --- source/blender/blenkernel/BKE_image.h (revision 12984) +++ source/blender/blenkernel/BKE_image.h (working copy) @@ -114,7 +114,7 @@ struct Image *BKE_add_image_file(const char *name); /* adds image, adds ibuf, generates color or pattern */ -struct Image *BKE_add_image_size(int width, int height, char *name, short uvtestgrid, float color[4]); +struct Image *BKE_add_image_size(int width, int height, char *name, int floatbuf, short uvtestgrid, float color[4]); /* for reload, refresh, pack */ void BKE_image_signal(struct Image *ima, struct ImageUser *iuser, int signal); Index: source/blender/src/verse_object.c =================================================================== --- source/blender/src/verse_object.c (revision 12984) +++ source/blender/src/verse_object.c (working copy) @@ -295,6 +295,7 @@ vbitmap->height, vnode->name, 0, + 0, color); ((Image*)vbitmap->image)->vnode = (void*)vnode; sync_blender_image_with_verse_bitmap_node(vnode); Index: source/blender/src/meshtools.c =================================================================== --- source/blender/src/meshtools.c (revision 12984) +++ source/blender/src/meshtools.c (working copy) @@ -1043,7 +1043,8 @@ if(event==1) event= RE_BAKE_ALL; else if(event==2) event= RE_BAKE_AO; else if(event==3) event= RE_BAKE_NORMALS; - else event= RE_BAKE_TEXTURE; + else if(event==4) event= RE_BAKE_TEXTURE; + else event= RE_BAKE_DISPLACEMENT; if(event==RE_BAKE_AO) { if(G.scene->world==NULL) { Index: source/blender/src/editsima.c =================================================================== --- source/blender/src/editsima.c (revision 12984) +++ source/blender/src/editsima.c (working copy) @@ -2218,6 +2218,7 @@ { static int width= 1024, height= 1024; static short uvtestgrid= 0; + static int floatbuf=0; static float color[] = {0, 0, 0, 1}; char name[22]; Image *ima; @@ -2230,10 +2231,11 @@ add_numbut(3, COL, "", 0, 0, &color, NULL); add_numbut(4, NUM|FLO, "Alpha:", 0.0, 1.0, &color[3], NULL); add_numbut(5, TOG|SHO, "UV Test Grid", 0, 0, &uvtestgrid, NULL); - if (!do_clever_numbuts("New Image", 6, REDRAW)) + add_numbut(6, TOG|INT, "Float Buffer", 0, 0, &floatbuf, NULL); + if (!do_clever_numbuts("New Image", 7, REDRAW)) return; - ima = BKE_add_image_size(width, height, name, uvtestgrid, color); + ima = BKE_add_image_size(width, height, name, floatbuf, uvtestgrid, color); image_changed(G.sima, ima); BKE_image_signal(G.sima->image, &G.sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE); BIF_undo_push("Add image"); Index: source/blender/src/buttons_scene.c =================================================================== --- source/blender/src/buttons_scene.c (revision 12984) +++ source/blender/src/buttons_scene.c (working copy) @@ -1269,11 +1269,12 @@ uiDefButS(block, ROW,B_REDR,"Ambient Occlusion",210,150,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_AO, 0, 0, ""); uiDefButS(block, ROW,B_REDR,"Normals", 210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, ""); uiDefButS(block, ROW,B_REDR,"Textures", 210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, ""); + uiDefButS(block, ROW,B_REDR,"Displacement", 210,90,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_DISPLACEMENT, 0, 0, ""); uiBlockEndAlign(block); - uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear", 210,80,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking"); + uiDefButBitS(block, TOG, R_BAKE_CLEAR, B_DIFF, "Clear", 210,60,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking"); - uiDefButS(block, NUM, B_DIFF,"Margin:", 210,50,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter"); + uiDefButS(block, NUM, B_DIFF,"Margin:", 210,30,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter"); } static void render_panel_render(void) Index: source/blender/imbuf/intern/filter.c =================================================================== --- source/blender/imbuf/intern/filter.c (revision 12984) +++ source/blender/imbuf/intern/filter.c (working copy) @@ -242,7 +242,7 @@ #define EXTEND_PIXEL(a, w) if((a)[3]) {r+= w*(a)[0]; g+= w*(a)[1]; b+= w*(a)[2]; tot+=w;} -/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 255 */ +/* if alpha is zero, it checks surrounding pixels and averages color. sets new alphas to 1.0 */ void IMB_filter_extend(struct ImBuf *ibuf) { register char *row1, *row2, *row3; @@ -251,7 +251,57 @@ rowlen= ibuf->x; - if(ibuf->rect) { + + if (ibuf->rect_float) { + float *temprect; + float *row1f, *row2f, *row3f; + float *fp; + int pixlen = 4; + temprect= MEM_dupallocN(ibuf->rect_float); + + for(y=1; y<=ibuf->y; y++) { + /* setup rows */ + row1f= (float *)(temprect + (y-2)*rowlen*4); + row2f= row1f + 4*rowlen; + row3f= row2f + 4*rowlen; + if(y==1) + row1f= row2f; + else if(y==ibuf->y) + row3f= row2f; + + fp= (float *)(ibuf->rect_float + (y-1)*rowlen*4); + + for(x=0; xrect) { int *temprect; /* make a copy, to prevent flooding */