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 }
posted on 2012-05-25 03:12 CGBeginner 阅读(443) 评论(0) 编辑 收藏 举报