【DirectX11】【学习笔记(14)】点光源

好久没有更新博客了。。。  最近一直在忙一些其他的事情= =。。  DX都快忘了

今天继续更新!  

上次说到简单光照,今天我们就学习一个点光源

影响点光源的因素主要有:

范围,位置,衰减

其中衰减用一个二次方程来表达

Attenuation = att0 + (att1 * d) + (att2 * d²)

 

att0  - 常量修饰符

由于此值未乘以任何值,因此称为“常量修改器”,这意味着此值不会随着从光源到像素的距离的变化而变化。该值用于为光源范围内的所有物体提供最小量的光。如果您要将此值设置为“1.0f”,那么光源范围内的所有内容都将具有全彩或全光。

att1  - 线性修改器

您可以看到此值乘以光源和像素之间的距离,或乘以等式中的d。这使得该值成为“线性修改器”,这意味着随着像素和光源之间的距离增加,这将逐渐减少像素获得的光量。这可能是最现实的因素。

att2  - 指数修饰符

此值乘以d的平方,使该值为“指数修饰符”。使用此值可以使非常接近光源的物体获得大量光线,但随着它们移开,它们快速接收的光线会在很短的距离内减小,然后随着距离越来越远而逐渐减小。

Point Light Equation

lightToPixelVec = light.pos - input.worldPos;

之前我们已经学了如何把世界空间中的变量发送到VS中,其实把灯光发送到PS也是一样的道理。

然后调用HLSL中的函数。然后把向量单位化

d = length(lightToPixelVec);
lightToPixelVec /= d; 

计算光照强度,然后乘光照本身的颜色得到颜色。  最后除以衰减系数

howMuchLight = dot(lightToPixelVec, input.normal);
finalColor += howMuchLight * diffuse * light.diffuse;
finalColor /= light.att[0] + (light.att[1] * d) + (light.att[2] * (d*d));

The Light Structure

struct Light
{
    Light()
    {
        ZeroMemory(this, sizeof(Light));
    }
    XMFLOAT3 dir;
    float pad1;
    ///**************new**************
    XMFLOAT3 pos;
    float range;
    XMFLOAT3 att;
    float pad2;
    ///**************new**************
    XMFLOAT4 ambient;
    XMFLOAT4 diffuse;
};

描述光照

light.pos = XMFLOAT3(0.0f, 0.0f, 0.0f);
light.range = 100.0f;
light.att = XMFLOAT3(0.0f, 0.2f, 0.0f);
light.ambient = XMFLOAT4(0.3f, 0.3f, 0.3f, 1.0f);
light.diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);

Update the Lights Position

XMVECTOR lightVector = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f );

lightVector = XMVector3TransformCoord(lightVector,cube1World);

light.pos.x = XMVectorGetX(lightVector);
light.pos.y = XMVectorGetY(lightVector);
light.pos.z = XMVectorGetZ(lightVector);

我们这里把光照位置设置为第一个立方体的位置

在effect file中描述我们的结构体

struct Light
{
    float3 dir;
    float3 pos;
    float  range;
    float3 att;
    float4 ambient;
    float4 diffuse;
};

 VS 和PS如下

VS_OUTPUT VS(float4 inPos : POSITION, float2 inTexCoord : TEXCOORD, float3 normal : NORMAL)
{
    VS_OUTPUT output;

    output.Pos = mul(inPos, WVP);
    
    output.worldPos = mul(inPos, World);
    output.normal = mul(normal, World);

    output.TexCoord = inTexCoord;

    return output;
}
float4 PS(VS_OUTPUT input) : SV_TARGET
{
    input.normal = normalize(input.normal);

    float4 diffuse = ObjTexture.Sample( ObjSamplerState, input.TexCoord );

    float3 finalColor = float3(0.0f, 0.0f, 0.0f);
    
    //Create the vector between light position and pixels position
    float3 lightToPixelVec = light.pos - input.worldPos;
        
    //Find the distance between the light pos and pixel pos
    float d = length(lightToPixelVec);
    
    //Create the ambient light
    float3 finalAmbient = diffuse * light.ambient;

    //If pixel is too far, return pixel color with ambient light
    if( d > light.range )
        return float4(finalAmbient, diffuse.a);
        
    //Turn lightToPixelVec into a unit length vector describing
    //the pixels direction from the lights position
    lightToPixelVec /= d; 
    
    //Calculate how much light the pixel gets by the angle
    //in which the light strikes the pixels surface
    float howMuchLight = dot(lightToPixelVec, input.normal);

    //If light is striking the front side of the pixel
    if( howMuchLight > 0.0f )
    {    
        //Add light to the finalColor of the pixel
        finalColor += howMuchLight * diffuse * light.diffuse;
        
        //Calculate Light's Falloff factor
        finalColor /= light.att[0] + (light.att[1] * d) + (light.att[2] * (d*d));
    }    
        
    //make sure the values are between 1 and 0, and add the ambient
    finalColor = saturate(finalColor + finalAmbient);
    
    //Return Final Color
    return float4(finalColor, diffuse.a);
}

在PS里  我们先算了物体的自发光  物体的自发光就是他的漫反射的颜色*光照的自发光

如果不在光照范围内,直接返回这个颜色。

否则的化计算他接收的多少光照:   光照强度*物体本身的漫反射颜色*光照本身的漫反射。(这里不乘光照的自发光ambient是因为这个元素只与自身计算有关,并不对其他物体执行计算。  但是在计算finalAmbient的时候也用到了光照的ambient,我感觉有点不对。  等我仔细看一些相关的内容再来解释~)

本节内容的代码部分可以在我的github里面找到!

游戏开发路途遥远,但我相信只要坚持,总能到达彼岸!

如果我的文章对于你学习DirectX11有点帮助,欢迎评论给出建议,让我们一起学习进步!

                                                                                               ———————— 小明 2018.12.30 11.46

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值