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:
authorTon Roosendaal <ton@blender.org>2005-12-09 18:14:32 +0300
committerTon Roosendaal <ton@blender.org>2005-12-09 18:14:32 +0300
commit485dd1d37673d229db9062d8cad98e624d79c8ec (patch)
tree4594dc9f61d65286c430a304ba11742f1acea818
parentc492729b3a0d52ae01ee67e5ad92bdb02f6585df (diff)
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. :)
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h3
-rw-r--r--source/blender/makesdna/DNA_material_types.h7
-rw-r--r--source/blender/render/intern/source/rendercore.c59
-rw-r--r--source/blender/render/intern/source/renderdatabase.c3
-rw-r--r--source/blender/render/intern/source/texture.c29
-rw-r--r--source/blender/renderconverter/intern/convertBlenderScene.c91
-rw-r--r--source/blender/src/buttons_shading.c59
-rw-r--r--source/blender/src/previewrender.c92
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; a<R.totvlak; a++) {
VlakRen *vlr= RE_findOrAddVlak(a);
if(vlr->flag & 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; a<R.totvert; a++) {
VertRen *ver= RE_findOrAddVert(a);
Normalise(ver->n);
+ 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; a<R.totvlak; a++) {
vlr= RE_findOrAddVlak(a);
@@ -3066,6 +3137,6 @@ static void do_displacement(Object *ob, int startface, int numface, int startver
}
/* Recalc vertex normals */
- calc_vertexnormals(startvert, startface);
+ calc_vertexnormals(startvert, startface, 0);
}
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index b697d4cab34..27504e1d2e0 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -2856,27 +2856,29 @@ static void material_panel_map_input(Object *ob, Material *ma)
/* TEXCO */
uiBlockBeginAlign(block);
- uiDefButS(block, ROW, B_MATPRV, "UV", 630,166,40,18, &(mtex->texco), 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 {