diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-11-11 10:25:45 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-11-11 10:25:45 +0400 |
commit | 92d35b74e79e63ae95732cf3161e84ace1e79e59 (patch) | |
tree | 19a8ecf74bfcae5187a4e25520f4e55384e7707b /source/blender/render | |
parent | 67386c003d5d4bd5355323acdfbef1aa9fa2b71d (diff) | |
parent | afeb0eeaf0e8caf5e46a5dd6fbea3786e9fb1354 (diff) |
svn merge -r41722:41723 ^/trunk/blender
Diffstat (limited to 'source/blender/render')
-rw-r--r-- | source/blender/render/extern/include/RE_render_ext.h | 7 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_shader_ext.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/include/pointdensity.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/include/texture.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/include/voxeldata.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/pointdensity.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/render_texture.c | 287 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeinput.c | 28 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeoutput.c | 22 | ||||
-rw-r--r-- | source/blender/render/intern/source/volumetric.c | 10 | ||||
-rw-r--r-- | source/blender/render/intern/source/voxeldata.c | 10 |
12 files changed, 338 insertions, 38 deletions
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h index 9f8b5ac2763..f93e3c9fd20 100644 --- a/source/blender/render/extern/include/RE_render_ext.h +++ b/source/blender/render/extern/include/RE_render_ext.h @@ -48,6 +48,7 @@ struct RNode; struct Render; struct MTex; struct ImBuf; +struct DerivedMesh; // RADIO REMOVED, Maybe this will be useful later //void RE_zbufferall_radio(struct RadView *vw, struct RNode **rg_elem, int rg_totelem, struct Render *re); @@ -63,5 +64,11 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result); void antialias_tagbuf(int xsize, int ysize, char *rectmove); +/* dynamicpaint.c */ +struct Material *RE_init_sample_material(struct Material *orig_mat, struct Scene *scene); +void RE_free_sample_material(struct Material *mat); +void RE_sample_material_color(struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], + int face_index, short hit_quad, struct DerivedMesh *orcoDm, struct Object *ob); + #endif /* RE_RENDER_EXT_H */ diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 36dec3801cd..dd0a0f308ce 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -90,7 +90,7 @@ typedef struct ShadeInputUV { } ShadeInputUV; typedef struct ShadeInputCol { - float col[3]; + float col[4]; char *name; } ShadeInputCol; diff --git a/source/blender/render/intern/include/pointdensity.h b/source/blender/render/intern/include/pointdensity.h index 910f011b467..7ceb24e9ece 100644 --- a/source/blender/render/intern/include/pointdensity.h +++ b/source/blender/render/intern/include/pointdensity.h @@ -40,6 +40,7 @@ struct Render; struct TexResult; +void cache_pointdensity(struct Render *re, struct Tex *tex); void make_pointdensities(struct Render *re); void free_pointdensities(struct Render *re); int pointdensitytex(struct Tex *tex, float *texvec, struct TexResult *texres); diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index a702e890c3b..a8d13077680 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -70,9 +70,9 @@ struct ImBuf; void do_halo_tex(struct HaloRen *har, float xn, float yn, float col_r[4]); void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float hor[3], float zen[3], float *blend, int skyflag, short thread); -void do_material_tex(struct ShadeInput *shi); +void do_material_tex(struct ShadeInput *shi, struct Render *re); void do_lamp_tex(LampRen *la, const float lavec[3], struct ShadeInput *shi, float col_r[3], int effect); -void do_volume_tex(struct ShadeInput *shi, const float xyz[3], int mapto_flag, float col[3], float *val); +void do_volume_tex(struct ShadeInput *shi, const float xyz[3], int mapto_flag, float col[3], float *val, struct Render *re); void init_render_textures(Render *re); void end_render_textures(Render *re); diff --git a/source/blender/render/intern/include/voxeldata.h b/source/blender/render/intern/include/voxeldata.h index 11ac60baa12..aa4a9fdb845 100644 --- a/source/blender/render/intern/include/voxeldata.h +++ b/source/blender/render/intern/include/voxeldata.h @@ -42,6 +42,7 @@ typedef struct VoxelDataHeader int frames; } VoxelDataHeader; +void cache_voxeldata(Tex *tex, int scene_frame); void make_voxeldata(struct Render *re); void free_voxeldata(struct Render *re); int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 4fe34a29e55..66dc0b95a60 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2290,7 +2290,7 @@ static void displace_render_vert(Render *re, ObjectRen *obr, ShadeInput *shi, Ve shi->displace[0]= shi->displace[1]= shi->displace[2]= 0.0; - do_material_tex(shi); + do_material_tex(shi, re); //printf("no=%f, %f, %f\nbefore co=%f, %f, %f\n", vr->n[0], vr->n[1], vr->n[2], //vr->co[0], vr->co[1], vr->co[2]); diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index c3a4ca9bf7d..5b81ea85914 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -239,7 +239,7 @@ static void pointdensity_cache_object(Render *re, PointDensity *pd, Object *ob) dm->release(dm); } -static void cache_pointdensity(Render *re, Tex *tex) +void cache_pointdensity(Render *re, Tex *tex) { PointDensity *pd = tex->pd; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index b5386dde623..2d3f6fa6005 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -38,6 +38,7 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "DNA_anim_types.h" #include "DNA_texture_types.h" #include "DNA_object_types.h" #include "DNA_lamp_types.h" @@ -55,10 +56,12 @@ #include "BKE_node.h" #include "BKE_plugin_types.h" - +#include "BKE_animsys.h" +#include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_scene.h" #include "BKE_library.h" #include "BKE_image.h" @@ -66,6 +69,8 @@ #include "BKE_key.h" #include "BKE_ipo.h" +#include "MEM_guardedalloc.h" + #include "envmap.h" #include "pointdensity.h" #include "voxeldata.h" @@ -2141,7 +2146,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T return rgbnor; } -void do_material_tex(ShadeInput *shi) +void do_material_tex(ShadeInput *shi, Render *re) { CompatibleBump compat_bump; NTapBump ntap_bump; @@ -2159,7 +2164,7 @@ void do_material_tex(ShadeInput *shi) compatible_bump_init(&compat_bump); ntap_bump_init(&ntap_bump); - if (R.r.scemode & R_NO_TEX) return; + if (re->r.scemode & R_NO_TEX) return; /* here: test flag if there's a tex (todo) */ for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { @@ -2395,7 +2400,7 @@ void do_material_tex(ShadeInput *shi) float len= normalize_v3(texres.nor); // can be optimized... (ton) mul_mat3_m4_v3(shi->obr->ob->obmat, texres.nor); - mul_mat3_m4_v3(R.viewmat, texres.nor); + mul_mat3_m4_v3(re->viewmat, texres.nor); normalize_v3(texres.nor); mul_v3_fl(texres.nor, len); } @@ -2428,7 +2433,7 @@ void do_material_tex(ShadeInput *shi) ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) + if (ibuf && !(ibuf->rect_float) && re->r.color_mgt_flag & R_COLOR_MANAGEMENT) srgb_to_linearrgb_v3_v3(tcol, tcol); } @@ -2498,12 +2503,12 @@ void do_material_tex(ShadeInput *shi) if(mtex->normapspace == MTEX_NSPACE_CAMERA); else if(mtex->normapspace == MTEX_NSPACE_WORLD) { - mul_mat3_m4_v3(R.viewmat, nor); + mul_mat3_m4_v3(re->viewmat, nor); } else if(mtex->normapspace == MTEX_NSPACE_OBJECT) { if(shi->obr && shi->obr->ob) mul_mat3_m4_v3(shi->obr->ob->obmat, nor); - mul_mat3_m4_v3(R.viewmat, nor); + mul_mat3_m4_v3(re->viewmat, nor); } normalize_v3(nor); @@ -2651,9 +2656,9 @@ void do_material_tex(ShadeInput *shi) if(shi->amb<0.0f) shi->amb= 0.0f; else if(shi->amb>1.0f) shi->amb= 1.0f; - shi->ambr= shi->amb*R.wrld.ambr; - shi->ambg= shi->amb*R.wrld.ambg; - shi->ambb= shi->amb*R.wrld.ambb; + shi->ambr= shi->amb*re->wrld.ambr; + shi->ambg= shi->amb*re->wrld.ambg; + shi->ambb= shi->amb*re->wrld.ambb; } } } @@ -2667,7 +2672,7 @@ void do_material_tex(ShadeInput *shi) } -void do_volume_tex(ShadeInput *shi, const float xyz[3], int mapto_flag, float col[3], float *val) +void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float *col, float *val, Render *re) { MTex *mtex; Tex *tex; @@ -2676,7 +2681,7 @@ void do_volume_tex(ShadeInput *shi, const float xyz[3], int mapto_flag, float co float co[3], texvec[3]; float fact, stencilTin=1.0; - if (R.r.scemode & R_NO_TEX) return; + if (re->r.scemode & R_NO_TEX) return; /* here: test flag if there's a tex (todo) */ for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { @@ -2718,7 +2723,7 @@ void do_volume_tex(ShadeInput *shi, const float xyz[3], int mapto_flag, float co } else if(mtex->texco==TEXCO_GLOB) { copy_v3_v3(co, xyz); - mul_m4_v3(R.viewinv, co); + mul_m4_v3(re->viewinv, co); } else continue; // can happen when texco defines disappear and it renders old files @@ -3472,4 +3477,260 @@ void render_realtime_texture(ShadeInput *shi, Image *ima) shi->vcol[3]*= texr.ta; } +/* A modified part of shadeinput.c -> shade_input_set_uv() +* Used for sampling UV mapped texture color */ +static void textured_face_generate_uv(float *uv, float *normal, float *hit, float *v1, float *v2, float *v3) +{ + + float detsh, t00, t10, t01, t11, xn, yn, zn; + int axis1, axis2; + + /* find most stable axis to project */ + xn= fabs(normal[0]); + yn= fabs(normal[1]); + zn= fabs(normal[2]); + + if(zn>=xn && zn>=yn) { axis1= 0; axis2= 1; } + else if(yn>=xn && yn>=zn) { axis1= 0; axis2= 2; } + else { axis1= 1; axis2= 2; } + + /* compute u,v and derivatives */ + t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2]; + t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2]; + + detsh= 1.0f/(t00*t11-t10*t01); + t00*= detsh; t01*=detsh; + t10*=detsh; t11*=detsh; + + uv[0] = (hit[axis1]-v3[axis1])*t11-(hit[axis2]-v3[axis2])*t10; + uv[1] = (hit[axis2]-v3[axis2])*t00-(hit[axis1]-v3[axis1])*t01; + + /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */ + CLAMP(uv[0], -2.0f, 1.0f); + CLAMP(uv[1], -2.0f, 1.0f); +} + +/* Generate an updated copy of material to use for color sampling. */ +Material *RE_init_sample_material(Material *orig_mat, Scene *scene) +{ + Tex *tex = NULL; + Material *mat; + int tex_nr; + + if (!orig_mat) return NULL; + + /* copy material */ + mat = localize_material(orig_mat); + + /* update material anims */ + BKE_animsys_evaluate_animdata(scene, &mat->id, mat->adt, BKE_curframe(scene), ADT_RECALC_ANIM); + + /* strip material copy from unsupported flags */ + for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { + if(mat->septex & (1<<tex_nr)) continue; + + if(mat->mtex[tex_nr]) { + MTex *mtex = mat->mtex[tex_nr]; + + /* only keep compatible texflags */ + mtex->texflag = mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE | MTEX_ALPHAMIX); + + /* depending of material type, strip non-compatible mapping modes */ + if (mat->material_type == MA_TYPE_SURFACE) { + if (!ELEM4(mtex->texco, TEXCO_ORCO, TEXCO_OBJECT, TEXCO_GLOB, TEXCO_UV)) { + /* ignore this texture */ + mtex->texco = 0; + continue; + } + /* strip all mapto flags except color and alpha */ + mtex->mapto = (mtex->mapto & MAP_COL) | (mtex->mapto & MAP_ALPHA); + } + else if (mat->material_type == MA_TYPE_VOLUME) { + if (!ELEM3(mtex->texco, TEXCO_OBJECT, TEXCO_ORCO, TEXCO_GLOB)) { + /* ignore */ + mtex->texco = 0; + continue; + } + /* strip all mapto flags except color and alpha */ + mtex->mapto = mtex->mapto & (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY); + } + + /* if mapped to an object, calculate inverse matrices */ + if(mtex->texco==TEXCO_OBJECT) { + Object *ob= mtex->object; + if(ob) { + invert_m4_m4(ob->imat, ob->obmat); + copy_m4_m4(ob->imat_ren, ob->imat); + } + } + + /* copy texture */ + tex= mtex->tex = localize_texture(mtex->tex); + + /* update texture anims */ + BKE_animsys_evaluate_animdata(scene, &tex->id, tex->adt, BKE_curframe(scene), ADT_RECALC_ANIM); + + /* update texture cache if required */ + if(tex->type==TEX_VOXELDATA) { + cache_voxeldata(tex, (int)scene->r.cfra); + } + if(tex->type==TEX_POINTDENSITY) { + /* set dummy values for render and do cache */ + Render dummy_re = {0}; + dummy_re.scene = scene; + unit_m4(dummy_re.viewinv); + unit_m4(dummy_re.viewmat); + unit_m4(dummy_re.winmat); + dummy_re.winx = dummy_re.winy = 128; + cache_pointdensity(&dummy_re, tex); + } + + /* update image sequences and movies */ + if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { + if(tex->iuser.flag & IMA_ANIM_ALWAYS) + BKE_image_user_calc_frame(&tex->iuser, (int)scene->r.cfra, 0); + } + } + } + return mat; +} + +/* free all duplicate data allocated by RE_init_sample_material() */ +void RE_free_sample_material(Material *mat) +{ + int tex_nr; + + /* free textures */ + for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { + if(mat->septex & (1<<tex_nr)) continue; + if(mat->mtex[tex_nr]) { + MTex *mtex= mat->mtex[tex_nr]; + free_texture(mtex->tex); + MEM_freeN(mtex->tex); + mtex->tex = NULL; + } + } + + free_material(mat); + MEM_freeN(mat); +} + + + +/* +* Get material diffuse color and alpha (including linked textures) in given coordinates +* +* color,alpha : input/output color values +* volume_co : sample coordinate in global space. used by volumetric materials +* surface_co : sample surface coordinate in global space. used by "surface" materials +* face_index : surface face index +* hit_quad : whether point is on second "half" of a quad +* orcoDm : orco state derived mesh +*/ +void RE_sample_material_color(Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3], int face_index, short hit_quad, DerivedMesh *orcoDm, Object *ob) +{ + MFace *mface; + int v1, v2, v3; + MVert *mvert; + float uv[3], normal[3]; + ShadeInput shi = {0}; + Render re = {0}; + + /* Get face data */ + mvert = orcoDm->getVertArray(orcoDm); + mface = orcoDm->getFaceArray(orcoDm); + + if (!mvert || !mface || !mat) return; + v1=mface[face_index].v1, v2=mface[face_index].v2, v3=mface[face_index].v3; + if (hit_quad) {v2=mface[face_index].v3; v3=mface[face_index].v4;} + normal_tri_v3( normal, mvert[v1].co, mvert[v2].co, mvert[v3].co); + + /* generate shadeinput with data required */ + shi.mat = mat; + + /* fill shadeinput data depending on material type */ + if (mat->material_type == MA_TYPE_SURFACE) { + /* global coordinates */ + copy_v3_v3(shi.gl, surface_co); + /* object space coordinates */ + copy_v3_v3(shi.co, surface_co); + mul_m4_v3(ob->imat, shi.co); + /* orco coordinates */ + { + float l; + /* Get generated UV */ + textured_face_generate_uv(uv, normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co); + l= 1.0f+uv[0]+uv[1]; + + /* calculate generated coordinate */ + shi.lo[0]= l*mvert[v3].co[0]-uv[0]*mvert[v1].co[0]-uv[1]*mvert[v2].co[0]; + shi.lo[1]= l*mvert[v3].co[1]-uv[0]*mvert[v1].co[1]-uv[1]*mvert[v2].co[1]; + shi.lo[2]= l*mvert[v3].co[2]-uv[0]*mvert[v1].co[2]-uv[1]*mvert[v2].co[2]; + } + /* uv coordinates */ + { + int i, layers = CustomData_number_of_layers(&orcoDm->faceData, CD_MTFACE); + int layer_index = CustomData_get_layer_index(&orcoDm->faceData, CD_MTFACE); + + /* for every uv layer set coords and name */ + for (i=0; i<layers; i++) { + if(layer_index >= 0) { + float *uv1, *uv2, *uv3; + float l; + CustomData *data = &orcoDm->faceData; + MTFace *tface = (MTFace*) data->layers[layer_index+i].data; + float uv[3]; + /* point layer name from actual layer data */ + shi.uv[i].name = data->layers[i].name; + /* Get generated coordinates to calculate UV from */ + textured_face_generate_uv(uv, normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co); + /* Get UV mapping coordinate */ + l= 1.0f+uv[0]+uv[1]; + + uv1= tface[face_index].uv[0]; + uv2= (hit_quad) ? tface[face_index].uv[2] : tface[face_index].uv[1]; + uv3= (hit_quad) ? tface[face_index].uv[3] : tface[face_index].uv[2]; + + shi.uv[i].uv[0]= -1.0f + 2.0f*(l*uv3[0]-uv[0]*uv1[0]-uv[1]*uv2[0]); + shi.uv[i].uv[1]= -1.0f + 2.0f*(l*uv3[1]-uv[0]*uv1[1]-uv[1]*uv2[1]); + shi.uv[i].uv[2]= 0.0f; /* texture.c assumes there are 3 coords */ + } + } + /* active uv layer */ + shi.actuv = CustomData_get_active_layer_index(&orcoDm->faceData,CD_MTFACE) - layer_index; + shi.totuv = layers; + } + + /* apply initial values from material */ + shi.r = mat->r; + shi.g = mat->g; + shi.b = mat->b; + shi.alpha = mat->alpha; + + /* do texture */ + do_material_tex(&shi, &re); + + /* apply result */ + color[0] = shi.r; + color[1] = shi.g; + color[2] = shi.b; + *alpha = shi.alpha; + } + else if (mat->material_type == MA_TYPE_VOLUME) { + ObjectInstanceRen obi = {0}; + obi.ob = ob; + shi.obi = &obi; + unit_m4(re.viewinv); + + color[0] = mat->vol.reflection_col[0]; + color[1] = mat->vol.reflection_col[1]; + color[2] = mat->vol.reflection_col[2]; + *alpha = mat->vol.density; + + /* do texture */ + do_volume_tex(&shi, volume_co, (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY), + color, alpha, &re); + } +} + /* eof */ diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 1852dfaebab..f2a053e89d9 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -469,17 +469,20 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert scol->col[0]= cp[3]/255.0f; scol->col[1]= cp[2]/255.0f; scol->col[2]= cp[1]/255.0f; + scol->col[3]= cp[0]/255.0f; } if(shi->totcol) { shi->vcol[0]= shi->col[shi->actcol].col[0]; shi->vcol[1]= shi->col[shi->actcol].col[1]; shi->vcol[2]= shi->col[shi->actcol].col[2]; + shi->vcol[3]= shi->col[shi->actcol].col[3]; } else { shi->vcol[0]= 0.0f; shi->vcol[1]= 0.0f; shi->vcol[2]= 0.0f; + shi->vcol[3]= 0.0f; } } @@ -512,6 +515,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert shi->vcol[0]= 1.0f; shi->vcol[1]= 1.0f; shi->vcol[2]= 1.0f; + shi->vcol[3]= 1.0f; } } } @@ -528,6 +532,7 @@ void shade_input_set_strand_texco(ShadeInput *shi, StrandRen *strand, StrandVert shi->vcol[0]= 1.0f; shi->vcol[1]= 1.0f; shi->vcol[2]= 1.0f; + shi->vcol[3]= 1.0f; } } @@ -1096,6 +1101,7 @@ void shade_input_set_shade_texco(ShadeInput *shi) for (i=0; (mcol=RE_vlakren_get_mcol(obr, vlr, i, &name, 0)); i++) { ShadeInputCol *scol= &shi->col[i]; char *cp1, *cp2, *cp3; + float a[3]; shi->totcol++; scol->name= name; @@ -1103,17 +1109,29 @@ void shade_input_set_shade_texco(ShadeInput *shi) cp1= (char *)(mcol+j1); cp2= (char *)(mcol+j2); cp3= (char *)(mcol+j3); - - scol->col[0]= (l*((float)cp3[3]) - u*((float)cp1[3]) - v*((float)cp2[3]))/255.0f; - scol->col[1]= (l*((float)cp3[2]) - u*((float)cp1[2]) - v*((float)cp2[2]))/255.0f; - scol->col[2]= (l*((float)cp3[1]) - u*((float)cp1[1]) - v*((float)cp2[1]))/255.0f; + + /* alpha values */ + a[0] = ((float)cp1[0])/255.f; + a[1] = ((float)cp2[0])/255.f; + a[2] = ((float)cp3[0])/255.f; + scol->col[3]= l*a[2] - u*a[0] - v*a[1]; + + /* sample premultiplied color value */ + scol->col[0]= (l*((float)cp3[3])*a[2] - u*((float)cp1[3])*a[0] - v*((float)cp2[3])*a[1])/255.f; + scol->col[1]= (l*((float)cp3[2])*a[2] - u*((float)cp1[2])*a[0] - v*((float)cp2[2])*a[1])/255.f; + scol->col[2]= (l*((float)cp3[1])*a[2] - u*((float)cp1[1])*a[0] - v*((float)cp2[1])*a[1])/255.f; + + /* if not zero alpha, restore non-multiplied color */ + if (scol->col[3]) { + mul_v3_fl(scol->col, 1.0f/scol->col[3]); + } } if(shi->totcol) { shi->vcol[0]= shi->col[shi->actcol].col[0]; shi->vcol[1]= shi->col[shi->actcol].col[1]; shi->vcol[2]= shi->col[shi->actcol].col[2]; - shi->vcol[3]= 1.0f; + shi->vcol[3]= shi->col[shi->actcol].col[3]; } else { shi->vcol[0]= 0.0f; diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 0ed3a094cf8..fde4eab37b0 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -864,16 +864,22 @@ void shade_color(ShadeInput *shi, ShadeResult *shr) { Material *ma= shi->mat; - if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { + if(ma->mode & (MA_FACETEXTURE)) { shi->r= shi->vcol[0]; shi->g= shi->vcol[1]; shi->b= shi->vcol[2]; if(ma->mode & (MA_FACETEXTURE_ALPHA)) shi->alpha= shi->vcol[3]; } + else if(ma->mode & (MA_VERTEXCOLP)) { + float neg_alpha = 1.0f - shi->vcol[3]; + shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3]; + shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3]; + shi->b= shi->b*neg_alpha + shi->vcol[2]*shi->vcol[3]; + } if(ma->texco) - do_material_tex(shi); + do_material_tex(shi, &R); if(ma->fresnel_tra!=0.0f) shi->alpha*= fresnel_fac(shi->view, shi->vn, ma->fresnel_tra_i, ma->fresnel_tra); @@ -1655,15 +1661,21 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) /* material color itself */ if(passflag & (SCE_PASS_COMBINED|SCE_PASS_RGBA)) { - if(ma->mode & (MA_VERTEXCOLP|MA_FACETEXTURE)) { + if(ma->mode & (MA_FACETEXTURE)) { shi->r= shi->vcol[0]; shi->g= shi->vcol[1]; shi->b= shi->vcol[2]; if(ma->mode & (MA_FACETEXTURE_ALPHA)) - shi->alpha= (shi->mode & MA_TRANSP) ? shi->vcol[3] : 1.0f; + shi->alpha= shi->vcol[3]; + } + else if(ma->mode & (MA_VERTEXCOLP)) { + float neg_alpha = 1.0f - shi->vcol[3]; + shi->r= shi->r*neg_alpha + shi->vcol[0]*shi->vcol[3]; + shi->g= shi->g*neg_alpha + shi->vcol[1]*shi->vcol[3]; + shi->b= shi->b*neg_alpha + shi->vcol[2]*shi->vcol[3]; } if(ma->texco){ - do_material_tex(shi); + do_material_tex(shi, &R); if (!(shi->mode & MA_TRANSP)) shi->alpha = 1.0f; } diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c index 577671af684..4b1894236fc 100644 --- a/source/blender/render/intern/source/volumetric.c +++ b/source/blender/render/intern/source/volumetric.c @@ -289,7 +289,7 @@ float vol_get_density(struct ShadeInput *shi, const float co[3]) float density_scale = shi->mat->vol.density_scale; if (shi->mat->mapto_textured & MAP_DENSITY) - do_volume_tex(shi, co, MAP_DENSITY, NULL, &density); + do_volume_tex(shi, co, MAP_DENSITY, NULL, &density, &R); // if meta-object, modulate by metadensity without increasing it if (shi->obi->obr->ob->type == OB_MBALL) { @@ -311,11 +311,11 @@ static void vol_get_reflection_color(ShadeInput *shi, float ref_col[3], const fl copy_v3_v3(ref_col, shi->mat->vol.reflection_col); if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_REFLECTION_COL)) - do_volume_tex(shi, co, MAP_SCATTERING+MAP_REFLECTION_COL, ref_col, &scatter); + do_volume_tex(shi, co, MAP_SCATTERING+MAP_REFLECTION_COL, ref_col, &scatter, &R); /* only one single float parameter at a time... :s */ if (shi->mat->mapto_textured & (MAP_REFLECTION)) - do_volume_tex(shi, co, MAP_REFLECTION, NULL, &reflection); + do_volume_tex(shi, co, MAP_REFLECTION, NULL, &reflection, &R); ref_col[0] = reflection * ref_col[0] * scatter; ref_col[1] = reflection * ref_col[1] * scatter; @@ -330,7 +330,7 @@ static void vol_get_emission(ShadeInput *shi, float emission_col[3], const float copy_v3_v3(emission_col, shi->mat->vol.emission_col); if (shi->mat->mapto_textured & (MAP_EMISSION+MAP_EMISSION_COL)) - do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission); + do_volume_tex(shi, co, MAP_EMISSION+MAP_EMISSION_COL, emission_col, &emission, &R); emission_col[0] = emission_col[0] * emission; emission_col[1] = emission_col[1] * emission; @@ -350,7 +350,7 @@ static void vol_get_sigma_t(ShadeInput *shi, float sigma_t[3], const float co[3] float scattering = shi->mat->vol.scattering; if (shi->mat->mapto_textured & (MAP_SCATTERING+MAP_TRANSMISSION_COL)) - do_volume_tex(shi, co, MAP_SCATTERING+MAP_TRANSMISSION_COL, transmission_col, &scattering); + do_volume_tex(shi, co, MAP_SCATTERING+MAP_TRANSMISSION_COL, transmission_col, &scattering, &R); sigma_t[0] = (1.0f - transmission_col[0]) + scattering; sigma_t[1] = (1.0f - transmission_col[1]) + scattering; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index 57ff5f4237a..ce5561b3e34 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -309,7 +309,7 @@ static void init_frame_smoke(VoxelData *vd, float cfra) #endif } -static void cache_voxeldata(struct Render *re, Tex *tex) +void cache_voxeldata(Tex *tex, int scene_frame) { VoxelData *vd = tex->vd; FILE *fp; @@ -317,7 +317,7 @@ static void cache_voxeldata(struct Render *re, Tex *tex) char path[sizeof(vd->source_path)]; /* only re-cache if dataset needs updating */ - if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == re->r.cfra)) + if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == scene_frame)) if (vd->ok) return; /* clear out old cache, ready for new */ @@ -329,7 +329,7 @@ static void cache_voxeldata(struct Render *re, Tex *tex) if (vd->flag & TEX_VD_STILL) curframe = vd->still_frame; else - curframe = re->r.cfra; + curframe = scene_frame; BLI_strncpy(path, vd->source_path, sizeof(path)); @@ -338,7 +338,7 @@ static void cache_voxeldata(struct Render *re, Tex *tex) load_frame_image_sequence(vd, tex); return; case TEX_VD_SMOKE: - init_frame_smoke(vd, re->r.cfra); + init_frame_smoke(vd, scene_frame); return; case TEX_VD_BLENDERVOXEL: BLI_path_abs(path, G.main->name); @@ -373,7 +373,7 @@ void make_voxeldata(struct Render *re) /* XXX: should be doing only textures used in this render */ for (tex= re->main->tex.first; tex; tex= tex->id.next) { if(tex->id.us && tex->type==TEX_VOXELDATA) { - cache_voxeldata(re, tex); + cache_voxeldata(tex, re->r.cfra); } } |