zoukankan      html  css  js  c++  java
  • Introduction to my galaxy engine 4: Test on local light model

    今天按照shadow volumn阴影的检查方法对spot light和point light的灯光范围模型做了个测试。

    测试图片如下:(蓝色为场景中的物体,黄色表示场景中受灯光影响的部分,绿色为灯光模型)

    depth fail test 和 stencil test 是在GPU中执行的,首先渲染蓝色的盒子RenderScene,再渲染灯光模型CalRadium(disable write to depth buffer),最后再将模板值为1的部分添加上另一个颜色来突出受光照部分LitScene,代码如下:

      1 SamplerState g_samWrap
      2 {
      3     Filter = MIN_MAG_MIP_LINEAR;
      4     AddressU = Wrap;
      5     AddressV = Wrap;
      6 };
      7 
      8 SamplerState g_samClamp
      9 {
     10     Filter = MIN_MAG_MIP_LINEAR;
     11     AddressU = Clamp;
     12     AddressV = Clamp;
     13 };
     14 
     15 DepthStencilState DisableDepth
     16 {
     17     DepthEnable = FALSE;
     18     DepthWriteMask = ZERO;
     19 };
     20 
     21 DepthStencilState EnableDepth
     22 {
     23     DepthEnable = TRUE;
     24     DepthWriteMask = ALL;
     25     DepthFunc = Less_Equal;//set to less equal since texture background is ini as 1.0
     26 };
     27 
     28 BlendState NoBlending
     29 {
     30     AlphaToCoverageEnable = FALSE;
     31     BlendEnable[0] = FALSE;
     32 };
     33 
     34 BlendState AlphaBlendingOn
     35 {
     36     BlendEnable[0] = TRUE;
     37     SrcBlend = SRC_ALPHA;
     38     DestBlend = INV_SRC_ALPHA;
     39 };
     40 
     41 BlendState AdditiveBlending
     42 {
     43     AlphaToCoverageEnable = FALSE;
     44     BlendEnable[0] = TRUE;
     45     SrcBlend = ONE;
     46     DestBlend = ONE;
     47     BlendOp = ADD;
     48     SrcBlendAlpha = ZERO;
     49     DestBlendAlpha = ZERO;
     50     BlendOpAlpha = ADD;
     51     RenderTargetWriteMask[0] = 0x0F;
     52 };
     53 
     54 RasterizerState DisableCulling
     55 {
     56     //FillMode = WIREFRAME;
     57     CullMode = NONE;
     58 };
     59 
     60 RasterizerState EnableCulling
     61 {
     62     //FillMode = WIREFRAME;
     63     CullMode = BACK;
     64 };
     65 
     66 RasterizerState FrontCulling
     67 {
     68     //FillMode = WIREFRAME;
     69     CullMode = FRONT;
     70 };
     71 
     72 BlendState DisableFrameBuffer
     73 {
     74     BlendEnable[0] = FALSE;
     75     RenderTargetWriteMask[0] = 0x0;
     76 };
     77 
     78 BlendState EnableFrameBuffer
     79 {
     80     BlendEnable[0] = FALSE;
     81     RenderTargetWriteMask[0] = 0x0F;
     82 };
     83 
     84 DepthStencilState TwoSidedStencil
     85 {
     86     DepthEnable = true;
     87     DepthWriteMask = ZERO;//Turn off writes to the depth-stencil buffer.
     88     DepthFunc = Less;
     89     
     90     // Setup stencil states
     91     StencilEnable = true;
     92     StencilReadMask = 0xFFFFFFFF;
     93     StencilWriteMask = 0xFFFFFFFF;
     94     
     95     BackFaceStencilFunc = Always;// how stencil data is compared against existing stencil data.Always pass the comparison.
     96     BackFaceStencilDepthFail = Incr;// describes the stencil operation to perform when stencil testing passes and depth testing fails. 
     97     BackFaceStencilPass = Keep;// describes the stencil operation to perform when stencil testing and depth testing both pass. 
     98     BackFaceStencilFail = Keep;//describes the stencil operation to perform when stencil testing fails. 
     99     
    100     FrontFaceStencilFunc = Always;
    101     FrontFaceStencilDepthFail = Decr;
    102     FrontFaceStencilPass = Keep;
    103     FrontFaceStencilFail = Keep;
    104 };
    105 
    106 DepthStencilState RenderNonShadows
    107 {
    108     DepthEnable = true;
    109     DepthWriteMask = ZERO;
    110     DepthFunc = Less_Equal;
    111     
    112     StencilEnable = true;
    113     StencilReadMask = 0xFFFFFFFF;//read stencil buffer to check if lit or not
    114     StencilWriteMask = 0x0;
    115     
    116     FrontFaceStencilFunc = Less_Equal;//If the source data is greater (multipay light)or equal to the destination data, the comparison passes.
    117     FrontFaceStencilPass = Keep;//Keep the existing stencil data.
    118     FrontFaceStencilFail = Zero;//Set the stencil data to 0.
    119     
    120     BackFaceStencilFunc = Never;//Never pass the comparison.
    121     BackFaceStencilPass = Zero;
    122     BackFaceStencilFail = Zero;
    123 };
    124 
    125 Texture2D  g_ModelTexture;
    126 
    127 Texture2D  g_NormDepthTexture;
    128 Texture2D  g_DiffuseTexture;
    129 
    130 matrix World;
    131 matrix View;
    132 matrix Projection;
    133 
    134 float4 g_AmbientColor = float4(0.1f, 0.1f, 0.1f, 1.0f);
    135 float4 g_DirLightColor = float4(0.3f, 0.3f, 0.3f, 1.0f);
    136 float3 g_DirLightDir = float3(0.0f, 1.0f, -1.0f);
    137 float4 g_LocalLightColor;
    138 //---------------------------------------------------------------------------------------------------------------------------------
    139 struct VS_MODEL_INPUT
    140 {
    141     float4 Pos            : POSITION;         
    142     float2 Tex            : TEXCOORD0;     
    143     float3 Norm        : NORMAL;       
    144 };
    145 
    146 struct PS_MODEL_INPUT
    147 {
    148     float4 Pos            :SV_POSITION;   
    149     float2 Tex            : TEXCOORD0;     
    150     float3 Norm        : TEXCOORD1;    
    151 };
    152 
    153 struct PS_MODEL_OUTPUT
    154 {
    155     float4 NormDepth    : SV_Target0;
    156     float4 DiffuseColor    : SV_Target1;
    157 };
    158 //------------------------------------------------------------------------------------------------------------------------
    159 struct VS_QUAD_INPUT
    160 {
    161     float4 Pos            :POSITION;           
    162     float2 Tex            : TEXCOORD0;       
    163 };
    164 
    165 struct PS_SCENE_INPUT
    166 {
    167     float4 Pos            :SV_POSITION;   
    168     float2 Tex            : TEXCOORD0;     
    169 };
    170 
    171 struct PS_SCENE_OUTPUT
    172 {
    173     float4 Color        :SV_Target;   
    174     float     Depth        : SV_Depth;
    175 };
    176 //-----------------------------------------------------------render scene to gbuffer-----------------------------------------------
    177 PS_MODEL_INPUT VS_SCENE(VS_MODEL_INPUT input)
    178 {
    179     PS_MODEL_INPUT output = (PS_MODEL_INPUT)0;
    180     output.Pos = input.Pos;
    181     output.Pos.w = 1;
    182 
    183     output.Pos = mul( output.Pos, World );
    184     output.Pos = mul( output.Pos, View );
    185     output.Pos = mul( output.Pos, Projection );
    186     output.Pos = output.Pos / output.Pos.w;
    187 
    188     output.Norm = input.Norm;
    189     output.Tex = input.Tex;
    190     return output;
    191 }
    192 
    193 PS_MODEL_OUTPUT PS_SCENE(PS_MODEL_INPUT input)
    194 {
    195     PS_MODEL_OUTPUT output = (PS_MODEL_OUTPUT)0;
    196 
    197     float4 NormDepth = 0;
    198     NormDepth.rgb = input.Norm;//normal
    199     NormDepth.a = input.Pos.z;//depth
    200 
    201     output.NormDepth = NormDepth;
    202     output.DiffuseColor = g_ModelTexture.Sample( g_samWrap, input.Tex );
    203 
    204     return output;
    205 }
    206 //----------------------------------------------add ambient light to scene------------------------------------------------
    207 PS_SCENE_INPUT VS_Ambient(VS_QUAD_INPUT input)
    208 {
    209     PS_SCENE_INPUT output = (PS_SCENE_INPUT)0;
    210 
    211     float2 Pos = input.Pos.xy;
    212     output.Pos = float4(Pos.xy, 0, 1);
    213     
    214     output.Tex.x = 0.5 * (1 + Pos.x);
    215     output.Tex.y = 0.5 * (1 - Pos.y);
    216 
    217     return output;
    218 }
    219 
    220 PS_SCENE_OUTPUT PS_Ambient(PS_SCENE_INPUT input)
    221 {
    222     PS_SCENE_OUTPUT output = (PS_SCENE_OUTPUT)0;
    223 
    224     float4 DiffuseColor = g_DiffuseTexture.Sample( g_samClamp, input.Tex );
    225     float4 NormalDepth = g_NormDepthTexture.Sample( g_samClamp, input.Tex );
    226     float3 Normal = NormalDepth.rgb;
    227     float Depth = NormalDepth.a;
    228     float4 Pos = input.Pos;
    229 
    230     clip(Depth - 0.0001);
    231 
    232     output.Color = (g_AmbientColor + dot(normalize(g_DirLightDir), Normal) * g_DirLightColor) * DiffuseColor;
    233     output.Color.a = 1;
    234     output.Depth = Depth;
    235     
    236     return output;
    237 }
    238 //------------------------------calcuate depth test and set stencil value-------------------------------------------------------
    239 float4 PS_CalRadium(PS_MODEL_INPUT input) : SV_Target
    240 {   
    241     return float4(0.0, 1.0, 0.0, 0.3);//green light volumn
    242 }
    243 //-------------------------------------------------------------------------------------lit the area where stencil value is 1----------------------------------------------------------------------------------------
    244 float4 PS_LitScene(PS_SCENE_INPUT input) : SV_Target
    245 {
    246     return g_LocalLightColor;
    247 }
    248 //---------------------------------------------------------------------------------------------------------
    249 technique10 RenderScene
    250 {
    251     pass p0
    252     {
    253         SetVertexShader( CompileShader( vs_4_0, VS_SCENE() ) );
    254         SetGeometryShader( NULL );
    255         SetPixelShader( CompileShader( ps_4_0, PS_SCENE() ) );
    256 
    257         SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    258         SetDepthStencilState( EnableDepth, 0 );
    259         SetRasterizerState( EnableCulling );
    260 
    261         //SetRasterizerState( FrontCulling );
    262     }  
    263 }
    264 
    265 technique10 AmbientLighting
    266 {
    267     pass p0
    268     {
    269         SetVertexShader( CompileShader( vs_4_0, VS_Ambient() ) );
    270         SetGeometryShader( NULL );
    271         SetPixelShader( CompileShader( ps_4_0, PS_Ambient() ) );
    272 
    273         SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    274         SetDepthStencilState( EnableDepth, 0 );//render all model on texture, no depth test is needed
    275         SetRasterizerState( EnableCulling );
    276     }  
    277 }
    278 
    279 technique10 CalRadium
    280 {
    281     pass p0
    282     {
    283         SetVertexShader( CompileShader( vs_4_0, VS_SCENE() ) );
    284         SetGeometryShader( NULL );
    285         SetPixelShader( CompileShader( ps_4_0, PS_CalRadium() ) );
    286 
    287         SetBlendState( AlphaBlendingOn, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    288         //SetBlendState( DisableFrameBuffer, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );//don't render color to render target
    289         SetDepthStencilState( TwoSidedStencil, 1 ); //do depth fail test, write to stencil buffer
    290         SetRasterizerState( DisableCulling );//no culling, so both front and back face could be tested
    291     }  
    292 }
    293 
    294 technique10 LitScene
    295 {
    296     pass p0
    297     {
    298         SetVertexShader( CompileShader( vs_4_0, VS_Ambient() ) );
    299         SetGeometryShader( NULL );
    300         SetPixelShader( CompileShader( ps_4_0, PS_LitScene() ) );
    301 
    302         SetBlendState( AdditiveBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
    303         SetDepthStencilState( RenderNonShadows, 1); //when stencil value is 0, stencil fun pass and lit that pixel
    304         SetRasterizerState( EnableCulling );
    305     }  
    306 }
  • 相关阅读:
    数字签名与HTTPS详解
    利用策略模式优化过多 if else 代码
    Redis 的事务到底是不是原子性的
    Spring Boot项目的接口防刷
    深入分析 ThreadLocal
    什么是四层和七层负载均衡?他们之间的区别是什么?
    MyEclipse或Eclipse中project的导入和导出
    org.hibernate.exception.ConstraintViolationException: could not insert:
    C++ STL vector(向量容器)的使用(附完整程序代码)
    Swift2.0语言教程之函数嵌套调用形式
  • 原文地址:https://www.cnblogs.com/RobinG/p/2517404.html
Copyright © 2011-2022 走看看