📄 brdf.cpp
字号:
/* Copyright (c) 2007 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * brdf.cpp includes all brdf related material code * @author Russel Ryan * never include it on its own, just let material.cpp include it */MATERIAL_SHADER(material_BRDFStyleShade) { dprintf("material_BRDFStyleShade()\r\n"); vector float NL_v; vector float _zero = spu_splats(0.0f); union { vector unsigned int ids; struct { unsigned int id1, id2, id3, id4; }; }; ids = hp.materialID; union{ vector unsigned int mats; struct { material* mat1; material* mat2; material* mat3; material* mat4; }; }; mat1 = &materials[id1]; mat2 = &materials[id2]; mat3 = &materials[id3]; mat4 = &materials[id4]; //tmp1-4 is used now for dirToLight normalization, later it's used for transpose from SoA/AoS vector float tmp1 = dirToLight_x; vector float tmp2 = dirToLight_y; vector float tmp3 = dirToLight_z; normalize3_v(&tmp1, &tmp2, &tmp3, tmp1, tmp2, tmp3); vector float vx = spu_nmsub(rp.dx, hp.t, _zero); //spu_sub(_zero, spu_mul(rp.dx, hp.t)); vector float vy = spu_nmsub(rp.dy, hp.t, _zero); //spu_sub(_zero, spu_mul(rp.dy, hp.t)); vector float vz = spu_nmsub(rp.dz, hp.t, _zero); //spu_sub(_zero, spu_mul(rp.dz, hp.t)); normalize3_v(&vx, &vy, &vz, vx, vy, vz); vector float hx = spu_add(tmp1, vx); vector float hy = spu_add(tmp2, vy); vector float hz = spu_add(tmp3, vz); normalize3_v(&hx, &hy, &hz, hx, hy, hz); vector float nx = hp.nx; vector float ny = hp.ny; vector float nz = hp.nz; normalize3_v(&nx, &ny, &nz, nx, ny, nz); NL_v = dot_product3_v(tmp1, tmp2, tmp3, nx, ny, nz); //dot product of normalized directionto light with hit normal //NL_v = dot_product3_v(dirToLight_x, dirToLight_y, dirToLight_z, hp.nx, hp.ny, hp.nz); vector unsigned int nl_ge_0 = spu_cmpgt(NL_v, _zero); vector unsigned int valid = spu_and(nl_ge_0, shadeBits); //bitwise and union { vector float specularCoefficients_v; struct { float specularCoefficients[4]; }; }; specularCoefficients_v = _zero; union { vector unsigned int functions; struct { material_shader_specular f1; material_shader_specular f2; material_shader_specular f3; material_shader_specular f4; }; }; union { vector unsigned int matTypes; struct { unsigned int mat1_type, mat2_type, mat3_type, mat4_type; }; }; matTypes = (vector unsigned int) {(unsigned int)materials[id1].materialType, (unsigned int)materials[id2].materialType, (unsigned int)materials[id3].materialType, (unsigned int)materials[id4].materialType}; vector unsigned int dummy = spu_splats((unsigned int)material_getSpecularCoefficientDummy); functions = (vector unsigned int) { (unsigned int)fp_shader[mat1_type].specular, (unsigned int)fp_shader[mat2_type].specular, (unsigned int)fp_shader[mat3_type].specular, (unsigned int)fp_shader[mat4_type].specular}; vector unsigned int thisID; thisID = spu_cmpeq(matTypes, spu_splats(mat1_type)); (*f1)(mats, specularCoefficients_v, vx, vy, vz, hx, hy, hz, nx, ny, nz, NL_v, spu_and(valid, thisID)); functions = spu_sel(functions, dummy, thisID); thisID = spu_cmpeq(matTypes, spu_splats(mat2_type)); (*f2)(mats, specularCoefficients_v, vx, vy, vz, hx, hy, hz, nx, ny, nz, NL_v, spu_and(valid, thisID)); functions = spu_sel(functions, dummy, thisID); thisID = spu_cmpeq(matTypes, spu_splats(mat3_type)); (*f3)(mats, specularCoefficients_v, vx, vy, vz, hx, hy, hz, nx, ny, nz, NL_v, spu_and(valid, thisID)); functions = spu_sel(functions, dummy, thisID); thisID = spu_cmpeq(matTypes, spu_splats(mat4_type)); (*f4)(mats, specularCoefficients_v, vx, vy, vz, hx, hy, hz, nx, ny, nz, NL_v, spu_and(valid, thisID)); functions = spu_sel(functions, dummy, thisID); /* vector unsigned char hi = ((vector unsigned char) { 0x00,0x01,0x02,0x03,0x10,0x11,0x12,0x13,0x04,0x05,0x06,0x07,0x14,0x15,0x16,0x17 }); vector unsigned char lo = ((vector unsigned char) { 0x08,0x09,0x0A,0x0B,0x18,0x19,0x1A,0x1B,0x0C,0x0D,0x0E,0x0F,0x1C,0x1D,0x1E,0x1F }); //transpose from SoA to AoS tmp1 = spu_shuffle(vx, vz, hi); tmp2 = spu_shuffle(vx, vz, lo); tmp3 = spu_shuffle(vy, vw, hi); tmp4 = spu_shuffle(vy, vw, lo); vx = spu_shuffle(tmp1, tmp3, hi); vy = spu_shuffle(tmp1, tmp3, lo); vz = spu_shuffle(tmp2, tmp4, hi); vw = spu_shuffle(tmp2, tmp4, lo); tmp1 = spu_shuffle(hx, hz, hi); tmp2 = spu_shuffle(hx, hz, lo); tmp3 = spu_shuffle(hy, hw, hi); tmp4 = spu_shuffle(hy, hw, lo); hx = spu_shuffle(tmp1, tmp3, hi); hy = spu_shuffle(tmp1, tmp3, lo); hz = spu_shuffle(tmp2, tmp4, hi); hw = spu_shuffle(tmp2, tmp4, lo); tmp1 = spu_shuffle(nx, nz, hi); tmp2 = spu_shuffle(nx, nz, lo); tmp3 = spu_shuffle(ny, nw, hi); tmp4 = spu_shuffle(ny, nw, lo); nx = spu_shuffle(tmp1, tmp3, hi); ny = spu_shuffle(tmp1, tmp3, lo); nz = spu_shuffle(tmp2, tmp4, hi); nw = spu_shuffle(tmp2, tmp4, lo); if(spu_extract(valid,0)) { specularCoefficients[0] = (*fp_shader[materials[id1].materialType].specular) (materials[id1], vx, hx, nx, spu_extract(NL_v,0)); } if(spu_extract(valid,1)) { specularCoefficients[1] = (*fp_shader[materials[id2].materialType].specular) (materials[id2], vy, hy, ny, spu_extract(NL_v,1)); } if(spu_extract(valid,2)) { specularCoefficients[2] = (*fp_shader[materials[id3].materialType].specular) (materials[id3], vz, hz, nz, spu_extract(NL_v,2)); } if(spu_extract(valid,3)) { specularCoefficients[3] = (*fp_shader[materials[id4].materialType].specular) (materials[id4], vw, hw, nw, spu_extract(NL_v,3)); } */ //clamp 0 to 1 for multiplying //PRINTF_VECTOR_FLOAT("NL",NL_v); NL_v = clamp_0_to_1_v(NL_v); //PRINTF_VECTOR_FLOAT("NLc",NL_v); specularCoefficients_v = spu_mul(NL_v, specularCoefficients_v); //tmp1 and tmp2 are now dumping areas for diffuse_[r,g,b] and specular_[r,g,b] //tmp3 is a temp calculation place now tmp1 = (vector float){materials[id1].diffuse_r,materials[id2].diffuse_r,materials[id3].diffuse_r,materials[id4].diffuse_r}; tmp2 = (vector float){materials[id1].specular_r,materials[id2].specular_r,materials[id3].specular_r,materials[id4].specular_r}; tmp3 = spu_madd(specularCoefficients_v, tmp2, spu_mul(NL_v, tmp1)); rgbp.r = spu_sel(rgbp.r, spu_mul(lightColor_r, tmp3), valid); //rgbp.r = spu_sel(rgbp.r, spu_mul(lightColor_r, spu_add(spu_mul(NL_v, tmp1), spu_mul(specularCoefficients_v, tmp2))), valid); tmp1 = (vector float){materials[id1].diffuse_g,materials[id2].diffuse_g,materials[id3].diffuse_g,materials[id4].diffuse_g}; tmp2 = (vector float){materials[id1].specular_g,materials[id2].specular_g,materials[id3].specular_g,materials[id4].specular_g}; tmp3 = spu_madd(specularCoefficients_v, tmp2, spu_mul(NL_v, tmp1)); rgbp.g = spu_sel(rgbp.g, spu_mul(lightColor_g, tmp3), valid); //rgbp.g = spu_sel(rgbp.g, spu_mul(lightColor_g, spu_add(spu_mul(NL_v, tmp1), spu_mul(specularCoefficients_v, tmp2))), valid); tmp1 = (vector float){materials[id1].diffuse_b,materials[id2].diffuse_b,materials[id3].diffuse_b,materials[id4].diffuse_b}; tmp2 = (vector float){materials[id1].specular_b,materials[id2].specular_b,materials[id3].specular_b,materials[id4].specular_b}; tmp3 = spu_madd(specularCoefficients_v, tmp2, spu_mul(NL_v, tmp1)); rgbp.b = spu_sel(rgbp.b, spu_mul(lightColor_b, tmp3), valid); //rgbp.b = spu_sel(rgbp.b, spu_mul(lightColor_b, spu_add(spu_mul(NL_v, tmp1),spu_mul(specularCoefficients_v, tmp2))), valid); return; }MATERIAL_SHADER_SPECULAR(material_getPhongSpecularCoefficient) { dprintf("getPhongSpecular\r\n"); /* float alpha = dot_product3(normal, halfangle); PRINT_VECTOR_FLOAT("normal:", normal); PRINT_VECTOR_FLOAT("halfangle:", halfangle); dprintf("alpha: %f\r\n", alpha); spec9Exponent exp; set_spec_exponent9(&exp, mat.arg1_i); //arg1_i is exponent for phong materials return spec9(alpha, &exp); */ spec9Exponent exp; union { vector float coeff; struct { float coeff1; float coeff2; float coeff3; float coeff4; }; }; vector float alpha = dot_product3_v(nx, ny, nz, hx, hy, hz); set_spec_exponent9(&exp, ((material*)spu_extract(materials, 0))->arg1_i); coeff1 = spec9(spu_extract(alpha,0), &exp); set_spec_exponent9(&exp, ((material*)spu_extract(materials, 1))->arg1_i); coeff2 = spec9(spu_extract(alpha,1), &exp); set_spec_exponent9(&exp, ((material*)spu_extract(materials, 2))->arg1_i); coeff3 = spec9(spu_extract(alpha,2), &exp); set_spec_exponent9(&exp, ((material*)spu_extract(materials, 3))->arg1_i); coeff4 = spec9(spu_extract(alpha,3), &exp); specularCoefficients = spu_sel(specularCoefficients, coeff, shadeBits);}MATERIAL_SHADER_SPECULAR(material_getCookTorranceSpecularCoefficient) { dprintf("material_getCookTorranceSpecularCoefficient()\r\n"); union{ vector unsigned int mats; struct { material* mat1; material* mat2; material* mat3; material* mat4; }; }; mats = materials; vector float HN = dot_product3_v(nx, ny, nz, hx, hy, hz); vector float VN = dot_product3_v(vx, vy, vz, nx, ny, nz); vector float HV = dot_product3_v(hx, hy, hz, vx, vy, vz); vector float HN2 = spu_mul(HN, HN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -