Directx11教程二十二之Multiple Point Lights(多个点光源)

这个教程的结构以下:函数





这节讲的是由关于点光源的spa


第一,什么是点光源?

首先你得知道到底光照和光源的关系,光源发出光照,关系就是如此的简单。
如今将光照分为DirectionLight(方向光),DiffuseLight(漫反射光),SpecularLight(镜面光),(这里不谈论全局光什么的,其实我如今不懂全局光)
光源分为:类太阳体,点光源,聚光灯。

这里我是不会具体说明上面的每种概念,D3D11龙书都写得很清楚的,
这里只说点光源,上面我说到光源发出光照,更具体的说每种光源都能发出三种光,即 DirectionLight(方向光),DiffuseLight(漫反射光),SpecularLight(镜面光)

天然而然 点光源也能发出这三种光,可是这里咱们假设点光源只发出DiffuseLight(漫反射光),

看看点光源的模型吧:   




看上面的图,假设Q点为光源原点,假设在Q点(Xq,Yq,Zq)光照强度为PointLightColor=(r,g,b);  Q点到P点(Xp,Yp,Zp)的距离为 d, 灯光衰减因子atten1,atten2,atten3(衰减因子由你本身决定的,三个不可同时为0).net


那么点光源或者说灯泡照射在P点的强度为: LightIntensity=PointLightColor/(atten1+atten2*d+atten3*d*d);code

光入射P点的向量为(Q,P)或者说为(Xp-Xq,Yp-Yq,Zp-Zq);orm


下面的有些我已经在 blog

D3D11教程五之DiffuseLight(漫射光)说过了,这里不在重复


贴出shader代码,那些累赘重复的代码我没封装成函数,请见谅:教程

Texture2D ShaderTexture:register(t0);  //纹理资源
SamplerState SampleType:register(s0);   //采样方式

#define LIGHT_NUM 4

cbuffer CBMatrix:register(b0)
{
	matrix World;
	matrix View;
	matrix Proj;
	matrix WorldInvTranspose;
};

cbuffer CBDiffuseColor:register(b1)
{
	float4 diffuseColor[LIGHT_NUM];
};

cbuffer CBLightPos : register(b2)
{
	float4 LightPos[LIGHT_NUM];
};

struct VertexIn
{
	float3 Pos:POSITION;
	float2 Tex:TEXCOORD0;  //多重纹理能够用其它数字
	float3 Normal:NORMAL;
};


struct VertexOut
{
	float4 Pos:SV_POSITION;
	float3 Pos_W:POSITION; //点在世界空间的位置
	float2 Tex:TEXCOORD0;
	float3 W_Normal:NORMAL;  //世界空间的法线
};


VertexOut VS(VertexIn ina)
{
	VertexOut outa;

	//将模型坐标变到齐次裁剪空间
	outa.Pos = mul(float4(ina.Pos,1.0f), World);
	outa.Pos = mul(outa.Pos, View);
	outa.Pos = mul(outa.Pos, Proj);

	//将法向量变到世界空间
	outa.W_Normal = mul(ina.Normal, (float3x3)WorldInvTranspose);  //此事世界逆转置矩阵的第四行原本就没啥用
	outa.W_Normal = normalize(outa.W_Normal);

	//纹理坐标
	outa.Tex= ina.Tex;

	//求点在世界空间的位置
	float4 PosW= mul(float4(ina.Pos, 1.0f), World);
	outa.Pos_W = PosW.xyz;

	return outa;
}


//这里光照发生在世界空间,固然其它空间也行.
float4 PS(VertexOut outa) : SV_Target
{
	float4 TexColor; //采集的纹理颜色
	float4 color = {0.0f,0.0f,0.0f,0.0f}; //最终输出的颜色
	float DiffuseFactor1;
	float DiffuseFactor2;
	float DiffuseFactor3;
	float DiffuseFactor4;
	float4 DiffuseColorIntensity1;
	float4 DiffuseColorIntensity2;
	float4 DiffuseColorIntensity3;
	float4 DiffuseColorIntensity4;
	float4 DiffuseColor1;
	float4 DiffuseColor2;
	float4 DiffuseColor3;
	float4 DiffuseColor4;
	float atten1, atten2, atten3; //衰减系数

	//初始化衰减系数
	atten1 = 1.0f;
	atten2 = 0.5f;
	atten3 = 0.0f;

	/*灯光一*/
	//计算像素到灯光1的向量,照射到像素的光强度,
	float3 LookDirection1 = LightPos[0].xyz - outa.Pos_W.xyz;

	//计算光源到像素点的距离
	float distance1 = length(LookDirection1);

	//计算光源照射到像素点的光照强度
	DiffuseColorIntensity1 = diffuseColor[0] / (atten1 + atten2*distance1 + atten3*distance1*distance1); //衰减系数注意加括号计算为分母

	//将像素点到光源向量进规格化
	LookDirection1 = normalize(LookDirection1);

	//求出漫反射光因子
	DiffuseFactor1 = saturate(dot(outa.W_Normal, LookDirection1));

	//求出最终照射在像素点的漫反射光照强度
	DiffuseColor1 = DiffuseFactor1*DiffuseColorIntensity1;

	/*灯光二*/
	//计算像素到灯光2的向量,照射到像素的光强度,
	float3 LookDirection2 = LightPos[1].xyz - outa.Pos_W.xyz;
	float distance2 = length(LookDirection2);
	DiffuseColorIntensity2 = diffuseColor[1] / (atten1 + atten2*distance2 + atten3*distance2*distance2);
	LookDirection2 = normalize(LookDirection2);
	DiffuseFactor2 = saturate(dot(outa.W_Normal, LookDirection2));
	DiffuseColor2 = DiffuseFactor2*DiffuseColorIntensity2;

	/*灯光三*/
	//计算像素到灯光3的向量,照射到像素的光强度,
	float3 LookDirection3 = LightPos[2].xyz - outa.Pos_W.xyz;
	float distance3 = length(LookDirection3);
	DiffuseColorIntensity3= diffuseColor[2] / (atten1 + atten2*distance3 + atten3*distance3*distance3);
	LookDirection3 = normalize(LookDirection3);
	DiffuseFactor3= saturate(dot(outa.W_Normal, LookDirection3));
	DiffuseColor3= DiffuseFactor3*DiffuseColorIntensity3;

	/*灯光四*/
	//计算像素到灯光4的向量,照射到像素的光强度,
	float3 LookDirection4= LightPos[3].xyz - outa.Pos_W.xyz;
	float distance4 = length(LookDirection4);
	DiffuseColorIntensity4 = diffuseColor[3] / (atten1 + atten2*distance4 + atten3*distance4*distance4);
	LookDirection4= normalize(LookDirection4);
	DiffuseFactor4 = saturate(dot(outa.W_Normal, LookDirection4));
	DiffuseColor4 = DiffuseFactor4*DiffuseColorIntensity4;


	//获取采样颜色
    TexColor = ShaderTexture.Sample(SampleType, outa.Tex);

		
	//第五,用灯光颜色调节纹理颜色
	color = saturate(DiffuseColor1+ DiffuseColor2+ DiffuseColor3+ DiffuseColor4)*TexColor;

	return color;
}



程序运行效果图:资源




下面是个人源代码连接:

http://download.csdn.net/download/qq_29523119/9661206

get