From 485dd1d37673d229db9062d8cad98e624d79c8ec Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Fri, 9 Dec 2005 15:14:32 +0000 Subject: Orange; WIP commit for inclusion of "Tangent" vector in rendering. This first implementation only supports it for Meshes with UV maps, and only tangents in V direction. Tangent diffuse: http://www.blender.org/bf/0001_0080.avi Tangent spec, diffuse, and bump: http://www.blender.org/bf/20001_0080.avi NOTE: since UV coordinates are still very badly subsurfed, this won't work well for subsurf meshes... on the todo. On the todo; - generate tangents for meshes without UV (with some options) - use tangents from Curve/Surface - add the Ashkimin shader from tracker ----- Important bugfix; curves didn't render anymore since yesterday. :) --- source/blender/blenkernel/BKE_utildefines.h | 3 +- source/blender/makesdna/DNA_material_types.h | 7 +- source/blender/render/intern/source/rendercore.c | 59 +++++++++----- .../blender/render/intern/source/renderdatabase.c | 3 +- source/blender/render/intern/source/texture.c | 29 +++++-- .../renderconverter/intern/convertBlenderScene.c | 91 ++++++++++++++++++--- source/blender/src/buttons_shading.c | 59 +++++++------- source/blender/src/previewrender.c | 92 +++++++++++++--------- 8 files changed, 235 insertions(+), 108 deletions(-) diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index f0b05802e97..f784973708d 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -1,5 +1,3 @@ -/* util defines -- might go away ?*/ - /* $Id$ @@ -103,6 +101,7 @@ #define VECADD(v1,v2,v3) {*(v1)= *(v2) + *(v3); *(v1+1)= *(v2+1) + *(v3+1); *(v1+2)= *(v2+2) + *(v3+2);} #define VECSUB(v1,v2,v3) {*(v1)= *(v2) - *(v3); *(v1+1)= *(v2+1) - *(v3+1); *(v1+2)= *(v2+2) - *(v3+2);} +#define VECADDFAC(v1,v2,v3,fac) {*(v1)= *(v2) + *(v3)*(fac); *(v1+1)= *(v2+1) + *(v3+1)*(fac); *(v1+2)= *(v2+2) + *(v3+2)*(fac);} #define INPR(v1, v2) ( (v1)[0]*(v2)[0] + (v1)[1]*(v2)[1] + (v1)[2]*(v2)[2] ) diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index ff2eb7194eb..9991148ad3d 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -169,6 +169,8 @@ typedef struct Material { #define MA_FULL_OSA 0x800000 #define MA_TANGENT_STR 0x1000000 #define MA_SHADBUF 0x2000000 + /* note; we drop MA_TANGENT_STR later to become tangent_u */ +#define MA_TANGENT_V 0x4000000 /* diff_shader */ #define MA_DIFF_LAMBERT 0 @@ -217,9 +219,8 @@ typedef struct Material { #define TEXCO_OSA 512 #define TEXCO_WINDOW 1024 #define NEED_UV 2048 - /* optim = use simpler AA */ -#define TEXCO_OPTIM 4096 - /* stored in vertex->accum, 1 D */ +#define TEXCO_TANGENT 4096 + /* still stored in vertex->accum, 1 D */ #define TEXCO_STRAND 8192 #define TEXCO_STRESS 16384 diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 3ca504e2ce4..0d6e141df5f 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -1636,7 +1636,14 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) if(vlr->flag & R_TANGENT) { float cross[3]; Crossf(cross, lv, vn); - Crossf(vnor, cross, shi->vn); + Crossf(vnor, cross, vn); + vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2]; + vn= vnor; + } + else if(ma->mode & MA_TANGENT_V) { + float cross[3]; + Crossf(cross, lv, shi->tang); + Crossf(vnor, cross, shi->tang); vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2]; vn= vnor; } @@ -1685,7 +1692,9 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) } vn= shi->vn; // bring back original vector, we use special specular shaders for tangent - + if(ma->mode & MA_TANGENT_V) + vn= shi->tang; + /* shadow and spec, (lampdist==0 outside spot) */ if(lampdist> 0.0) { @@ -1762,15 +1771,15 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) float specfac; if(ma->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(vn, lv, view, shi->har, vlr->flag & R_TANGENT); + specfac= Phong_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); else if(ma->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(vn, lv, view, shi->har, vlr->flag & R_TANGENT); + specfac= CookTorr_Spec(vn, lv, view, shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); else if(ma->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, vlr->flag & R_TANGENT); + specfac= Blinn_Spec(vn, lv, view, ma->refrac, (float)shi->har, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); else if(ma->spec_shader==MA_SPEC_WARDISO) - specfac= WardIso_Spec( vn, lv, view, ma->rms, vlr->flag & R_TANGENT); + specfac= WardIso_Spec( vn, lv, view, ma->rms, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); else - specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], vlr->flag & R_TANGENT); + specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); /* area lamp correction */ if(lar->type==LA_AREA) specfac*= inp; @@ -1979,9 +1988,25 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i shi->dyno[2]= dl*n3[2]-shi->dyuv[0]*n1[2]-shi->dyuv[1]*n2[2]; } + + if(mode & MA_TANGENT_V) { + float *s1, *s2, *s3; + + s1= RE_vertren_get_tangent(v1, 0); + s2= RE_vertren_get_tangent(v2, 0); + s3= RE_vertren_get_tangent(v3, 0); + if(s1 && s2 && s3) { + shi->tang[0]= (l*s3[0] - u*s1[0] - v*s2[0]); + shi->tang[1]= (l*s3[1] - u*s1[1] - v*s2[1]); + shi->tang[2]= (l*s3[2] - u*s1[2] - v*s2[2]); + } + else shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f; + } } else { VECCOPY(shi->vn, shi->facenor); + if(mode & MA_TANGENT_V) + shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f; } /* texture coordinates. shi->dxuv shi->dyuv have been set */ @@ -2100,20 +2125,6 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i shi->dyuv[0]= 2.0*(dl*uv3[0]-duv[0]*uv1[0]-duv[1]*uv2[0]); shi->dyuv[1]= 2.0*(dl*uv3[1]-duv[0]*uv1[1]-duv[1]*uv2[1]); } -#if 0 - { /* tangent derived from UV, comes back later! (ton) */ - //float s1= uv2[0] - uv1[0]; - //float s2= uv3[0] - uv1[0]; - float t1= uv2[1] - uv1[1]; - float t2= uv3[1] - uv1[1]; - - shi->vn[0]= (t2 * (v2->co[0]-v1->co[0]) - t1 * (v3->co[0]-v1->co[0])); - shi->vn[1]= (t2 * (v2->co[1]-v1->co[1]) - t1 * (v3->co[1]-v1->co[1])); - shi->vn[2]= (t2 * (v2->co[2]-v1->co[2]) - t1 * (v3->co[2]-v1->co[2])); - Normalise(shi->vn); - vlr->flag |= R_TANGENT; - } -#endif if(mode & MA_FACETEXTURE) { if((mode & (MA_VERTEXCOL|MA_VERTEXCOLP))==0) { shi->vcol[0]= 1.0; @@ -2176,6 +2187,12 @@ void shade_input_set_coords(ShadeInput *shi, float u, float v, int i1, int i2, i } else shi->stress= 0.0f; } + if(texco & TEXCO_TANGENT) { + if((mode & MA_TANGENT_V)==0) { + /* just prevent surprises */ + shi->tang[0]= shi->tang[1]= shi->tang[2]= 0.0f; + } + } } else { shi->rad[0]= shi->rad[1]= shi->rad[2]= 0.0; diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 4c7453bf1b1..d37c73dc932 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -160,6 +160,7 @@ float *RE_vertren_get_strand(VertRen *ver, int verify) return strand + (ver->index & 255)*RE_STRAND_ELEMS; } +/* needs calloc */ float *RE_vertren_get_tangent(VertRen *ver, int verify) { float *tangent; @@ -168,7 +169,7 @@ float *RE_vertren_get_tangent(VertRen *ver, int verify) tangent= R.vertnodes[nr].tangent; if(tangent==NULL) { if(verify) - tangent= R.vertnodes[nr].tangent= MEM_mallocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table"); + tangent= R.vertnodes[nr].tangent= MEM_callocN(256*RE_TANGENT_ELEMS*sizeof(float), "tangent table"); else return NULL; } diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 38936ec89fa..dff275e0a71 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -1444,6 +1444,9 @@ void do_material_tex(ShadeInput *shi) else if(mtex->texco==TEXCO_NORM) { co= shi->orn; dx= shi->dxno; dy= shi->dyno; } + else if(mtex->texco==TEXCO_TANGENT) { + co= shi->tang; dx= shi->dxno; dy= shi->dyno; + } else if(mtex->texco==TEXCO_GLOB) { co= shi->gl; dx= shi->dxco; dy= shi->dyco; } @@ -1690,14 +1693,28 @@ void do_material_tex(ShadeInput *shi) fact= Tnor*tex->norfac; if(fact>1.0) fact= 1.0; else if(fact<-1.0) fact= -1.0; facm= 1.0- fact; - shi->vn[0]= facm*shi->vn[0] + fact*texres.nor[0]; - shi->vn[1]= facm*shi->vn[1] + fact*texres.nor[1]; - shi->vn[2]= facm*shi->vn[2] + fact*texres.nor[2]; + if(shi->mat->mode & MA_TANGENT_V) { + shi->tang[0]= facm*shi->tang[0] + fact*texres.nor[0]; + shi->tang[1]= facm*shi->tang[1] + fact*texres.nor[1]; + shi->tang[2]= facm*shi->tang[2] + fact*texres.nor[2]; + } + else { + shi->vn[0]= facm*shi->vn[0] + fact*texres.nor[0]; + shi->vn[1]= facm*shi->vn[1] + fact*texres.nor[1]; + shi->vn[2]= facm*shi->vn[2] + fact*texres.nor[2]; + } } else { - shi->vn[0]+= Tnor*tex->norfac*texres.nor[0]; - shi->vn[1]+= Tnor*tex->norfac*texres.nor[1]; - shi->vn[2]+= Tnor*tex->norfac*texres.nor[2]; + if(shi->mat->mode & MA_TANGENT_V) { + shi->tang[0]+= Tnor*tex->norfac*texres.nor[0]; + shi->tang[1]+= Tnor*tex->norfac*texres.nor[1]; + shi->tang[2]+= Tnor*tex->norfac*texres.nor[2]; + } + else { + shi->vn[0]+= Tnor*tex->norfac*texres.nor[0]; + shi->vn[1]+= Tnor*tex->norfac*texres.nor[1]; + shi->vn[2]+= Tnor*tex->norfac*texres.nor[2]; + } } Normalise(shi->vn); diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 509e42637c0..3b694813e91 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -320,6 +320,7 @@ static VertRen *RE_duplicate_vertren(VertRen *ver) int index= v1->index; *v1= *ver; v1->index= index; + return v1; } static void split_v_renderfaces(int startvlak, int startvert, int usize, int vsize, int uIndex, int cyclu, int cyclv) @@ -442,7 +443,67 @@ static void calc_edge_stress(Mesh *me, int startvert, int startvlak) MEM_freeN(accum); } -static void calc_vertexnormals(int startvert, int startvlak) +static void calc_tangent_vector(VlakRen *vlr, float fac1, float fac2, float fac3, float fac4) +{ + TFace *tface= vlr->tface; + + if(tface) { + VertRen *v1=vlr->v1, *v2=vlr->v2, *v3=vlr->v3, *v4=vlr->v4; + float *uv1= tface->uv[0], *uv2= tface->uv[1], *uv3= tface->uv[2], *uv4= tface->uv[3]; + float tang[3], *tav; + float s1, s2, t1, t2, det; + + /* we calculate quads as two triangles, so weight for diagonal gets halved */ + if(v4) { + fac1*= 0.5f; + fac3*= 0.5f; + } + + /* first tria, we use the V now */ + s1= uv2[0] - uv1[0]; + s2= uv3[0] - uv1[0]; + t1= uv2[1] - uv1[1]; + t2= uv3[1] - uv1[1]; + det= 1.0f / (s1 * t2 - s2 * t1); + + /* normals in render are inversed... */ + tang[0]= (t2 * (v1->co[0]-v2->co[0]) - t1 * (v1->co[0]-v3->co[0])); + tang[1]= (t2 * (v1->co[1]-v2->co[1]) - t1 * (v1->co[1]-v3->co[1])); + tang[2]= (t2 * (v1->co[2]-v2->co[2]) - t1 * (v1->co[2]-v3->co[2])); + + tav= RE_vertren_get_tangent(v1, 1); + VECADDFAC(tav, tav, tang, fac1); + tav= RE_vertren_get_tangent(v2, 1); + VECADDFAC(tav, tav, tang, fac2); + tav= RE_vertren_get_tangent(v3, 1); + VECADDFAC(tav, tav, tang, fac3); + + if(v4) { + /* 2nd tria, we use the V now */ + s1= uv3[0] - uv1[0]; + s2= uv4[0] - uv1[0]; + t1= uv3[1] - uv1[1]; + t2= uv4[1] - uv1[1]; + det= 1.0f / (s1 * t2 - s2 * t1); + + /* normals in render are inversed... */ + tang[0]= (t2 * (v1->co[0]-v3->co[0]) - t1 * (v1->co[0]-v4->co[0])); + tang[1]= (t2 * (v1->co[1]-v3->co[1]) - t1 * (v1->co[1]-v4->co[1])); + tang[2]= (t2 * (v1->co[2]-v3->co[2]) - t1 * (v1->co[2]-v4->co[2])); + + Normalise(tang); + + tav= RE_vertren_get_tangent(v1, 1); + VECADDFAC(tav, tav, tang, fac1); + tav= RE_vertren_get_tangent(v3, 1); + VECADDFAC(tav, tav, tang, fac3); + tav= RE_vertren_get_tangent(v4, 1); + VECADDFAC(tav, tav, tang, fac4); + } + } +} + +static void calc_vertexnormals(int startvert, int startvlak, int do_tangent) { int a; @@ -452,7 +513,8 @@ static void calc_vertexnormals(int startvert, int startvlak) ver->n[0]=ver->n[1]=ver->n[2]= 0.0; } - /* calculate cos of angles and point-masses */ + /* calculate cos of angles and point-masses, use as weight factor to + add face normal to vertex */ for(a=startvlak; aflag & ME_SMOOTH) { @@ -461,13 +523,13 @@ static void calc_vertexnormals(int startvert, int startvlak) VertRen *adrve3= vlr->v3; VertRen *adrve4= vlr->v4; float n1[3], n2[3], n3[3], n4[3]; - float fac1, fac2, fac3, fac4; + float fac1, fac2, fac3, fac4=0.0f; VecSubf(n1, adrve2->co, adrve1->co); Normalise(n1); VecSubf(n2, adrve3->co, adrve2->co); Normalise(n2); - if(adrve4==0) { + if(adrve4==NULL) { VecSubf(n3, adrve1->co, adrve3->co); Normalise(n3); @@ -512,6 +574,9 @@ static void calc_vertexnormals(int startvert, int startvlak) adrve3->n[0] +=fac3*vlr->n[0]; adrve3->n[1] +=fac3*vlr->n[1]; adrve3->n[2] +=fac3*vlr->n[2]; + + if(do_tangent) + calc_tangent_vector(vlr, fac1, fac2, fac3, fac4); } } @@ -536,6 +601,10 @@ static void calc_vertexnormals(int startvert, int startvlak) for(a=startvert; an); + if(do_tangent) { + float *tav= RE_vertren_get_tangent(ver, 0); + if(tav) Normalise(tav); + } } /* vertex normal (puno) switch flags for during render */ @@ -1192,7 +1261,7 @@ static void render_static_particle_system(Object *ob, PartEff *paf) } if((ma->mode & MA_TANGENT_STR)==0) - calc_vertexnormals(totverto, totvlako); + calc_vertexnormals(totverto, totvlako, 0); } @@ -1393,7 +1462,7 @@ static void init_render_mesh(Object *ob) unsigned int *vertcol; float xn, yn, zn, imat[3][3], mat[4][4]; //nor[3], float *orco=0; - int a, a1, ok, need_orco=0, need_stress=0, totvlako, totverto, vertofs; + int a, a1, ok, need_orco=0, need_stress=0, need_tangent=0, totvlako, totverto, vertofs; int end, do_autosmooth=0, totvert = 0, dm_needsfree; me= ob->data; @@ -1425,6 +1494,8 @@ static void init_render_mesh(Object *ob) need_orco= 1; if(ma->texco & TEXCO_STRESS) need_stress= 1; + if(ma->mode & MA_TANGENT_V) + need_tangent= 1; } } @@ -1632,7 +1703,7 @@ static void init_render_mesh(Object *ob) } if (test_for_displace( ob ) ) { - calc_vertexnormals(totverto, totvlako); + calc_vertexnormals(totverto, totvlako, 0); do_displacement(ob, totvlako, R.totvlak-totvlako, totverto, R.totvert-totverto); } @@ -1640,7 +1711,7 @@ static void init_render_mesh(Object *ob) autosmooth(totverto, totvlako, me->smoothresh); } - calc_vertexnormals(totverto, totvlako); + calc_vertexnormals(totverto, totvlako, need_tangent); if(need_stress) calc_edge_stress(me, totverto, totvlako); @@ -2267,7 +2338,7 @@ static void init_render_curve(Object *ob) ver= RE_findOrAddVert(a); len= Normalise(ver->n); if(len==0.0) ver->flag= 1; /* flag use, its only used in zbuf now */ - else ver->flag= 1; + else ver->flag= 0; } for(a= startvlak; atexco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Glob", 670,166,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Object", 715,166,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",790,166,118,18, &(mtex->object), ""); + uiDefButS(block, ROW, B_MATPRV, "Glob", 630,180,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Object", 675,180,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MATPRV, "",750,180,158,18, &(mtex->object), ""); - uiDefButS(block, ROW, B_MATPRV, "Orco", 630,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object"); - uiDefButS(block, ROW, B_MATPRV, "Stress", 675,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh"); + uiDefButS(block, ROW, B_MATPRV, "UV", 630,160,40,18, &(mtex->texco), 4.0, (float)TEXCO_UV, 0, 0, "Uses UV coordinates for texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Orco", 670,160,55,18, &(mtex->texco), 4.0, (float)TEXCO_ORCO, 0, 0, "Uses the original undeformed coordinates of the object"); if( give_parteff(ob) ) - uiDefButS(block, ROW, B_MATPRV, "Strand", 725,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)"); + uiDefButS(block, ROW, B_MATPRV, "Strand", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STRAND, 0, 0, "Uses normalized strand texture coordinate (1D)"); else - uiDefButS(block, ROW, B_MATPRV, "Stick", 725,146,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Win", 775,146,45,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Uses screen coordinates as texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Nor", 820,146,44,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Uses normal vector as texture coordinates"); - uiDefButS(block, ROW, B_MATPRV, "Refl", 864,146,44,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Uses reflection vector as texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Stick", 725,160,50,18, &(mtex->texco), 4.0, (float)TEXCO_STICKY, 0, 0, "Uses mesh's sticky coordinates for the texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Win", 775,160,45,18, &(mtex->texco), 4.0, (float)TEXCO_WINDOW, 0, 0, "Uses screen coordinates as texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Nor", 820,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_NORM, 0, 0, "Uses normal vector as texture coordinates"); + uiDefButS(block, ROW, B_MATPRV, "Refl", 864,160,44,18, &(mtex->texco), 4.0, (float)TEXCO_REFL, 0, 0, "Uses reflection vector as texture coordinates"); + + uiDefButS(block, ROW, B_MATPRV, "Stress", 630,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh"); + uiDefButS(block, ROW, B_MATPRV, "Tangent", 700,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_TANGENT, 0, 0, "Uses te optional tangent vector as texture coordinates"); /* COORDS */ uiBlockBeginAlign(block); - uiDefButC(block, ROW, B_MATPRV, "Flat", 630,114,48,18, &(mtex->mapping), 5.0, (float)MTEX_FLAT, 0, 0, "Maps X and Y coordinates directly"); - uiDefButC(block, ROW, B_MATPRV, "Cube", 681,114,50,18, &(mtex->mapping), 5.0, (float)MTEX_CUBE, 0, 0, "Maps using the normal vector"); - uiDefButC(block, ROW, B_MATPRV, "Tube", 630,94,48,18, &(mtex->mapping), 5.0, (float)MTEX_TUBE, 0, 0, "Maps with Z as central axis (tube-like)"); - uiDefButC(block, ROW, B_MATPRV, "Sphe", 681,94,50,18, &(mtex->mapping), 5.0, (float)MTEX_SPHERE, 0, 0, "Maps with Z as central axis (sphere-like)"); + uiDefButC(block, ROW, B_MATPRV, "Flat", 630,115,48,19, &(mtex->mapping), 5.0, (float)MTEX_FLAT, 0, 0, "Maps X and Y coordinates directly"); + uiDefButC(block, ROW, B_MATPRV, "Cube", 681,115,50,19, &(mtex->mapping), 5.0, (float)MTEX_CUBE, 0, 0, "Maps using the normal vector"); + uiDefButC(block, ROW, B_MATPRV, "Tube", 630,95,48,19, &(mtex->mapping), 5.0, (float)MTEX_TUBE, 0, 0, "Maps with Z as central axis (tube-like)"); + uiDefButC(block, ROW, B_MATPRV, "Sphe", 681,95,50,19, &(mtex->mapping), 5.0, (float)MTEX_SPHERE, 0, 0, "Maps with Z as central axis (sphere-like)"); uiBlockBeginAlign(block); for(b=0; b<3; b++) { @@ -2892,13 +2894,13 @@ static void material_panel_map_input(Object *ob, Material *ma) } uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_MATPRV, "ofsX", 778,114,130,18, mtex->ofs, -10.0, 10.0, 10, 0, "Fine tunes texture mapping X coordinate"); - uiDefButF(block, NUM, B_MATPRV, "ofsY", 778,94,130,18, mtex->ofs+1, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Y coordinate"); - uiDefButF(block, NUM, B_MATPRV, "ofsZ", 778,74,130,18, mtex->ofs+2, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Z coordinate"); + uiDefButF(block, NUM, B_MATPRV, "ofsX", 778,115,130,19, mtex->ofs, -10.0, 10.0, 10, 0, "Fine tunes texture mapping X coordinate"); + uiDefButF(block, NUM, B_MATPRV, "ofsY", 778,95,130,19, mtex->ofs+1, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Y coordinate"); + uiDefButF(block, NUM, B_MATPRV, "ofsZ", 778,75,130,19, mtex->ofs+2, -10.0, 10.0, 10, 0, "Fine tunes texture mapping Z coordinate"); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_MATPRV, "sizeX", 778,50,130,18, mtex->size, -100.0, 100.0, 10, 0, "Sets scaling for the texture's X size"); - uiDefButF(block, NUM, B_MATPRV, "sizeY", 778,30,130,18, mtex->size+1, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Y size"); - uiDefButF(block, NUM, B_MATPRV, "sizeZ", 778,10,130,18, mtex->size+2, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Z size"); + uiDefButF(block, NUM, B_MATPRV, "sizeX", 778,50,130,19, mtex->size, -100.0, 100.0, 10, 0, "Sets scaling for the texture's X size"); + uiDefButF(block, NUM, B_MATPRV, "sizeY", 778,30,130,19, mtex->size+1, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Y size"); + uiDefButF(block, NUM, B_MATPRV, "sizeZ", 778,10,130,19, mtex->size+2, -100.0, 100.0, 10, 0, "Sets scaling for the texture's Z size"); uiBlockEndAlign(block); } @@ -3173,18 +3175,19 @@ static void material_panel_shading(Material *ma) uiBlockSetCol(block, TH_BUT_SETTING1); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, MA_TRACEBLE, 0,"Traceable", 245,160,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to being detected by ray tracing"); - uiDefButBitI(block, TOG, MA_SHADBUF, 0, "Shadbuf", 245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to cast shadows with shadow buffers"); + uiDefButBitI(block, TOG, MA_TRACEBLE, B_NOP,"Traceable", 245,160,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to being detected by ray tracing"); + uiDefButBitI(block, TOG, MA_SHADBUF, B_NOP, "Shadbuf", 245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Makes material to cast shadows with shadow buffers"); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, MA_SHADOW, 0, "Shadow", 245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows"); - uiDefButBitI(block, TOG, MA_SHADOW_TRA, 0, "TraShadow", 245,100,65,19, &(ma->mode), 0, 0, 0, 0, "Recieves transparent shadows based at material color and alpha"); - uiDefButBitI(block, TOG, MA_RAYBIAS, 0, "Bias", 245,80,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)"); + uiDefButBitI(block, TOG, MA_SHADOW, B_NOP, "Shadow", 245,120,65,19, &(ma->mode), 0, 0, 0, 0, "Makes material receive shadows"); + uiDefButBitI(block, TOG, MA_SHADOW_TRA, B_NOP, "TraShadow", 245,100,65,19, &(ma->mode), 0, 0, 0, 0, "Recieves transparent shadows based at material color and alpha"); + uiDefButBitI(block, TOG, MA_RAYBIAS, B_NOP, "Bias", 245,80,65,19, &(ma->mode), 0, 0, 0, 0, "Prevents ray traced shadow errors with phong interpolated normals (terminator problem)"); uiBlockEndAlign(block); uiDefIDPoinBut(block, test_grouppoin_but, ID_GR, B_NOP, "GR:", 9, 55, 150, 19, &ma->group, "Limit Lighting to Lamps in this Group"); - - uiDefButBitI(block, TOG, MA_RADIO, 0, "Radio", 245,55,65,19, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosity rendering"); + + uiDefButBitI(block, TOG, MA_TANGENT_V, B_MATPRV, "Tangent V", 170,55,65,19, &(ma->mode), 0, 0, 0, 0, "Use the tangent vector in V direction for shading"); + uiDefButBitI(block, TOG, MA_RADIO, B_NOP, "Radio", 245,55,65,19, &(ma->mode), 0, 0, 0, 0, "Enables material for radiosity rendering"); } } diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c index 3667b170270..e53e7a30097 100644 --- a/source/blender/src/previewrender.c +++ b/source/blender/src/previewrender.c @@ -734,7 +734,7 @@ static void shade_lamp_loop_preview(ShadeInput *shi, ShadeResult *shr, int pr_la extern float fresnel_fac(float *view, float *vn, float ior, float fac); Material *mat= shi->mat; float inp, is, inprspec=0; - float lv[3], *la; + float lv[3], *la, *vn, vnor[3]; int a; // copy all relevant material vars, note, keep this synced with render_types.h @@ -779,47 +779,57 @@ static void shade_lamp_loop_preview(ShadeInput *shi, ShadeResult *shr, int pr_la lv[2]= shi->co[2]-la[2]; Normalise(lv); - is= shi->vn[0]*lv[0]+shi->vn[1]*lv[1]+shi->vn[2]*lv[2]; - if(is<0.0f) is= 0.0f; - if(shi->spec>0.0f) { + /* specular shaders */ + float specfac; - if(is>0.0f) { - /* specular shaders */ - float specfac; - - if(mat->spec_shader==MA_SPEC_PHONG) - specfac= Phong_Spec(shi->vn, lv, shi->view, shi->har, 0); - else if(mat->spec_shader==MA_SPEC_COOKTORR) - specfac= CookTorr_Spec(shi->vn, lv, shi->view, shi->har, 0); - else if(mat->spec_shader==MA_SPEC_BLINN) - specfac= Blinn_Spec(shi->vn, lv, shi->view, mat->refrac, (float)shi->har, 0); - else if(mat->spec_shader==MA_SPEC_WARDISO) - specfac= WardIso_Spec(shi->vn, lv, shi->view, mat->rms, 0); - else - specfac= Toon_Spec(shi->vn, lv, shi->view, mat->param[2], mat->param[3], 0); - - inprspec= specfac*shi->spec; - - if(mat->mode & MA_RAMP_SPEC) { - float spec[3]; - do_specular_ramp(shi, specfac, inprspec, spec); - shr->spec[0]+= inprspec*spec[0]; - shr->spec[1]+= inprspec*spec[1]; - shr->spec[2]+= inprspec*spec[2]; - } - else { - shr->spec[0]+= inprspec*shi->specr; - shr->spec[1]+= inprspec*shi->specg; - shr->spec[2]+= inprspec*shi->specb; - } + if(mat->mode & MA_TANGENT_V) vn= shi->tang; + else vn= shi->vn; + + if(mat->spec_shader==MA_SPEC_PHONG) + specfac= Phong_Spec(vn, lv, shi->view, shi->har, mat->mode & MA_TANGENT_V); + else if(mat->spec_shader==MA_SPEC_COOKTORR) + specfac= CookTorr_Spec(vn, lv, shi->view, shi->har, mat->mode & MA_TANGENT_V); + else if(mat->spec_shader==MA_SPEC_BLINN) + specfac= Blinn_Spec(vn, lv, shi->view, mat->refrac, (float)shi->har, mat->mode & MA_TANGENT_V); + else if(mat->spec_shader==MA_SPEC_WARDISO) + specfac= WardIso_Spec(vn, lv, shi->view, mat->rms, mat->mode & MA_TANGENT_V); + else + specfac= Toon_Spec(vn, lv, shi->view, mat->param[2], mat->param[3], mat->mode & MA_TANGENT_V); + + inprspec= specfac*shi->spec; + + if(mat->mode & MA_RAMP_SPEC) { + float spec[3]; + do_specular_ramp(shi, specfac, inprspec, spec); + shr->spec[0]+= inprspec*spec[0]; + shr->spec[1]+= inprspec*spec[1]; + shr->spec[2]+= inprspec*spec[2]; + } + else { + shr->spec[0]+= inprspec*shi->specr; + shr->spec[1]+= inprspec*shi->specg; + shr->spec[2]+= inprspec*shi->specb; } } + + if(mat->mode & MA_TANGENT_V) { + float cross[3]; + Crossf(cross, lv, shi->tang); + Crossf(vnor, cross, shi->tang); + vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2]; + vn= vnor; + } + else vn= shi->vn; + + is= vn[0]*lv[0]+vn[1]*lv[1]+vn[2]*lv[2]; + if(is<0.0f) is= 0.0f; + /* diffuse shaders */ - if(mat->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(shi->vn, lv, shi->view, mat->roughness); - else if(mat->diff_shader==MA_DIFF_TOON) is= Toon_Diff(shi->vn, lv, shi->view, mat->param[0], mat->param[1]); - else if(mat->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(is, shi->vn, shi->view, mat->darkness); - else if(mat->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(shi->vn, lv, shi->view, mat->param[0], mat->param[1]); + if(mat->diff_shader==MA_DIFF_ORENNAYAR) is= OrenNayar_Diff(vn, lv, shi->view, mat->roughness); + else if(mat->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, shi->view, mat->param[0], mat->param[1]); + else if(mat->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(is, vn, shi->view, mat->darkness); + else if(mat->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, shi->view, mat->param[0], mat->param[1]); // else Lambert inp= (shi->refl*is + shi->emit); @@ -1287,6 +1297,14 @@ void BIF_previewrender(SpaceButs *sbuts) vec[1]= shi.vn[2]; vec[2]= -shi.vn[1]; + if(mat->mode & MA_TANGENT_V) { + float tmp[3]; + tmp[0]=tmp[2]= 0.0f; + tmp[1]= 1.0f; + Crossf(shi.tang, tmp, shi.vn); + Normalise(shi.tang); + } + shade_preview_pixel(&shi, vec, x, y, (char *)rect, 1); } else { -- cgit v1.2.3