Index: source/blender/render/intern/source/shadeoutput.c =================================================================== --- source/blender/render/intern/source/shadeoutput.c (revisjon 16766) +++ source/blender/render/intern/source/shadeoutput.c (arbeidskopi) @@ -666,9 +666,9 @@ } /* Ward isotropic gaussian spec */ -static float WardIso_Spec( float *n, float *l, float *v, float rms, int tangent) +static float WardIso_Spec(float *n, float *l, float *v, float rms, int tangent) { - float i, nh, nv, nl, h[3], angle, alpha; + float i, nh, nv, nl, h[3], angle, alpha, alpha2; /* half-way vector */ @@ -692,13 +692,74 @@ angle = tan(saacos(nh)); alpha = MAX2(rms, 0.001f); - i= nl * (1.0f/(4.0f*M_PI*alpha*alpha)) * (exp( -(angle*angle)/(alpha*alpha))/(sqrt(nv*nl))); + alpha2 = alpha * alpha; + i= nl * (1.0f/(4.0f*M_PI*alpha2)) * (exp( -(angle*angle)/alpha2)/(sqrt(nv*nl))); return i; } +/* Beckmann spec */ +static float Beckmann_Spec(float *n, float *l, float *v, float slope, float gloss, int phong_hard, int tangent) +{ + float i, nh, a, b, c, d, e, h[3], angle; + + /* Half-way vector */ + h[0] = l[0] + v[0]; + h[1] = l[1] + v[1]; + h[2] = l[2] + v[2]; + Normalize(h); + + /* Dot product between surface normal and half-way vector */ + nh = n[0]*h[0] + n[1]*h[1] + n[2]*h[2]; + if (tangent) nh = sasqrt(1.0f - nh*nh); + if (nh <= 0.0f) nh = 0.001f; + + /* Use the Beckmann distribution to calculate the specular light */ + angle = saacos(nh); + a = tan(angle) / slope; + b = cos(angle); + c = b * b; + d = - (a * b); + e = 4.0f * slope * slope * c * c; + i = exp(d) / e; + + /* Add some phong highlight */ + if (gloss > 0.0f) { + if (nh > 0.0f) nh = spec(angle, phong_hard); + else nh = 0.0f; + i = i*(1.0f - gloss) + nh*gloss; + } + + /* Make sure it's within range */ + if (i < 0.0f) i = 0.0f; + else if (i > 1.0f) i = 1.0f; + + return i; + +} + +/* KajiyaKay spec */ +/* t means tangent to strand */ +static float KajiyaKay_Spec(float *t, float *l, float *v, int hard) +{ + float tl, tv, i, a[3], stl, stv, r; + + tl = Inpf(t, l); + tv = Inpf(t, v); + + CROSS(a, t, l); + stl = sasqrt(Inpf(a,a)); + + CROSS(a, t, v); + stv = sasqrt(Inpf(a,a)); + + r =(tl*tv + stl*stv); + + return spec(r, hard); +} + /* cartoon render diffuse */ -static float Toon_Diff( float *n, float *l, float *v, float size, float smooth ) +static float Toon_Diff(float *n, float *l, float *v, float size, float smooth) { float rslt, ang; @@ -717,11 +778,12 @@ /* 'nl' is either dot product, or return value of area light */ /* in latter case, only last multiplication uses 'nl' */ -static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float rough ) +static float OrenNayar_Diff(float nl, float *n, float *l, float *v, float rough) { float i, nh, nv, vh, realnl, h[3]; float a, b, t, A, B; float Lit_A, View_A, Lit_B[3], View_B[3]; + float rough2; h[0]= v[0]+l[0]; h[1]= v[1]+l[1]; @@ -766,8 +828,9 @@ b = Lit_A; } - A = 1.0f - (0.5f * ((rough * rough) / ((rough * rough) + 0.33f))); - B = 0.45f * ((rough * rough) / ((rough * rough) + 0.09f)); + rough2 = rough * rough; + A = 1.0f - (0.5f * (rough2 / (rough2 + 0.33f))); + B = 0.45f * (rough2 / (rough2 + 0.09f)); b*= 0.95f; /* prevent tangens from shooting to inf, 'nl' can be not a dot product here. */ /* overflow only happens with extreme size area light, and higher roughness */ @@ -804,6 +867,16 @@ return fresnel_fac(lv, vn, fac_i, fac); } +/* Diffuse part of KajiyaKay */ +/* Is this really needed (don't other shaders do this */ +static float KajiyaKay_Diff(float *t, float *l) +{ + float a[3]; + CROSS(a, t, l); + return sasqrt(Inpf(a, a)); +} + + /* --------------------------------------------- */ /* also called from texture.c */ void calc_R_ref(ShadeInput *shi) @@ -1310,6 +1383,7 @@ else if(ma->diff_shader==MA_DIFF_TOON) is= Toon_Diff(vn, lv, view, ma->param[0], ma->param[1]); else if(ma->diff_shader==MA_DIFF_MINNAERT) is= Minnaert_Diff(inp, vn, view, ma->darkness); else if(ma->diff_shader==MA_DIFF_FRESNEL) is= Fresnel_Diff(vn, lv, view, ma->param[0], ma->param[1]); + else if(ma->diff_shader==MA_DIFF_KAJIYAKAY) is = KajiyaKay_Diff(vn, lv); else is= inp; // Lambert } @@ -1427,8 +1501,12 @@ 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 + else if(ma->spec_shader==MA_SPEC_KAJIYAKAY) + specfac= KajiyaKay_Spec(vn, lv, view, ma->har); + else if(ma->spec_shader==MA_SPEC_TOON) specfac= Toon_Spec(vn, lv, view, ma->param[2], ma->param[3], (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); + else + specfac= Beckmann_Spec(vn, lv, view, ma->slope, ma->gloss, 40.0f, (vlr->flag & R_TANGENT) || (ma->mode & MA_TANGENT_V)); /* area lamp correction */ if(lar->type==LA_AREA) specfac*= inp; Index: source/blender/python/api2_2x/Material.c =================================================================== --- source/blender/python/api2_2x/Material.c (revisjon 16766) +++ source/blender/python/api2_2x/Material.c (arbeidskopi) @@ -396,11 +396,15 @@ PyConstant_Insert(c, "DIFFUSE_ORENNAYAR", PyInt_FromLong(MA_DIFF_ORENNAYAR)); PyConstant_Insert(c, "DIFFUSE_TOON", PyInt_FromLong(MA_DIFF_TOON)); PyConstant_Insert(c, "DIFFUSE_MINNAERT", PyInt_FromLong(MA_DIFF_MINNAERT)); + PyConstant_Insert(c, "DIFFUSE_FRESNEL", PyInt_FromLong(MA_DIFF_FRESNEL)); + PyConstant_Insert(c, "DIFFUSE_KAJIYAKAY", PyInt_FromLong(MA_DIFF_KAJIYAKAY)); PyConstant_Insert(c, "SPEC_COOKTORR", PyInt_FromLong(MA_SPEC_COOKTORR)); PyConstant_Insert(c, "SPEC_PHONG", PyInt_FromLong(MA_SPEC_PHONG)); PyConstant_Insert(c, "SPEC_BLINN", PyInt_FromLong(MA_SPEC_BLINN)); PyConstant_Insert(c, "SPEC_TOON", PyInt_FromLong(MA_SPEC_TOON)); PyConstant_Insert(c, "SPEC_WARDISO", PyInt_FromLong(MA_SPEC_WARDISO)); + PyConstant_Insert(c, "SPEC_KAJIYAKAY", PyInt_FromLong(MA_SPEC_KAJIYAKAY)); + PyConstant_Insert(c, "SPEC_BECKMANN", PyInt_FromLong(MA_SPEC_BECKMANN)); } Index: source/blender/blenkernel/intern/material.c =================================================================== --- source/blender/blenkernel/intern/material.c (revisjon 16766) +++ source/blender/blenkernel/intern/material.c (arbeidskopi) @@ -128,6 +128,8 @@ ma->param[3]= 0.1; ma->rms= 0.1; ma->darkness= 1.0; + ma->slope= 0.1; + ma->gloss= 0.45; ma->strand_sta= ma->strand_end= 1.0f; Index: source/blender/makesdna/DNA_material_types.h =================================================================== --- source/blender/makesdna/DNA_material_types.h (revisjon 16766) +++ source/blender/makesdna/DNA_material_types.h (arbeidskopi) @@ -100,6 +100,7 @@ float param[4]; /* size, smooth, size, smooth, for toonshader */ float rms; float darkness; + float slope, gloss; short texco, mapto; /* ramp colors */ @@ -213,6 +214,7 @@ #define MA_DIFF_TOON 2 #define MA_DIFF_MINNAERT 3 #define MA_DIFF_FRESNEL 4 +#define MA_DIFF_KAJIYAKAY 5 /* spec_shader */ #define MA_SPEC_COOKTORR 0 @@ -220,6 +222,8 @@ #define MA_SPEC_BLINN 2 #define MA_SPEC_TOON 3 #define MA_SPEC_WARDISO 4 +#define MA_SPEC_BECKMANN 5 +#define MA_SPEC_KAJIYAKAY 6 /* dynamode */ #define MA_DRAW_DYNABUTS 1 Index: source/blender/src/buttons_shading.c =================================================================== --- source/blender/src/buttons_shading.c (revisjon 16766) +++ source/blender/src/buttons_shading.c (arbeidskopi) @@ -3978,8 +3978,8 @@ uiBlockEndAlign(block); } else { - char *str1= "Diffuse Shader%t|Lambert %x0|Oren-Nayar %x1|Toon %x2|Minnaert %x3|Fresnel %x4"; - char *str2= "Specular Shader%t|CookTorr %x0|Phong %x1|Blinn %x2|Toon %x3|WardIso %x4"; + char *str1= "Diffuse Shader%t|Lambert %x0|Oren-Nayar %x1|Toon %x2|Minnaert %x3|Fresnel %x4|Kajiya Kay %x5"; + char *str2= "Specular Shader%t|CookTorr %x0|Phong %x1|Blinn %x2|Toon %x3|WardIso %x4|Beckmann %x5|Kajiya Kay %x6"; /* diff shader buttons */ uiDefButS(block, MENU, B_MATPRV, str1, 9, 180,78,19, &(ma->diff_shader), 0.0, 0.0, 0, 0, "Creates a diffuse shader"); @@ -4005,7 +4005,7 @@ uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_MATPRV, "Spec ", 90,120,150,19, &(ma->spec), 0.0, 2.0, 0, 0, "Sets the degree of specularity"); - if ELEM3(ma->spec_shader, MA_SPEC_COOKTORR, MA_SPEC_PHONG, MA_SPEC_BLINN) { + if ELEM4(ma->spec_shader, MA_SPEC_COOKTORR, MA_SPEC_PHONG, MA_SPEC_BLINN, MA_SPEC_KAJIYAKAY) { uiDefButS(block, NUMSLI, B_MATPRV, "Hard:", 90, 100, 150,19, &(ma->har), 1.0, 511, 0, 0, "Sets the hardness of the specularity"); } if(ma->spec_shader==MA_SPEC_BLINN) @@ -4016,6 +4016,10 @@ } if(ma->spec_shader==MA_SPEC_WARDISO) uiDefButF(block, NUMSLI, B_MATPRV, "rms:", 90, 100,150,19, &(ma->rms), 0.0, 0.4, 0, 0, "Sets the standard deviation of surface slope"); + if(ma->spec_shader==MA_SPEC_BECKMANN) { + uiDefButF(block, NUMSLI, B_MATPRV, "Slope:", 90, 100,150,19, &(ma->slope), 0.0, 0.4, 0, 0, "Sets the average slope of the microfacets"); + uiDefButF(block, NUMSLI, B_MATPRV, "Gloss:", 90, 80,150,19, &(ma->gloss), 0.0, 1.0, 0, 0, "Set the amount of added gloss"); + } /* default shading variables */ uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_MATPRV, "Tralu ", 9,30,150,19, &(ma->translucency), 0.0, 1.0, 100, 2, "Translucency, amount of diffuse shading of the back side"); Index: source/blender/blenloader/intern/readfile.c =================================================================== --- source/blender/blenloader/intern/readfile.c (revisjon 16766) +++ source/blender/blenloader/intern/readfile.c (arbeidskopi) @@ -6290,6 +6290,7 @@ if(ma->darkness==0.0) { ma->rms=0.1f; ma->darkness=1.0f; + ma->slope=0.1f; } }