Introduction to my galaxy engine 4: Test on local light model
Introduction to my galaxy engine 4: Test on local light model<div id="cnblogs_post_body">今天按照shadow volumn阴影的检查方法对spot light和point light的灯光范围模型做了个测试。
测试图片如下:(蓝色为场景中的物体,黄色表示场景中受灯光影响的部分,绿色为灯光模型)
http://pic002.cnblogs.com/images/2012/411346/2012052503052028.jpg
http://pic002.cnblogs.com/images/2012/411346/2012052503054178.jpg
http://pic002.cnblogs.com/images/2012/411346/2012052503055847.jpg
http://pic002.cnblogs.com/images/2012/411346/2012052503060848.jpg
http://pic002.cnblogs.com/images/2012/411346/2012052503062655.jpg
http://pic002.cnblogs.com/images/2012/411346/2012052503064061.jpg
http://pic002.cnblogs.com/images/2012/411346/2012052503065365.jpg
depth fail test 和 stencil test 是在GPU中执行的,首先渲染蓝色的盒子RenderScene,再渲染灯光模型CalRadium(disable write to depth buffer),最后再将模板值为1的部分添加上另一个颜色来突出受光照部分LitScene,代码如下:
<div class="cnblogs_code">1 SamplerState g_samWrap2 {3 Filter = MIN_MAG_MIP_LINEAR;4 AddressU = Wrap;5 AddressV = Wrap;6 };7 8 SamplerState g_samClamp9 { 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 RenderNonShadows107 {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 not114 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 Texture2Dg_ModelTexture;126 127 Texture2Dg_NormDepthTexture;128 Texture2Dg_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_INPUT140 {141 float4 Pos : POSITION; 142 float2 Tex : TEXCOORD0; 143 float3 Norm : NORMAL; 144 };145 146 struct PS_MODEL_INPUT147 {148 float4 Pos :SV_POSITION; 149 float2 Tex : TEXCOORD0; 150 float3 Norm : TEXCOORD1; 151 };152 153 struct PS_MODEL_OUTPUT154 {155 float4 NormDepth : SV_Target0;156 float4 DiffuseColor : SV_Target1;157 };158 //------------------------------------------------------------------------------------------------------------------------159 struct VS_QUAD_INPUT160 {161 float4 Pos :POSITION; 162 float2 Tex : TEXCOORD0; 163 };164 165 struct PS_SCENE_INPUT166 {167 float4 Pos :SV_POSITION; 168 float2 Tex : TEXCOORD0; 169 };170 171 struct PS_SCENE_OUTPUT172 {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;//normal199 NormDepth.a = input.Pos.z;//depth200 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_Target240 { 241 return float4(0.0, 1.0, 0.0, 0.3);//green light volumn242 }243 //-------------------------------------------------------------------------------------lit the area where stencil value is 1----------------------------------------------------------------------------------------244 float4 PS_LitScene(PS_SCENE_INPUT input) : SV_Target245 {246 return g_LocalLightColor;247 }248 //---------------------------------------------------------------------------------------------------------249 technique10 RenderScene250 {251 pass p0252 {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 AmbientLighting266 {267 pass p0268 {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 needed275 SetRasterizerState( EnableCulling );276 }277 }278 279 technique10 CalRadium280 {281 pass p0282 {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 target289 SetDepthStencilState( TwoSidedStencil, 1 ); //do depth fail test, write to stencil buffer290 SetRasterizerState( DisableCulling );//no culling, so both front and back face could be tested291 }292 }293 294 technique10 LitScene295 {296 pass p0297 {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 pixel304 SetRasterizerState( EnableCulling );305 }306 }
页:
[1]