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

    PS:自己翻译的,转载请著明出处格
                                                      6-6 使用HLSL定义一个发光的点
    问题
                          直到现在,你已经使用了方向的光亮去点亮你的屏幕,它非常有用去添加光照到你的3D世界。通常情况下,你同样需要一个来自单一个点的光照,如来自一个手电筒或者一个爆炸。这样一个光源被称为:point Light。
    解决方案
                          传递光照点的3D位置从你的XNA工程到你的XNA效果。每一个顶点,你可以计算方向从光源朝着顶点,使用这个光照方向。一旦你知道光照方向,你继续象以前一样使用。
    它是如何工作的
                          在你的.fx文件中,取代这xLightDirection参数用这一行,允许你传递光源的3D位置从你的XNA工程到你的HLSL效果:
    1 float3 xLightPosition;
                          其次,每一个顶点,你计算这个方向从光照朝着顶点。一如往常,从A到B的方向是通过由B减A得到的。这意味着你需要顶点的最终3D位置,这意味着原来的3D位置转换成世界矩阵:
    1 float3 final3DPosition=mul(inPos,xWorld);
    2 float3 lightDirection=final3DPosition-xLightPosition;
    3 lightDirection=normalize(lightDirection);
    4 Output.LightFactor=dot(rotNormal,-lightDirection);
                          由于光源和顶点之间的方向可能大于1,你需要确保它的长度成为统一单位通过规格化它。一旦你知道这个光照方向,你已经准备去处理如果前面章节介绍的。
                          当您运行此代码时,在每个顶点你会计算从光源到那个顶点的方向,这样这个方向每个顶点都会不同。
    Distance Attenuation
                          为了让事情更现实一点,你可以减少一个光照点的影响,正如光源和顶点之间的距离变的很大。要做到这一点,找到这个距离通过调用length值在lightDirection之前规格化它。接下来,用这个距离划分LightFactor;这将导致光照的强度减少,正如在光源和增长顶点之间的距离:
    1 float3 final3DPosition=mul(inPos,xWorld);
    2 float3 lightDirection=final3DPosition-xLightPosition;
    3 float distance=length(lightDirection);
    4 lightDirection=normalize(lightDirection);
    5 Output.LightFactor=dot(rotNormal,-lightDirection);
    6 Output.LightFactor/=distance;
    代码
                           在你的XNA工程中,你可以在任何位置布置你的光源:
    1 effect.CurrentTechnique=effect.Technique["VertexShadin"];
    2 effect.Parameters["xView"].SetValue(fpsCam.ViewMatrix);
    3 effect.Parameters["xProjection"].SetValue(fpsCam.ProjectionMatrix);
    4 effect.Parameters["xLightDirection"].SetValue(new Vector3(1,5,0));
    5 effect.Parameters["xAmbient"].SetValue(0.0f);
                           这是你的完整的顶点着色器:
     1 VSVertexToPixel VSVertexShader(float4 inPos:POSITION0,float3 inNormal:NORMAL0)
     2 {
     3       VSVertexToPixel Output=(VSVertexToPixel)0;
     4       float4*4 preViewProjection=mul(xView,xProjection);
     5       float4*4 preWorldViewProjection=mul(xWorld,preViewProjection);
     6       Output.Position=mul(inPos,preWorldViewProjection);
     7       float3 normal=normalize(inNormal);
     8       float3*3 rotMatrix=(float3*3)xWorld;
     9       float3 rotNormal=mul(normal,rotMatrix);
    10       float3 final3DPosition=mul(inPos,xWorld);
    11       float3 lightDirection=final3DPosition-xLightPosition;
    12       lightDiection=normalize(lightDirection);
    13       Output.LightFactor=dot(rotNormal,-lightDirection);
    14       return Output;
    15 }  
  • 相关阅读:
    联表查询用on和where的区别
    了解触发器
    QUIC协议,了解
    SQL Mode
    redis持久化
    Kali Linux渗透测试实战 1.2 环境安装及初始化
    电容降压
    单火取电
    大整数的因子
    最大公约数
  • 原文地址:https://www.cnblogs.com/315358525/p/1544471.html
Copyright © 2011-2022 走看看