The provided code implements Phong shading, which is a common lighting model used in computer graphics. This model calculates the diffuse light intensity at a point on a surface, considering the angle between the surface normal and the light direction. To enhance the realism, we can incorporate light attenuation, which simulates the decrease in light intensity as the distance from the light source increases.

This code snippet calculates the diffuse light intensity 'I' at a point 'Pt' on a surface. It utilizes bilinear interpolation to determine the surface normal 'N' at 'Pt', given the normals of the four surrounding vertices. The code then calculates the light direction vector 'L' and the cosine of the angle between 'N' and 'L', represented by 'cosTheta'.

To implement light attenuation, we can introduce a factor that decreases with the square of the distance between the point and the light source. This factor is calculated as '1.0 / (VectorLength(L) * VectorLength(L))', where 'VectorLength(L)' represents the magnitude of the light direction vector. By multiplying this factor with the original light intensity calculation, we achieve the desired light attenuation effect.

Here's the modified code with the added attenuation factor:

double CIlluminationView::Phong(int Pt[3], int Vertices[4][3], double Normals[4][3], int lightPos[3], double Ip, double Kd)
{
	double I = 0; //漫反射光强
	double uv[4] = { 0 }; //插值系数
	bool bSuccess = BilinearInterpolation(Vertices, Pt, uv); //判断点Pt是否在四边形内部并且成功插值

	if (bSuccess) //如果插值成功
	{
		double N[3] = { 0 }; //点Pt的法向量
		for (int i = 0; i < 4; i++)
		{
			for (int j = 0; j < 3; j++)
			{
				N[j] += Normals[i][j] * uv[i]; //根据插值系数计算点Pt的法向量
			}
		}

		double L[3] = { 0 }; //光照向量
		for (int i = 0; i < 3; i++)
		{
			L[i] = lightPos[i] - Pt[i]; //计算光照向量
		}

		double normN = VectorLength( N); //法向量的模长
		double normL = VectorLength( L); //光照向量的模长

		double cosTheta = 0; //夹角余弦值
		if (normN != 0 && normL != 0)
		{
			cosTheta = DotProduct(L,N) / (normN * normL); //计算夹角余弦值
		}

		if (cosTheta > 0) //如果夹角余弦值大于0
		{	
			double attenuation = 1.0 / (VectorLength(L) * VectorLength(L)); //计算光强衰减系数
			I = Ip * Kd * cosTheta * attenuation; //计算漫反射光强
		}
	}

	return I;
}

This modification effectively simulates the natural phenomenon of light intensity decreasing with distance, adding greater realism to the lighting of your 3D scenes.

Phong Shading with Light Attenuation

原文地址: https://www.cveoy.top/t/topic/l0mM 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录