博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Introduction to my galaxy engine 6: Differed Lighting 2
阅读量:4678 次
发布时间:2019-06-09

本文共 11908 字,大约阅读时间需要 39 分钟。

接着上回随笔,这一次在局部光源的计算上做了些优化,包括光强度随距离衰弱的计算和将法向量加入到局部光源的计算中。

视频地址:

截图如下:

 

下面的是局部光源的Light volumn图

要精确计算局部光源,就必须获取当前物体的位置。这个可以通过将屏幕像素从投影坐标转换到视角坐标,再传入当前光源在视角坐标系中的位置,这样入射光线向量就有了。法向量可以从之前保持在贴图读取。两个向量作dot计算可以得出光照强度。同理,计算光源和物体位置的距离除以最大光照范围可以得到光强度衰减值(当前用的是简易的线性衰减)。此处点光源没有按精确的入射光来计算,原因是物体可能在光源范围里,但是却背朝光源中心点,虽然在光照范围内,但我们正向看时会比较奇怪。所以用了衰减系数乘以光的颜色来计算,类似全局光来处理。cone light的话方向我是看作为(0,-1, 0), 效果还可以。这部分计算是在PS_LitScene中。

现在光照的计算还比较简单,之后可以还可以用更复杂的模型。其实关键就是获取的物体的位置,之后都好计算了。

 

SamplerState g_samWrap{    Filter = MIN_MAG_MIP_LINEAR;    AddressU = Wrap;    AddressV = Wrap;};SamplerState g_samClamp{    Filter = MIN_MAG_MIP_LINEAR;    AddressU = Clamp;    AddressV = Clamp;};DepthStencilState DisableDepth{    DepthEnable = FALSE;    DepthWriteMask = ZERO;};DepthStencilState EnableDepth{    DepthEnable = TRUE;    DepthWriteMask = ALL;    DepthFunc = Less_Equal;//set to less equal since texture background is ini as 1.0};BlendState NoBlending{    AlphaToCoverageEnable = FALSE;    BlendEnable[0] = FALSE;};BlendState AlphaBlendingOn{    BlendEnable[0] = TRUE;    SrcBlend = SRC_ALPHA;    DestBlend = INV_SRC_ALPHA;};BlendState AdditiveBlending{    AlphaToCoverageEnable = FALSE;    BlendEnable[0] = TRUE;    SrcBlend = ONE;    DestBlend = ONE;    BlendOp = ADD;    SrcBlendAlpha = ZERO;    DestBlendAlpha = ZERO;    BlendOpAlpha = ADD;    RenderTargetWriteMask[0] = 0x0F;};RasterizerState DisableCulling{    //FillMode = WIREFRAME;    CullMode = NONE;};RasterizerState EnableCulling{    //FillMode = WIREFRAME;    CullMode = BACK;};RasterizerState FrontCulling{    //FillMode = WIREFRAME;    CullMode = FRONT;};BlendState DisableFrameBuffer{    BlendEnable[0] = FALSE;    RenderTargetWriteMask[0] = 0x0;};BlendState EnableFrameBuffer{    BlendEnable[0] = FALSE;    RenderTargetWriteMask[0] = 0x0F;};DepthStencilState TwoSidedStencil{    DepthEnable = true;    DepthWriteMask = ZERO;//Turn off writes to the depth-stencil buffer.    DepthFunc = Less;        // Setup stencil states    StencilEnable = true;    StencilReadMask = 0xFFFFFFFF;    StencilWriteMask = 0xFFFFFFFF;        BackFaceStencilFunc = Always;// how stencil data is compared against existing stencil data.Always pass the comparison.    BackFaceStencilDepthFail = Incr;// describes the stencil operation to perform when stencil testing passes and depth testing fails.     BackFaceStencilPass = Keep;// describes the stencil operation to perform when stencil testing and depth testing both pass.     BackFaceStencilFail = Keep;//describes the stencil operation to perform when stencil testing fails.         FrontFaceStencilFunc = Always;    FrontFaceStencilDepthFail = Decr;    FrontFaceStencilPass = Keep;    FrontFaceStencilFail = Keep;};DepthStencilState RenderNonShadows{    DepthEnable = true;    DepthWriteMask = ZERO;    DepthFunc = Less_Equal;        StencilEnable = true;    StencilReadMask = 0xFFFFFFFF;//read stencil buffer to check if lit or not    StencilWriteMask = 0x0;        FrontFaceStencilFunc = Less_Equal;//If the source data is greater (multipay light)or equal to the destination data, the comparison passes.    FrontFaceStencilPass = Keep;//Keep the existing stencil data.    FrontFaceStencilFail = Zero;//Set the stencil data to 0.        BackFaceStencilFunc = Never;//Never pass the comparison.    BackFaceStencilPass = Zero;    BackFaceStencilFail = Zero;};Texture2D  g_ModelTexture;Texture2D  g_NormDepthTexture;Texture2D  g_DiffuseTexture;matrix World;matrix View;matrix Projection;matrix g_InvProj;float4 g_AmbientColor = float4(0.1f, 0.1f, 0.1f, 1.0f);float4 g_DirLightColor = float4(0.3f, 0.3f, 0.3f, 1.0f);float3 g_DirLightDir = float3(0.0f, 1.0f, -1.0f);float4 g_LocalLightColor;float3 g_LocalLightPos;bool   g_LocalLightType;//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------struct VS_MODEL_INPUT{    float4 Pos            : POSITION;             float2 Tex            : TEXCOORD0;         float3 Norm        : NORMAL;       };struct PS_MODEL_INPUT{    float4 Pos            :SV_POSITION;       float2 Tex            : TEXCOORD0;         float3 Norm        : TEXCOORD1;    };struct PS_MODEL_OUTPUT{    float4 NormDepth    : SV_Target0;    float4 DiffuseColor    : SV_Target1;};//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------struct VS_QUAD_INPUT{    float4 Pos            :POSITION;               float2 Tex            : TEXCOORD0;       };struct PS_SCENE_INPUT{    float4 Pos            :SV_POSITION;       float2 Tex            : TEXCOORD0;     };struct PS_SCENE_OUTPUT{    float4 Color        : SV_Target;       float     Depth        : SV_Depth;};//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------struct PS_LIGHT_MODEL_INPUT{    float4 Pos                : SV_POSITION;       float2 Tex                : TEXCOORD0;         float4 LightPos        : TEXCOORD1;     //light original pos in view space};//----------------------------------------------------------------------------------------render scene to gbuffer-------------------------------------------------------------------------------------PS_MODEL_INPUT VS_SCENE(VS_MODEL_INPUT input){    PS_MODEL_INPUT output = (PS_MODEL_INPUT)0;    output.Pos = input.Pos;    output.Pos.w = 1;    output.Pos = mul( output.Pos, World );    output.Pos = mul( output.Pos, View );    output.Pos = mul( output.Pos, Projection );    output.Pos = output.Pos / output.Pos.w;    output.Norm = input.Norm;    output.Tex = input.Tex;    return output;}PS_MODEL_OUTPUT PS_SCENE(PS_MODEL_INPUT input){    PS_MODEL_OUTPUT output = (PS_MODEL_OUTPUT)0;    float4 NormDepth = 0;    NormDepth.rgb = input.Norm;//normal    NormDepth.a = input.Pos.z;//depth    output.NormDepth = NormDepth;    output.DiffuseColor = g_ModelTexture.Sample( g_samWrap, input.Tex );    return output;}//-------------------------------------------------------------------------------------add ambient light to scene----------------------------------------------------------------------------------------PS_SCENE_INPUT VS_Ambient(VS_QUAD_INPUT input){    PS_SCENE_INPUT output = (PS_SCENE_INPUT)0;    float2 Pos = input.Pos.xy;    output.Pos = float4(Pos.xy, 0, 1);        output.Tex.x = 0.5 * (1 + Pos.x);    output.Tex.y = 0.5 * (1 - Pos.y);    return output;}PS_SCENE_OUTPUT PS_Ambient(PS_SCENE_INPUT input){    PS_SCENE_OUTPUT output = (PS_SCENE_OUTPUT)0;    float4 DiffuseColor = g_DiffuseTexture.Sample( g_samClamp, input.Tex );    float4 NormalDepth = g_NormDepthTexture.Sample( g_samClamp, input.Tex );    float3 Normal = NormalDepth.rgb;    float Depth = NormalDepth.a;    float4 Pos = input.Pos;    clip(Depth - 0.0001);    output.Color = (g_AmbientColor + dot(normalize(g_DirLightDir), Normal) * g_DirLightColor) * DiffuseColor;    output.Color.a = 1;    output.Depth = Depth;        return output;}//--------------------------------------------------------------------------------------calcuate depth test and set stencil value--------------------------------------------------------------------------------PS_LIGHT_MODEL_INPUT VS_LightModel(VS_MODEL_INPUT input){    PS_LIGHT_MODEL_INPUT output = (PS_LIGHT_MODEL_INPUT)0;    output.Pos = input.Pos;    output.Pos.w = 1;    output.Pos = mul( output.Pos, World );    output.Pos = mul( output.Pos, View );    output.Pos = mul( output.Pos, Projection );    output.Pos = output.Pos / output.Pos.w;    //get the tex coord of the light model on canvas    output.Tex = (output.Pos.xy  + 1.0f) * 0.5f;    output.Tex.y = 1 - output.Tex.y;        float4 LightPos = float4(g_LocalLightPos, 1);    output.LightPos = mul( LightPos, View );    output.LightPos = output.LightPos / output.LightPos.w;    return output;}float4 PS_CalRadium(PS_LIGHT_MODEL_INPUT input) : SV_Target{       float4 vloumnColor = g_LocalLightColor;    vloumnColor.a = 0.1;    return vloumnColor;}//-------------------------------------------------------------------------------------lit the area where stencil value is 1----------------------------------------------------------------------------------------float4 PS_LitScene(PS_LIGHT_MODEL_INPUT input) : SV_Target{    float4 finalColor = 0;    float4 NormalDepth = g_NormDepthTexture.Sample( g_samClamp, input.Tex );    float2 PosXY = input.Tex * 2.0f - 1.0f;//tex coord to proj coord    PosXY.y *= -1;//back to ori coord    float4 PixelProjPos = float4(PosXY, NormalDepth.a, 1.0f);//projection space    float4 PixelViewPos = mul(PixelProjPos, g_InvProj);    PixelViewPos = PixelViewPos / PixelViewPos.w;    //the dis between the light and the scene obj, not with the light volumn !!!!! ori back ground depth is set to 1.    float dis = distance(PixelViewPos.xyz, input.LightPos.xyz);    float faint = 0;    if(g_LocalLightType)//cone light        faint = 1.0 - min(dis / 0.2f, 1.0f);//the maximum range of the local light, linear faint    else        faint = 1.0 - min(dis / 0.1f, 1.0f);    float4 DiffuseColor = g_DiffuseTexture.Sample( g_samClamp, input.Tex );    if(g_LocalLightType)        finalColor = g_LocalLightColor * dot( normalize( float3(0.0f, -1.0f, 0.0f) ), NormalDepth.rgb ) * faint;    else        finalColor = g_LocalLightColor * DiffuseColor * faint;//g_LocalLightColor * dot( normalize( input.LightPos.xyz - PixelViewPos.xyz ), NormalDepth.rgb ) * faint;            finalColor.a = 1;    return finalColor;}//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------technique10 RenderScene{    pass p0    {        SetVertexShader( CompileShader( vs_4_0, VS_SCENE() ) );        SetGeometryShader( NULL );        SetPixelShader( CompileShader( ps_4_0, PS_SCENE() ) );        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );        SetDepthStencilState( EnableDepth, 0 );        SetRasterizerState( EnableCulling );        //SetRasterizerState( FrontCulling );    }  }technique10 AmbientLighting{    pass p0    {        SetVertexShader( CompileShader( vs_4_0, VS_Ambient() ) );        SetGeometryShader( NULL );        SetPixelShader( CompileShader( ps_4_0, PS_Ambient() ) );        SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );        SetDepthStencilState( EnableDepth, 0 );//render all model on texture, no depth test is needed        SetRasterizerState( EnableCulling );    }  }technique10 CalRadium{    pass p0    {        SetVertexShader( CompileShader( vs_4_0, VS_LightModel() ) );        SetGeometryShader( NULL );        SetPixelShader( CompileShader( ps_4_0, PS_CalRadium() ) );        //SetBlendState( AlphaBlendingOn, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );        SetBlendState( DisableFrameBuffer, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );//don't render color to render target        SetDepthStencilState( TwoSidedStencil, 1 ); //do depth fail test, write to stencil buffer        SetRasterizerState( DisableCulling );//no culling, so both front and back face could be tested    }  }technique10 LitScene{    pass p0    {        SetVertexShader( CompileShader( vs_4_0, VS_LightModel() ) );        SetGeometryShader( NULL );        SetPixelShader( CompileShader( ps_4_0, PS_LitScene() ) );        SetBlendState( AdditiveBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );        SetDepthStencilState( RenderNonShadows, 1); //when stencil value is 0, stencil fun pass and lit that pixel        SetRasterizerState( EnableCulling );    }  }

 

 

转载于:https://www.cnblogs.com/RobinG/archive/2012/05/27/2519810.html

你可能感兴趣的文章
OGRE 入门 一、 ubuntu 12.04 下编译
查看>>
MySQL按照汉字的拼音排序
查看>>
3.1.3自适应阈值化
查看>>
NABCD
查看>>
ZOJ 2850 Beautiful Meadow (简单题)
查看>>
Android开源框架ImageLoader的完美例子
查看>>
LeetCode - Best Time to Buy and Sell Stock
查看>>
自写vim插件ldoc.vim,提供智能的lua注释代码补全
查看>>
java-Coculator
查看>>
一些小例子
查看>>
WebSocket4Net 0.5发布
查看>>
转 Winmail 退信分析大全 (2012,05,02 更新)
查看>>
499 单词计数 (Map Reduce版本)
查看>>
python笔记
查看>>
2、openSession和getCurrentSession方法的区别
查看>>
msgbox.js的修改使在iframe的可视区域显示
查看>>
a、b交换
查看>>
[SDOI2015]序列统计
查看>>
LaTeX技巧892: Ubuntu 安装新版本TeXLive并更新
查看>>
昨天用的流量有点多60M
查看>>