📄 light.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. *//** * light.cpp - Implementation for the the routines of the light class * @author Russel Ryan */#include <stdio.h>#include <stdlib.h>#include <float.h>#include <normalize3_v.h>#define normalize3_v _normalize3_v#include <length_vec3_v.h>#define length_vec3_v _length_vec3_v#include <dot_product3_v.h>#define dot_product3_v _dot_product3_v#include <set_spec_exponent9.h>#define set_spec_exponent9 _set_spec_exponent9#include <spec9_v.h>#define spec9_v _spec9_v#include <math.h>#include <simdmath.h>#include "common.h"#include "light.h"light_illumination light_illum_fp[LIGHT_TYPES] = { light_getDirectionalIllumination, light_getPointIllumination, light_getSpotIllumination};LIGHT_ILLUMINATION(light_getIllumination) { (*light_illum_fp[source.type])(source, rgbp, dirToLight_x, dirToLight_y, dirToLight_z, distanceToLight, p_x, p_y, p_z);}LIGHT_ILLUMINATION(light_getDirectionalIllumination) { dprintf("light_getDirectionalIllumination\r\n"); vector unsigned char splat_3 = (vector unsigned char){0x08, 0x09, 0x0A, 0x0B, 0x08, 0x09, 0x0A, 0x0B, 0x08, 0x09, 0x0A, 0x0B, 0x08, 0x09, 0x0A, 0x0B}; distanceToLight = spu_splats(-1.0f); dirToLight_x = spu_shuffle(source.CPDA_x, source.CPDA_x, splat_3); dirToLight_x = spu_mul(dirToLight_x, distanceToLight); dirToLight_y = spu_shuffle(source.CPDA_y, source.CPDA_y, splat_3); dirToLight_y = spu_mul(dirToLight_y, distanceToLight); dirToLight_z = spu_shuffle(source.CPDA_z, source.CPDA_z, splat_3); dirToLight_z = spu_mul(dirToLight_z, distanceToLight); splat_3 = (vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03}; rgbp.r = spu_shuffle(source.CPDA_x, source.CPDA_x, splat_3); rgbp.g = spu_shuffle(source.CPDA_y, source.CPDA_y, splat_3); rgbp.b = spu_shuffle(source.CPDA_z, source.CPDA_z, splat_3); distanceToLight = spu_splats(MAX_FLOAT);}LIGHT_ILLUMINATION(light_getPointIllumination) { dprintf("light_getPointIllumination\r\n"); vector unsigned char splat_3 = (vector unsigned char){0x04, 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07, 0x04, 0x05, 0x06, 0x07}; distanceToLight = spu_splats(-1.0f); dirToLight_x = spu_shuffle(source.CPDA_x, source.CPDA_x, splat_3); dirToLight_y = spu_shuffle(source.CPDA_y, source.CPDA_y, splat_3); dirToLight_z = spu_shuffle(source.CPDA_z, source.CPDA_z, splat_3); dirToLight_x = spu_sub(dirToLight_x, p_x); dirToLight_y = spu_sub(dirToLight_y, p_y); dirToLight_z = spu_sub(dirToLight_z, p_z); distanceToLight = length_vec3_v(dirToLight_x, dirToLight_y, dirToLight_z); source.args_v = spu_mul(spu_mul(spu_splats(source.attn_z), distanceToLight), distanceToLight); //use unused space to our advantage splat_3 = (vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03}; rgbp.r = spu_shuffle(source.CPDA_x, source.CPDA_x, splat_3); rgbp.g = spu_shuffle(source.CPDA_y, source.CPDA_y, splat_3); rgbp.b = spu_shuffle(source.CPDA_z, source.CPDA_z, splat_3); normalize3_v(&dirToLight_x, &dirToLight_y, &dirToLight_z, dirToLight_x, dirToLight_y, dirToLight_z); vector float atten = spu_add(spu_splats(source.attn_x), spu_add(spu_mul(spu_splats(source.attn_y), distanceToLight), source.args_v)); atten = spu_re(atten); rgbp.r = spu_mul(rgbp.r, atten); rgbp.g = spu_mul(rgbp.g, atten); rgbp.b = spu_mul(rgbp.b, atten);}LIGHT_ILLUMINATION(light_getSpotIllumination) { dprintf("light_getSpotIllumination"); vector unsigned char splat= (vector unsigned char){4,5,6,7, 4,5,6,7, 4,5,6,7, 4,5,6,7}; distanceToLight = spu_splats(-1.0f); //these hold position first, don't mess it up vector float dir_x = spu_shuffle(source.CPDA_x, source.CPDA_x, splat); vector float dir_y = spu_shuffle(source.CPDA_y, source.CPDA_y, splat); vector float dir_z = spu_shuffle(source.CPDA_z, source.CPDA_z, splat); //PRINTF_VECTOR_FLOAT("dir", dir_x); dirToLight_x = spu_sub(dir_x, p_x); dirToLight_y = spu_sub(dir_y, p_y); dirToLight_z = spu_sub(dir_z, p_z); distanceToLight = length_vec3_v(dirToLight_x, dirToLight_y, dirToLight_z); //splat direction splat = (vector unsigned char){8,9,10,11, 8,9,10,11, 8,9,10,11, 8,9,10,11}; dir_x = spu_shuffle(source.CPDA_x, source.CPDA_x, splat); dir_y = spu_shuffle(source.CPDA_y, source.CPDA_y, splat); dir_z = spu_shuffle(source.CPDA_z, source.CPDA_z, splat); //splat color splat = (vector unsigned char){0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x02, 0x03}; rgbp.r = spu_shuffle(source.CPDA_x, source.CPDA_x, splat); rgbp.g = spu_shuffle(source.CPDA_y, source.CPDA_y, splat); rgbp.b = spu_shuffle(source.CPDA_z, source.CPDA_z, splat); normalize3_v(&dirToLight_x, &dirToLight_y, &dirToLight_z, dirToLight_x, dirToLight_y, dirToLight_z); // atten_x + dist * attn_y * dist^2 * attn_z vector float atten = spu_add( spu_splats(source.attn_x), spu_add( spu_mul(distanceToLight, spu_splats(source.attn_y)), spu_mul(distanceToLight, spu_mul(distanceToLight, spu_splats(source.attn_z))) ) ); atten = spu_re(atten); rgbp.r = spu_mul(rgbp.r, atten); rgbp.g = spu_mul(rgbp.g, atten); rgbp.b = spu_mul(rgbp.b, atten); vector float negone = spu_splats(-1.0f); vector float thetas = dot_product3_v(spu_mul(negone, dirToLight_x), spu_mul(negone, dirToLight_y), spu_mul(negone, dirToLight_z), dir_x, dir_y, dir_z); //PRINTF_VECTOR_FLOAT("thetas:", thetas); spec9Exponent exp; set_spec_exponent9(&exp, source.arg3); atten = spu_splats(1.0f); vector float _zero = spu_splats(0.0f); vector float _one = spu_splats(1.0f); vector float chphi = spu_splats(source.arg1); vector float chalpha = spu_splats(source.arg2); vector unsigned int theta_lt_chphi = spu_cmpgt(chphi, thetas); vector unsigned int theta_lt_chalpha = spu_cmpgt(chalpha, thetas); vector float ang = spu_mul(spec9_v(spu_sub(thetas, chphi), &exp), spu_re(spu_sub(chalpha, chphi))); atten = _one; atten = spu_sel(atten, ang, theta_lt_chalpha); atten = spu_sel(atten, _zero, spu_and(spu_xor(theta_lt_chalpha, spu_splats(0xFFFFFFFF)),theta_lt_chphi)); rgbp.r = spu_mul(rgbp.r, atten); rgbp.g = spu_mul(rgbp.g, atten); rgbp.b = spu_mul(rgbp.b, atten); /* //reuse unusued vector floats dir_x = spu_splats(source.arg1); //chphi dir_y = spu_splats(source.arg2); //chalpha atten = spu_splats(0.0f); vector unsigned int theta_test = spu_cmpgt(thetas, dir_x); vector unsigned int theta_test2 = spu_and(theta_test, spu_cmpgt(dir_y, thetas)); //just using crap space atten = spu_sel(atten, spu_mul(spec9_v(spu_sub(thetas, dir_x), &exp), spu_re(spu_sub(dir_y, dir_x))), theta_test2); // atten = spu_sel(atten, spec9_v(spu_sub(thetas, dir_x), &exp) / spu_sub(dir_y, dir_x), theta_test2); theta_test2 = spu_and(theta_test, spu_cmpgt(thetas, dir_y)); atten = spu_sel(atten, spu_splats(1.0f), theta_test2); */ /* atten = spu_sel(atten, spu_mul(spec9_v(spu_sub(thetas, dir_x), &exp),spu_re(spu_sub(dir_y, dir_x))), spu_and(spu_xor(spu_cmpgt(dir_x, thetas),(vector unsigned int)(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)), spu_cmpgt(dir_y, thetas))); atten = spu_sel(atten, spu_splats(1.0f), spu_xor(spu_and(spu_xor(spu_cmpgt(dir_x, thetas), (vector unsigned int)(0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF)), spu_cmpgt(dir_y, thetas)), (vector unsigned int)(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF))); atten = spu_sel(atten, spu_splats(0.0f), spu_cmpgt(dir_x, thetas)); */ }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -