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

  • 相关阅读:
    20170719 Mysql 配置远端Mysql访问,增加表/存储过程
    20170720 Celery 异步任务处理到Sql Server 发生死锁
    20170718 关于Mysql 安装于虚拟机Ubuntu中,内网中Windows系统无法访问
    20170712 SQL Server 日志文件收索
    SQL Server 2016 发送邮件功能
    Sql server 函数--取值年月
    SSIS--(1)
    Hadoop 尝试
    百度之星复赛T6&&hd6149 ——Valley Numer II
    百度之星复赛T5&&hdu6148
  • 原文地址:https://www.cnblogs.com/AlexCheng/p/2120097.html
Copyright © 2020-2023  润新知