Revert bump mapping patch for now, backwards compatibility is not good enough,

we may need to preserve the previous method.
This commit is contained in:
Brecht Van Lommel 2011-01-07 16:55:56 +00:00
parent f01cac08e7
commit b9fe5399e8
4 changed files with 174 additions and 127 deletions

View File

@ -995,7 +995,7 @@ class TEXTURE_PT_influence(TextureSlotPanel, bpy.types.Panel):
col.prop(tex, "color", text="")
if isinstance(idblock, bpy.types.Material):
sub = col.row()
sub = layout.row()
sub.prop(tex, "bump_method", text="Bump Method")
sub.active = tex.use_map_normal

View File

@ -455,7 +455,6 @@ typedef struct TexMapping {
#define MTEX_DUPLI_MAPTO 32
#define MTEX_OB_DUPLI_ORIG 64
#define MTEX_NEW_BUMP 128
#define MTEX_5TAP_BUMP 256
/* blendtype */
#define MTEX_BLEND 0

View File

@ -368,9 +368,8 @@ static void rna_def_material_mtex(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem prop_bump_method_items[] = {
{0, "BUMP_OLD", 0, "Old Bump", ""},
{MTEX_NEW_BUMP, "BUMP_3_TAP", 0, "3-Tap", ""},
{MTEX_NEW_BUMP|MTEX_5TAP_BUMP, "BUMP_5_TAP", 0, "5-Tap", ""},
{0, "BUMP_ORIGINAL", 0, "Original", ""},
{MTEX_NEW_BUMP, "BUMP_IMPROVED", 0, "Improved", ""},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "MaterialTextureSlot", "TextureSlot");

View File

@ -1677,12 +1677,9 @@ void do_material_tex(ShadeInput *shi)
float fact, facm, factt, facmm, stencilTin=1.0;
float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0;
int tex_nr, rgbnor= 0, warpdone=0;
float nu[3] = {0,0,0}, nv[3] = {0,0,0}, nn[3] = {0,0,0}, dudnu = 1.f, dudnv = 0.f, dvdnu = 0.f, dvdnv = 1.f; // bump mapping
int nunvdone= 0, newbump;
// bumpmapping
float vNacc[3]; // original surface normal minus the surface gradient of every bump map which is encountered
float vR1[3], vR2[3]; // cross products (sigma_y, original_normal), (original_normal, sigma_x)
float sgn_det=0.0f; // sign of the determinant of the matrix {sigma_x, sigma_y, original_normal}
if (R.r.scemode & R_NO_TEX) return;
/* here: test flag if there's a tex (todo) */
@ -1708,9 +1705,7 @@ void do_material_tex(ShadeInput *shi)
dyt[0]= dyt[1]= dyt[2]= 0.0f;
}
else {
co= shi->lo;
dx= shi->dxlo;
dy= shi->dylo;
co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
}
}
else if(mtex->texco==TEXCO_STICKY) {
@ -1773,8 +1768,59 @@ void do_material_tex(ShadeInput *shi)
co= suv->uv;
dx= suv->dxuv;
dy= suv->dyuv;
dy= suv->dyuv;
// uvmapping only, calculation of normal tangent u/v partial derivatives
// (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct,
// nu/nv in ShadeInput and this calculation should then move to shadeinput.c, shade_input_set_shade_texco() func.)
// NOTE: test for shi->obr->ob here, since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it..
// NOTE: shi->v1 is NULL when called from displace_render_vert, assigning verts in this case is not trivial because the shi quad face side is not know.
if ((mtex->texflag & MTEX_NEW_BUMP) && shi->obr && shi->obr->ob && shi->v1) {
if(mtex->mapto & (MAP_NORM|MAP_WARP) && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) {
MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0);
int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
// compute ortho basis around normal
if(!nunvdone) {
// render normal is negated
nn[0] = -shi->vn[0];
nn[1] = -shi->vn[1];
nn[2] = -shi->vn[2];
ortho_basis_v3v3_v3( nu, nv,nn);
nunvdone= 1;
}
if (tf) {
float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
const float an[3] = {fabsf(nn[0]), fabsf(nn[1]), fabsf(nn[2])};
const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0;
const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2;
const float dp1_a1 = shi->v1->co[a1] - shi->v3->co[a1];
const float dp1_a2 = shi->v1->co[a2] - shi->v3->co[a2];
const float dp2_a1 = shi->v2->co[a1] - shi->v3->co[a1];
const float dp2_a2 = shi->v2->co[a2] - shi->v3->co[a2];
const float du1 = uv1[0] - uv3[0], du2 = uv2[0] - uv3[0];
const float dv1 = uv1[1] - uv3[1], dv2 = uv2[1] - uv3[1];
const float dpdu_a1 = dv2*dp1_a1 - dv1*dp2_a1;
const float dpdu_a2 = dv2*dp1_a2 - dv1*dp2_a2;
const float dpdv_a1 = du1*dp2_a1 - du2*dp1_a1;
const float dpdv_a2 = du1*dp2_a2 - du2*dp1_a2;
float d = dpdu_a1*dpdv_a2 - dpdv_a1*dpdu_a2;
float uvd = du1*dv2 - dv1*du2;
if (uvd == 0.f) uvd = 1e-5f;
if (d == 0.f) d = 1e-5f;
d = uvd / d;
dudnu = (dpdv_a2*nu[a1] - dpdv_a1*nu[a2])*d;
dvdnu = (dpdu_a1*nu[a2] - dpdu_a2*nu[a1])*d;
dudnv = (dpdv_a2*nv[a1] - dpdv_a1*nv[a2])*d;
dvdnv = (dpdu_a1*nv[a2] - dpdu_a2*nv[a1])*d;
}
}
}
}
}
else if(mtex->texco==TEXCO_WINDOW) {
@ -1808,140 +1854,142 @@ void do_material_tex(ShadeInput *shi)
else texres.nor= NULL;
if(warpdone) {
VECADD(tempvec, co, warpvec)
VECADD(tempvec, co, warpvec);
co= tempvec;
}
/* XXX texture node trees don't work for this yet */
if(newbump) {
// compute ortho basis around normal
if(!nunvdone) {
// render normal is negated
nn[0] = -shi->vn[0];
nn[1] = -shi->vn[1];
nn[2] = -shi->vn[2];
ortho_basis_v3v3_v3( nu, nv,nn);
nunvdone= 1;
}
if(texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) {
TexResult ttexr = {0, 0, 0, 0, 0, texres.talpha, NULL}; // temp TexResult
float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
const float Hscale = 0.016f * Tnor*stencilTin*mtex->norfac; // factor 0.016 proved to look like the previous bump code
// 2 channels for 2D texture and 3 for 3D textures.
const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3;
int c;
float dHdx, dHdy;
// disable internal bump eval in sampler, save pointer
float *nvec = texres.nor;
const float bf = 0.04f*Tnor*stencilTin*mtex->norfac;
// disable internal bump eval
float* nvec = texres.nor;
texres.nor = NULL;
// du & dv estimates, constant value defaults
du = dv = 0.01f;
if(!(mtex->texflag & MTEX_5TAP_BUMP)) {
// compute height derivatives with respect to output image pixel coordinates x and y
float STll[3], STlr[3], STul[3];
float Hll, Hlr, Hul;
// two methods, either constant based on main image resolution,
// (which also works without osa, though of course not always good (or even very bad) results),
// or based on tex derivative max values (osa only). Not sure which is best...
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
for(c=0; c<nr_channels; c++) {
// dx contains the derivatives (du/dx, dv/dx)
// dy contains the derivatives (du/dy, dv/dy)
STll[c] = texvec[c];
STlr[c] = texvec[c]+dxt[c];
STul[c] = texvec[c]+dyt[c];
if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
// in case we have no proper derivatives, fall back to
// computing du/dv it based on image size
ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
if (ibuf) {
du = 1.f/(float)ibuf->x;
dv = 1.f/(float)ibuf->y;
}
// clear unused derivatives
for(c=nr_channels; c<3; c++) {
STll[c] = 0.0f;
STlr[c] = 0.0f;
STul[c] = 0.0f;
}
else if (shi->osatex) {
// we have derivatives, can compute proper du/dv
if (tex->type == TEX_IMAGE) { // 2d image, use u & v max. of dx/dy 2d vecs
const float adx[2] = {fabsf(dx[0]), fabsf(dx[1])};
const float ady[2] = {fabsf(dy[0]), fabsf(dy[1])};
du = MAX2(adx[0], ady[0]);
dv = MAX2(adx[1], ady[1]);
}
// use texres for the center sample, set rgbnor
rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, &texres);
Hll = (fromrgb)? (texres.tr + texres.tg + texres.tb)*0.33333333f: texres.tin;
// use ttexr for the other 2 taps
multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr);
Hlr = (fromrgb)? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f: ttexr.tin;
multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr);
Hul = (fromrgb)? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f: ttexr.tin;
dHdx = Hscale*(Hlr - Hll);
dHdy = Hscale*(Hul - Hll);
else { // 3d procedural, estimate from all dx/dy elems
const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])};
const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])};
du = MAX3(adx[0], adx[1], adx[2]);
dv = MAX3(ady[1], ady[1], ady[2]);
}
}
// center, main return value
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres);
cd = fromrgb ? (texres.tr + texres.tg + texres.tb)*0.33333333f : texres.tin;
if (mtex->texco == TEXCO_UV) {
// for the uv case, use the same value for both du/dv,
// since individually scaling the normal derivatives makes them useless...
du = MIN2(du, dv);
idu = (du < 1e-5f) ? bf : (bf/du);
// +u val
tco[0] = co[0] + dudnu*du;
tco[1] = co[1] + dvdnu*du;
tco[2] = 0.f;
texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
// +v val
tco[0] = co[0] + dudnv*du;
tco[1] = co[1] + dvdnv*du;
tco[2] = 0.f;
texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
}
else {
/* same as above, but doing 5 taps, increasing quality at cost of speed */
float STc[3], STl[3], STr[3], STd[3], STu[3];
float Hc, Hl, Hr, Hd, Hu;
float tu[3] = {nu[0], nu[1], nu[2]}, tv[3] = {nv[0], nv[1], nv[2]};
texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
idu = (du < 1e-5f) ? bf : (bf/du);
idv = (dv < 1e-5f) ? bf : (bf/dv);
for(c=0; c<nr_channels; c++) {
STc[c] = texvec[c];
STl[c] = texvec[c] - 0.5f*dxt[c];
STr[c] = texvec[c] + 0.5f*dxt[c];
STd[c] = texvec[c] - 0.5f*dyt[c];
STu[c] = texvec[c] + 0.5f*dyt[c];
if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) {
mul_mat3_m4_v3(shi->obr->ob->imat, tu);
mul_mat3_m4_v3(shi->obr->ob->imat, tv);
normalize_v3(tu);
normalize_v3(tv);
}
else if (mtex->texco == TEXCO_GLOB) {
mul_mat3_m4_v3(R.viewinv, tu);
mul_mat3_m4_v3(R.viewinv, tv);
}
else if (mtex->texco == TEXCO_OBJECT && mtex->object) {
mul_mat3_m4_v3(mtex->object->imat, tu);
mul_mat3_m4_v3(mtex->object->imat, tv);
normalize_v3(tu);
normalize_v3(tv);
}
// clear unused derivatives
for(c=nr_channels; c<3; c++) {
STc[c] = 0.0f;
STl[c] = 0.0f;
STr[c] = 0.0f;
STd[c] = 0.0f;
STu[c] = 0.0f;
}
// use texres for the center sample, set rgbnor
rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, &texres);
Hc = (fromrgb)? (texres.tr + texres.tg + texres.tb)*0.33333333f: texres.tin;
// use ttexr for the other taps
multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr);
Hl = (fromrgb)? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f: ttexr.tin;
multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr);
Hr = (fromrgb)? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f: ttexr.tin;
multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr);
Hd = (fromrgb)? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f: ttexr.tin;
multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr);
Hu = (fromrgb)? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f: ttexr.tin;
dHdx = Hscale*(Hr - Hl);
dHdy = Hscale*(Hu - Hd);
// +u val
tco[0] = co[0] + tu[0]*du;
tco[1] = co[1] + tu[1]*du;
tco[2] = co[2] + tu[2]*du;
texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
// +v val
tco[0] = co[0] + tv[0]*dv;
tco[1] = co[1] + tv[1]*dv;
tco[2] = co[2] + tv[2]*dv;
texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
}
// restore pointer
// bumped normal
nu[0] += ud*nn[0];
nu[1] += ud*nn[1];
nu[2] += ud*nn[2];
nv[0] += vd*nn[0];
nv[1] += vd*nn[1];
nv[2] += vd*nn[2];
cross_v3_v3v3(nvec, nu, nv);
nvec[0] = -nvec[0];
nvec[1] = -nvec[1];
nvec[2] = -nvec[2];
texres.nor = nvec;
/* replaced newbump with code based on listing 1 and 2 of
[Mik08] Mikkelsen M. S.: Simulation of Wrinkled Surfaces Revisited.
-> http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf */
if(!nunvdone) {
// initialize normal perturbation vectors
float *dPdx = shi->dxco;
float *dPdy = shi->dyco;
float *vN = shi->vn;
int xyz;
float fDet;
cross_v3_v3v3(vR1, dPdy, vN);
cross_v3_v3v3(vR2, vN, dPdx);
fDet = dot_v3v3(dPdx, vR1);
sgn_det = (fDet < 0)? -1.0f: 1.0f;
for(xyz=0; xyz<3; xyz++)
vNacc[xyz] = (sgn_det * fDet) * vN[xyz];
nunvdone= 1;
}
// subtract the surface gradient from vNacc
for(c=0; c<3; c++) {
float vSurfGrad_compi = sgn_det * (dHdx * vR1[c] + dHdy * vR2[c]);
vNacc[c] -= vSurfGrad_compi;
texres.nor[c] = vNacc[c]; // copy
}
rgbnor |= TEX_NOR;
}
else {
@ -1955,7 +2003,7 @@ void do_material_tex(ShadeInput *shi)
}
/* texture output */
if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
rgbnor-= TEX_RGB;
@ -2084,7 +2132,7 @@ void do_material_tex(ShadeInput *shi)
}
}
}
if( mtex->mapto & MAP_NORM ) {
if( (mtex->mapto & MAP_NORM) ) {
if(texres.nor) {
float norfac= mtex->norfac;
@ -2285,6 +2333,7 @@ void do_material_tex(ShadeInput *shi)
}
}
void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, float *val)
{
MTex *mtex;