6-8.用HLSL定义聚光灯

6-8.HLSL定义聚光灯

问题

        你想定义一个聚光灯,它的行为很像点光源,但它照亮一个光锥,如6-10.

       

 

方案

        在像素着色器,确定当前像素是否在照明锥中。可以求光的方向和锥方向间的点积。

运作

从上一节的代码开始。因为聚光灯比点光灯更专用,你将添加这些额外的XNAHLSL变量到你的.fx文件:

float xLightStrength;     // 光强度

float3 xConeDirection;  // 光锥方向

float3 xConeAngle;       // 光锥角

float3 xConeDecay;       // 光锥衰减

第一个变量允许你增加/减少光的强度。这对其他类型的光也是有用的,并且当你的场景中有多个光源时也是必要的。接着,你可以调整聚光灯的光锥的中心方向,以及光锥的宽度。最后,你可以指定朝着光锥的边缘要减少多少光强度。

除此之外,您需要稍微扩展您的像素着色器。通常,你将做的和每像素点光源类似,但你将添加一个检查证实像素是否在光的光锥中:

SLPixelToFrame SLPixelShader(SLVertexToPixel PSIn) : COLOR0

{

     SLPixelToFrame Output = (SLPixelToFrame)0;

     float4 baseColor = float4(0,0,1,1);      

     float3 normal = normalize(PSIn.Normal);

     float3 lightDirection = normalize(PSIn.LightDirection);   

     float coneDot = dot(lightDirection, normalize(xConeDirection));

     float shading = 0;        

     if (coneDot > xConeAngle)

     {

         float coneAttenuation = pow(coneDot, xConeDecay);

         shading = dot(normal, -lightDirection);

         shading *= xLightStrength;

         shading *= coneAttenuation;

     }       

     Output.Color = baseColor*(shading+xAmbient);

     return Output;

}

一旦你单位化法线和光方向,你应该发现当前像素是否在光锥中。要做到这一点,你要检查两个方向间的夹角:

当前像素和光源间的方向

光锥中心方向

第一个方向是lightDirection,而第二个在xConeDirection变量中规定。只有如果这个角度低于某一阈值,像素才被照亮。

快速的检查方法是求两个方向的点积。如果值接近1表示两个方向的夹角很小,值越小,角越大。

要决定角是否不会太大,你检查点积是否不小于存在xConeAngle中的某一阈值。如果像素在锥中,你计算光照因子,叫做shading。要削弱接近锥的边界的照明效果,你求coneDot变量指定xConeDecay次方的结果。结果,离光锥中心方向很远的像素的coneDot值等于或小于1

光锥外边的像素的着色值为0,所以光不影响这些像素。

转载于:https://www.cnblogs.com/XNAconglele/archive/2009/09/25/1573711.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值