Phong 光照模型实现及漫反射光强计算
/********************************************************************** 功 能:实现Phong光照模型,求给定点的漫放射光强; 参数含义: Pt[3] : 点的坐标, Vertices:点Pt所在的四边形的四个顶点坐标,顶点按逆时针顺序存放 Normals :四个顶点的法向量,和Vertices按同样的顺序存放; lightPos:光源的位置 Ip :漫放射光源的强度 Kd :漫放射系数 返 回 值: 点Pt的漫放射光强;
可调用函数: =========================================================================== bool BilinearInterpolation(int Vertices[4][3], int P[3], double uv[4]); 功 能:在凸四边形中实现二次线性插值
参数含义:
Vertices : 四边形的四个顶点,按逆时针存储;
P : 点的坐标
uv : 用于返回插值系数;
返 回 值: True-插值成功,Flase-插值失败(如果Pt不在四边形内部,则失败)
===========================================================================
日 期: 2009-10-20 作 者: 罗月童 **********************************************************************/
double CIlluminationView::Phong(int Pt[3], int Vertices[4][3], double Normals[4][3], int lightPos[3], double Ip, double Kd) { double I = 0; // intensity
// calculate the light vector from the point to the light source
double L[3];
L[0] = lightPos[0] - Pt[0];
L[1] = lightPos[1] - Pt[1];
L[2] = lightPos[2] - Pt[2];
double L_len = sqrt(L[0]*L[0] + L[1]*L[1] + L[2]*L[2]);
L[0] /= L_len;
L[1] /= L_len;
L[2] /= L_len;
// calculate the view vector from the point to the camera (assumed to be at the origin)
double V[3];
V[0] = -Pt[0];
V[1] = -Pt[1];
V[2] = -Pt[2];
double V_len = sqrt(V[0]*V[0] + V[1]*V[1] + V[2]*V[2]);
V[0] /= V_len;
V[1] /= V_len;
V[2] /= V_len;
// calculate the normal vector at the point by bilinear interpolation
double uv[4];
if (!BilinearInterpolation(Vertices, Pt, uv)) {
return 0; // point is not inside the quad, return 0 intensity
}
double N[3] = {0, 0, 0};
for (int i = 0; i < 4; i++) {
N[0] += uv[i] * Normals[i][0];
N[1] += uv[i] * Normals[i][1];
N[2] += uv[i] * Normals[i][2];
}
double N_len = sqrt(N[0]*N[0] + N[1]*N[1] + N[2]*N[2]);
N[0] /= N_len;
N[1] /= N_len;
N[2] /= N_len;
// calculate the reflection vector
double R[3];
double dot_L_N = L[0]*N[0] + L[1]*N[1] + L[2]*N[2];
R[0] = 2*dot_L_N*N[0] - L[0];
R[1] = 2*dot_L_N*N[1] - L[1];
R[2] = 2*dot_L_N*N[2] - L[2];
double R_len = sqrt(R[0]*R[0] + R[1]*R[1] + R[2]*R[2]);
R[0] /= R_len;
R[1] /= R_len;
R[2] /= R_len;
// calculate the diffuse reflection intensity
double dot_L_N_Kd = dot_L_N * Kd;
if (dot_L_N_Kd < 0) {
dot_L_N_Kd = 0;
}
double diffuse_I = Ip * dot_L_N_Kd;
// calculate the specular reflection intensity
double dot_R_V = R[0]*V[0] + R[1]*V[1] + R[2]*V[2];
if (dot_R_V < 0) {
dot_R_V = 0;
}
double specular_I = Ip * pow(dot_R_V, 16);
// calculate the total intensity at the point
I = diffuse_I + specular_I;
return I;
}
原文地址: https://www.cveoy.top/t/topic/lUVw 著作权归作者所有。请勿转载和采集!