Index: release/scripts/ui/properties_material.py =================================================================== --- release/scripts/ui/properties_material.py (revision 35115) +++ release/scripts/ui/properties_material.py (working copy) @@ -294,8 +294,11 @@ row = col.row() row.prop(mat, "specular_hardness", text="Hardness") row.prop(mat, "specular_ior", text="IOR") - elif mat.specular_shader == 'WARDISO': - col.prop(mat, "specular_slope", text="Slope") + elif mat.specular_shader == 'WARDANSIO': + #col.prop(mat, "specular_slope", text="Slope") + col.prop(mat, "specular_slope_x", text="SlopeX") + col.prop(mat, "specular_slope_y", text="SlopeY") + col.prop(mat, "specular_slope_rot", text="Rot") elif mat.specular_shader == 'TOON': row = col.row() row.prop(mat, "specular_toon_size", text="Size") Index: source/blender/render/intern/source/shadeoutput.c =================================================================== --- source/blender/render/intern/source/shadeoutput.c (revision 35115) +++ source/blender/render/intern/source/shadeoutput.c (working copy) @@ -667,38 +667,62 @@ return rslt; } -/* Ward isotropic gaussian spec */ -static float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent) -{ - float i, nh, nv, nl, h[3], angle, alpha; +/* Ward anistropic distrbution spec */ +static float WardAnsio_Spec( float *n, float *l, float *v, float rmsx, float rmsy, float rot, float *tangent) + { + float i, y[3], x[3], hx, hy, hn, nv, nl, h[3], alphax, alphay; + + //if (tangent){ + normalize_v3(tangent); + cross_v3_v3v3(x, n, tangent); // bitangent + VECCOPY(y, tangent); + /*} + else VecOrthoBasisf(n, x, y);*/ + + /*translate rot into the x vector and find y using x*/ + if (rot > 0.0f && rot < 1.0f) { + float angle = rot*(float)M_PI*2.f; + float cosa = cosf(angle); + float sina = sinf(angle); + x[0] = cosa*x[0] + sina*y[0]; + x[1] = cosa*x[1] + sina*y[1]; + x[2] = cosa*x[2] + sina*y[2]; + cross_v3_v3v3(y, x, n); + } + /* half-way vector */ h[0] = l[0] + v[0]; h[1] = l[1] + v[1]; h[2] = l[2] + v[2]; + + /* all vectors must be unit vectors*/ normalize_v3(h); + normalize_v3(n); + normalize_v3(l); + normalize_v3(v); + normalize_v3(x); + normalize_v3(y); - nh = n[0]*h[0]+n[1]*h[1]+n[2]*h[2]; /* Dot product between surface normal and half-way vector */ - if(tangent) nh = sasqrt(1.0f - nh*nh); - if(nh<=0.0f) nh = 0.001f; - - nv = n[0]*v[0]+n[1]*v[1]+n[2]*v[2]; /* Dot product between surface normal and view vector */ - if(tangent) nv = sasqrt(1.0f - nv*nv); - if(nv<=0.0f) nv = 0.001f; + hn = INPR(h, n); /* Dot product between surface normal and half-way vector */ - nl = n[0]*l[0]+n[1]*l[1]+n[2]*l[2]; /* Dot product between surface normal and light vector */ - if(tangent) nl = sasqrt(1.0f - nl*nl); - if(nl<=0.0f) nl = 0.001f; + nv = INPR(n, v); /* Dot product between surface normal and view vector */ + if(nv<=0.0f) return 0; + + nl = INPR(n, l); /* Dot product between surface normal and light vector */ + if(nl<=0.0f) return 0; - angle = tan(saacos(nh)); - alpha = MAX2(rms, 0.001f); + hx = INPR(h, x); + hy = INPR(h, y); + + alphax = MAX2(rmsx, 0.001f); + alphay = MAX2(rmsy, 0.001f); - i= nl * (1.0f/(4.0f*M_PI*alpha*alpha)) * (exp( -(angle*angle)/(alpha*alpha))/(sqrt(nv*nl))); + i = ((1.0f/sqrt(nl*nv))*(nl/(4.0f*alphax*alphay)*(exp(-2.0f*((((hx/alphax)*(hx/alphax)) + ((hy/alphay)*(hy/alphay)))/(1.0f+hn)))))); + return i; + } - return i; -} - /* cartoon render diffuse */ static float Toon_Diff( float *n, float *l, float *v, float size, float smooth ) { @@ -1217,7 +1241,7 @@ Material *ma= shi->mat; VlakRen *vlr= shi->vlr; float lv[3], lampdist, lacol[3], shadfac[4], lashdw[3]; - float i, is, i_noshad, inp, *vn, *view, vnor[3], phongcorr=1.0f; + float i, is, i_noshad, inp, *vn, *view, *tangent, vnor[3], phongcorr=1.0f; float visifac; vn= shi->vn; @@ -1265,7 +1289,7 @@ /* tangent case; calculate fake face normal, aligned with lampvector */ /* note, vnor==vn is used as tangent trigger for buffer shadow */ - if(vlr->flag & R_TANGENT) { + if((vlr->flag & R_TANGENT)&&(ma->spec_shader != MA_SPEC_WARDANSIO)) { float cross[3], nstrand[3], blend; if(ma->mode & MA_STR_SURFDIFF) { @@ -1296,7 +1320,7 @@ vnor[0]= -vnor[0];vnor[1]= -vnor[1];vnor[2]= -vnor[2]; vn= vnor; } - else if (ma->mode & MA_TANGENT_V) { + else if ((ma->mode & MA_TANGENT_V)&&(ma->spec_shader != MA_SPEC_WARDANSIO)) { float cross[3]; cross_v3_v3v3(cross, lv, shi->tang); cross_v3_v3v3(vnor, cross, shi->tang); @@ -1362,7 +1386,7 @@ i_noshad= i; vn= shi->vn; // bring back original vector, we use special specular shaders for tangent - if(ma->mode & MA_TANGENT_V) + if((ma->mode & MA_TANGENT_V)&&(ma->spec_shader != MA_SPEC_WARDANSIO)) vn= shi->tang; /* init transp shadow */ @@ -1460,8 +1484,20 @@ 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) || (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) || (ma->mode & MA_TANGENT_V)); + else if(ma->spec_shader==MA_SPEC_WARDANSIO){ + /*float obn[3] = {0.0f,0.0f,0.0f}; + float tmat[4][4];*/ + + /* put the current surface normal into object space*/ + /*Mat4Invert( tmat, shi->obi->mat); + VECCOPY(obn, vn); + Mat4Mul3Vecfl( tmat, obn ); + Normalize( obn ); + if ((vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V))tangent= shi->tang; + else tangent = NULL;*/ + + specfac= WardAnsio_Spec(vn, lv, view, ma->rmsx, ma->rmsy, ma->rot, shi->nmaptang); + } else specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); Index: source/blender/makesdna/DNA_material_types.h =================================================================== --- source/blender/makesdna/DNA_material_types.h (revision 35115) +++ source/blender/makesdna/DNA_material_types.h (working copy) @@ -129,7 +129,7 @@ /* XXX param[4] needs review and improvement (shader system as whole anyway) This is nasty reused variable for different goals and not easy to RNAify nicely. -jesterKing */ float param[4]; /* size, smooth, size, smooth, for toonshader, 0 (fac) and 1 (fresnel) also for fresnel shader */ - float rms; + float rms,rmsx,rmsy,rot,pad5; float darkness; short texco, mapto; @@ -255,7 +255,7 @@ #define MA_SPEC_PHONG 1 #define MA_SPEC_BLINN 2 #define MA_SPEC_TOON 3 -#define MA_SPEC_WARDISO 4 +#define MA_SPEC_WARDANSIO 4 /* dynamode */ #define MA_DRAW_DYNABUTS 1 /* deprecated */ Index: source/blender/gpu/intern/gpu_material.c =================================================================== --- source/blender/gpu/intern/gpu_material.c (revision 35115) +++ source/blender/gpu/intern/gpu_material.c (working copy) @@ -728,7 +728,7 @@ GPU_link(mat, "shade_cooktorr_spec", vn, lv, view, shi->har, &specfac); else if(ma->spec_shader==MA_SPEC_BLINN) GPU_link(mat, "shade_blinn_spec", vn, lv, view, GPU_uniform(&ma->refrac), shi->har, &specfac); - else if(ma->spec_shader==MA_SPEC_WARDISO) + else if(ma->spec_shader==MA_SPEC_WARDANSIO) GPU_link(mat, "shade_wardiso_spec", vn, lv, view, GPU_uniform(&ma->rms), &specfac); else GPU_link(mat, "shade_toon_spec", vn, lv, view, GPU_uniform(&ma->param[2]), GPU_uniform(&ma->param[3]), &specfac); Index: source/blender/makesrna/intern/rna_material.c =================================================================== --- source/blender/makesrna/intern/rna_material.c (revision 35115) +++ source/blender/makesrna/intern/rna_material.c (working copy) @@ -1388,7 +1388,7 @@ {MA_SPEC_PHONG, "PHONG", 0, "Phong", ""}, {MA_SPEC_BLINN, "BLINN", 0, "Blinn", ""}, {MA_SPEC_TOON, "TOON", 0, "Toon", ""}, - {MA_SPEC_WARDISO, "WARDISO", 0, "WardIso", ""}, + {MA_SPEC_WARDANSIO, "WARDANSIO", 0, "WardAnsio", ""}, {0, NULL, 0, NULL, NULL}}; prop= RNA_def_property(srna, "specular_shader", PROP_ENUM, PROP_NONE); @@ -1437,6 +1437,24 @@ RNA_def_property_range(prop, 0, 0.4); RNA_def_property_ui_text(prop, "Specular Slope", "The standard deviation of surface slope"); RNA_def_property_update(prop, 0, "rna_Material_update"); + + prop= RNA_def_property(srna, "specular_slope_x", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "rmsx"); + RNA_def_property_range(prop, 0, 0.4); + RNA_def_property_ui_text(prop, "Specular Slope X", "The standard deviation of surface slope on the X axis"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + + prop= RNA_def_property(srna, "specular_slope_y", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "rmsy"); + RNA_def_property_range(prop, 0, 0.4); + RNA_def_property_ui_text(prop, "Specular Slope Y", "The standard deviation of surface slope on the Y axis"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + + prop= RNA_def_property(srna, "specular_slope_rot", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "rot"); + RNA_def_property_range(prop, 0, 0.4); + RNA_def_property_ui_text(prop, "Specular Slope Rot", "Rotation of the standard deviation of surface slope"); + RNA_def_property_update(prop, 0, "rna_Material_update"); } static void rna_def_material_strand(BlenderRNA *brna)