java点光源_在场景中添加光线——使用HLSL定义点光源

问题

直到现在,你都是用单向光照亮场景,这对在3D世界中添加阳光是很有用的。但很多情况中,你还需要一个从点发出的光线,例如一个探照灯或爆炸。这种光源叫做点光源。

解决方案

将点光源的3D位置从XNA项目传送到XNA effect中。对每个顶点,计算光源指向顶点的方向,并将这个方向作为光线方向。知道了光线方向就可以像以前一样继续了。

工作原理

在. fx文件中,使用下列代码替换xLightDirection参数,让你可以将光源的3D位置从XNA项目传递到HLSL effect中: float3 xLightPosition;

然后,对每个顶点,你要计算从光源指向顶点的方向。从A指向B的方向可以通过B减去A获得。记住你需要顶点的最终3D位置,这意味着初始3D位置需要通过是世界矩阵进行变换:

float3 final3DPosition = mul(inPos, xWorld);

float3 lightDirection = final3DPosition - xLightPosition;

lightDirection = normalize(lightDirection);

Output.LightFactor = dot(rotNormal, -lightDirection);

因为光源指向顶点的方向可能比1大得多,所以要确保将这个方向归一化。有了光线方向,你可以像以前的教程那样继续处理了。

当运行代码时,对每个顶点都要计算光源到这个顶点的方向,所以这个方向往往是不同的。

距离衰减

要让效果变得更加真实,你想在光源与顶点的距离变大时让点光源的光照变弱。要做到这点,可以在归一化lightDirection之前对它使用length函数获得distance,然后将LightFactor除以这个distance:

float3 final3DPosition = mul(inPos, xWorld);

float3 lightDirection = final3DPosition - xLightPosition;

float distance = length(lightDirection);

lightDirection = normalize(lightDirection);

Output.LightFactor = dot(rotNormal, -lightDirection);

Output.LightFactor /= distance;

代码

在XNA项目中,你可以在任何你想的位置放置点光源:

effect.CurrentTechnique = effect.Techniques["VertexShading"];

effect.Parameters["xView"].SetValue(fpsCam.ViewMatrix);

effect.Parameters["xProjection"].SetValue(fpsCam.ProjectionMatrix);

effect.Parameters["xLightPosition"].SetValue(new Vector3(1, 5, 0));

effect.Parameters["xAmbient"].SetValue(0.0f);

下面是完整的vertex shader:

VSVertexToPixel VSVertexShader(float4 inPos: POSITION0, float3 inNormal: NORMAL0)

{

VSVertexToPixel Output = (VSVertexToPixel)0;

float4x4 preViewProjection = mul(xView, xProjection);

float4x4 preWorldViewProjection = mul(xWorld, preViewProjection);

Output.Position = mul(inPos, preWorldViewProjection);

float3 normal = normalize(inNormal);

float3x3 rotMatrix = (float3x3)xWorld;

float3 rotNormal = mul(normal, rotMatrix);

float3 final3DPosition = mul(inPos, xWorld);

float3 lightDirection = final3DPosition - xLightPosition;

lightDirection = normalize(lightDirection);

Output.LightFactor = dot(rotNormal, -lightDirection);

return Output;

}

image.axd?picture=image_thumb_90.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值