在场景中添加光线——使用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

转载于:https://www.cnblogs.com/AlexCheng/archive/2011/02/14/2120097.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值