zoukankan      html  css  js  c++  java
  • [翻译]XNA 3.0 Game Programming Recipes之fortyfour

    PS:自己翻译的,转载请著明出处格
                                                                    6-8 用HLSL定义一个聚光灯
    问题
                            一个光照点作为在前面定义的一样,闪耀的光从一个点向所有方向。你想定义一个聚光灯,它它的行为完全像一个点光源,除了它照耀的象一个光核一样,如图6-10所显示。

    解决方案
                            在你的象素着色器中,判断当前的象素是否在光照核内。你可以通过使用点乘积在光的方向和核的方向之间来实现这个。
    它是如何工作的
                            开始前面小节的代码。由于一个聚光灯比一个光照点更个性化,你添加这些额外的XNA-to-HLSL变量到你的.fx文件中:
    1 float xLightStrength;
    2 float3 xConeDiection;
    3 float xConeAngle;
    4 float xConeDecay;
                            第一个变量将允许你增加/减少你的光照的强度。这同样很有用为任何光照的类型也是非常有必要的,当你有多个光照在你的屏幕中。接下来,你可以指定聚光灯核心的中心方向,和核心的宽度。最后,你可以指定多大的光照强度应该减少朝着核心的边缘。
                             除了这个,你需要扩展一下你的象素着色器。一般来说,你将会做相同的per-pixel光照点,但是你要添加一个检查去核实象素在光的核心中:
     1 SLPixelToFrame SLPixelShader(SLVertexToPixel PSIn):COLOR0
     2 {
     3      SLPixelToFrame Output=(SLPixelToFrame)0;
     4      float4 baseColor=float4(0,0,1,1);
     5      float3 normal=normalize(PSIn.Normal);
     6      float3 lightDirection=normalize(PSIn.LightDirection);
     7      float coneDot=dot(lightDirection,normalize(xConeDiection));
     8      float shading=0;
     9      if(coneDot>xConeAngle)
    10      {
    11               float coneAttenuation=pow(coneDot,xConeDecay);
    12               shading=dot(normal,-lightDirection);
    13               shading*=xLightStrength;
    14               shading*=coneAttenuation;
    15      }
    16      Output.Color=baseColor*(shading+xAmbient);
    17      return Output;
    18 }
                              一旦你已经规格化法线和光照方向,你应该检测当前的象素是否在光的核心内。要做到这一点,你要检查两个方向之间的角度:
                            1。当前象素和光源之间的方向。
                            2。核心的中心方向。
                              第一个方向是lightDirection,同时第二个被指定在xConeDirection变量。只有在这个角度是低于某一临界值,像素应点亮。
                              一种为这个的快速检查是通过接收点乘积在两个方向之间 。一个值接近到1,意思是一个非常小的角度在两个方向之间,同时值越小表明角度越大。
                             为了测定角度是否太大,你检查这点乘积是否比临界值小,保存在xConeAngle内,如果象素是在核心内,你计算光照因子,称为shading.为了削弱光照效果接近于核心的边,你使用coneDot值到指定的强度在xConeDecay里,作为一个结果,coneDot值等于或者比1小,象素将变的更小,它离核心中心方向就越远。
                             核心以外的象素会得到一个shading值为0,所以光将有没有影响这些象素。
    代码
                             你的完整的象素着色器已经列出来了。
                             在你的XNA代码的Draw方法中,一个有活力的效果,设置它的参数,绘制到你的屏幕中:
     1 effect.CurrentTechnique=effect.Technique["SpotLight"];
     2 effect.Parameters["xWorld"].SetValue(Matrix.Identity);
     3 effect.Parameters["xView"].SetValue(fpsCam.ViewMatrix);
     4 effect.Parameters["xProjection"].SetValue(fpsCam.ProjectionMatrix);
     5 effect.Parameters["xLightDirection"].SetValue(new Vector3(5.0f,2.0f,-15.0f+variation));
     6 effect.Parameters["xAmbient"].SetValue(2.0f);
     7 effect.Parameters["xConeDirection"].SetValue(new Vector3(0,-1,0));
     8 effect.Parameters["xConeAngle"].SetValue(0.5f);
     9 effect.Parameters["xConeDecay"].SetValue(2.0f);
    10 effect.Parameters["xLightStrength"].SetValue(0.7f);
    11 effect.Begin();
    12 foreach(EffectPass pass in effect.CurrentTechnique.Passes)
    13 {
    14      pass.Begin();
    15      device.VertexDeclaration=myVertexDeclaration;
    16      device.DrawUserPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList,vertices,0,6);
    17      pass.End();
    18 }
    19 effect.End();
  • 相关阅读:
    MongoDB 基础API使用
    MongoDB -- JAVA基本API操作
    Docker数据管理
    Docker容器的简单使用
    Docker
    Centos 7.3 镜像制作
    Fuel部署OpenStack
    Fuel
    Ceph添加、删除osd及故障硬盘更换
    ceph常用命令
  • 原文地址:https://www.cnblogs.com/315358525/p/1544604.html
Copyright © 2011-2022 走看看