Directx11教程三十四之ProjectiveLightMap(投影光照图)

这节教程呢,其实结构跟  

D3D11教程三十之ProjectiveTexturing(投影纹理) 那节教程一样,我就不放出程序结构图了



这次投影的纹理换为一张光照贴图,模仿光线从窗户照射进的那种情况,






放出Shader代码:ColorShader.fx

Texture2D BaseTexture:register(t0);  //基础纹理
Texture2D ProjectiveTexture:register(t1);  //投影纹理
SamplerState SampleType:register(s0);   //采样方式

//VertexShader
cbuffer CBMatrix:register(b0)
{
	matrix World;
	matrix View;
	matrix Proj;
	matrix WorldInvTranspose;
	matrix ProjectorView;
	matrix ProjectorProj;
};

cbuffer CBLight:register(b1)
{
	float4 DiffuseColor;
	float3 LightDirection;
	float pad;
}

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


struct VertexOut
{
	float4 Pos:SV_POSITION;
	float4 ProjPos: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;

	//将坐标变换到投影相机下的齐次裁剪空间
	outa.ProjPos= mul(float4(ina.Pos, 1.0f), World);
	outa.ProjPos = mul(outa.ProjPos, ProjectorView);
	outa.ProjPos = mul(outa.ProjPos, ProjectorProj);
	return outa;
}


float4 PS(VertexOut outa) : SV_Target
{
	float4 TexColor; //采集基础纹理颜色
    float2 ProjTex;   //投影纹理坐标
	float4 LightMapColor;
	float4 color = {0.0f,0.0f,0.0f,0.0f}; //最终输出的颜色
	float brightness;
	float DiffuseFactor;
	float4 DiffuseLight; //漫反射光
	float4 AmbientColor = { 0.15f,0.15f,0.15f,0.15f }; //环境光


	//设置光亮强度(不是严格的点光源强度计算,其实上我们个Shader除	matrix ProjectorView;matrix ProjectorProj就没用到点光源了)
	brightness = 1.5f;

	//计算漫反射光的反方向
	float3 InverseLightDir = -LightDirection;

	//计算漫反射光因子
	DiffuseFactor = saturate(dot(InverseLightDir, outa.W_Normal));

	//漫反射光
	DiffuseLight = brightness*DiffuseFactor*DiffuseColor;


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

	//第二,获取投影相机下的投影纹理空间的坐标值[0.0,1.0]  u=0.5*x+0.5;   v=-0.5*y+0.5;   -w<=x<=w  -w<=y<=w  
	ProjTex.x =(outa.ProjPos.x/outa.ProjPos.w)*0.5f + 0.5f;
	ProjTex.y= (outa.ProjPos.y/outa.ProjPos.w)*(-0.5f) + 0.5f;

	//第三,由于3D模型可能超出投影相机下的视截体,其投影纹理可能不在[0.0,1.0],所以得进行判定这个3D物体投影的部分是否在视截体内     (没SV_POSITION签名 显卡不会进行裁剪)
	if (saturate(ProjTex.x) == ProjTex.x&&saturate(ProjTex.y) == ProjTex.y)
	{
		//对投影的光照贴图进行采集像素
		LightMapColor = ProjectiveTexture.Sample(SampleType, ProjTex);

		color = saturate(DiffuseLight*LightMapColor*TexColor + AmbientColor*TexColor);
	}
	else
	{
		color = saturate(AmbientColor*TexColor);
	}

	return color;
}


放出程序运行图:




我的源代码如下:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于DirectX 11的开发教程,以下是一些建议的资源和步骤: 1. 官方文档:首先,你可以参考Microsoft官方提供的DirectX开发文档。他们提供了详细的教程和示例代码,涵盖了DirectX 11的各个方面。你可以在Microsoft的官方网站上找到这些文档。 2. 学习基础知识:在开始使用DirectX 11之前,建议你先学习一些基础知识,比如形学和着色器编程。了解基本的形学概念和渲染管线的工作原理对理解DirectX 11的开发非常有帮助。 3. 使用工具:为了使用DirectX 11进行开发,你需要安装DirectX SDK或者Windows SDK。这些工具包括编译器、调试器和其他必要的辅助工具,帮助你开发DirectX 11应用程序。 4. 编写代码:开始编写自己的DirectX 11应用程序。你可以使用C++来编写代码,并使用DirectX API来创建窗口、渲染形和处理用户输入等操作。在编写代码时,可以参考官方文档中的示例代码和教程。 5. 调试和优化:一旦你的应用程序运行起来,你可能会遇到一些问题,比如性能瓶颈或者渲染错误。在这种情况下,你可以使用调试工具来诊断和解决这些问题。另外,优化你的代码也是很重要的,以提高应用程序的性能和效率。 6. 参考其他资源:除了官方文档之外,还有一些其他资源可以帮助你学习和理解DirectX 11的开发。比如书籍、在线教程、论坛和博客等等。你可以根据自己的需求和学习风格选择适合自己的资源。 希望以上建议对你有所帮助!祝你在DirectX 11开发中取得成功!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值