Introduction to my galaxy engine 7: Volumetric Light Scattering
Introduction to my galaxy engine 7: Volumetric Light Scattering花了一天时间,给引擎中添加了Volumetric Light Scattering模块.
视频地址:https://vimeo.com/43232452
截屏图如下:
http://pic002.cnblogs.com/images/2012/411346/2012060112065029.jpg
Volumetric Light Scattering又名god light,Crepuscular Rays 等等, 也是一个游戏中比较常见的效果,主要是用post process来实现的。
具体实现步骤如下:
1.渲染发光体和场景,场景不添加材质,只显示成黑色,将结果渲染到render target 1上。
http://pic002.cnblogs.com/images/2012/411346/2012060112100266.jpg
http://pic002.cnblogs.com/images/2012/411346/2012060112101352.jpg
2. 只渲染场景,添加材质和光照,将结果渲染到render target 2上。
3. 对render target 1 做采样处理,计算光照。原理见如下图:
http://pic002.cnblogs.com/images/2012/411346/2012060112135213.png
在屏幕上每一点到光源中心点做射线,对射线上点做采样。如果采样点被物体遮住,自然光照亮会减少。具体计算公式见GPU GERM 3相关那一张。最近处理结果如下图所示:
http://pic002.cnblogs.com/images/2012/411346/2012060112161023.jpg
4. 最后一步,将render target 2的贴图附在上图上,就是最后的结果了。
http://pic002.cnblogs.com/images/2012/411346/2012060112074267.jpg
完整代码如下:
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 AdditiveBlending 35 { 36 AlphaToCoverageEnable = FALSE; 37 BlendEnable[0] = TRUE; 38 SrcBlend = ONE; 39 DestBlend = ONE; 40 BlendOp = ADD; 41 SrcBlendAlpha = SRC_ALPHA; 42 DestBlendAlpha = INV_SRC_ALPHA; 43 RenderTargetWriteMask[0] = 0x0F; 44 }; 45 46 Texture2Dg_ModelTexture; 47 48 Texture2Dg_BlackSceneTexture; 49 Texture2Dg_NormalSceneTexture; 50 51 matrix g_World; 52 matrix g_View; 53 matrix g_Projection; 54 55 //float4 g_AmbientColor = float4(0.1f, 0.1f, 0.1f, 1.0f); 56 float4 g_DirLightColor = float4(0.3f, 0.3f, 0.3f, 1.0f); 57 float3 g_DirLightDir = float3(0.0f, 1.0f, -1.0f); 58 59 float4 g_LightPos = float4(0.0f, 1.0f, 0.0f, 1.0f); 60 uint NUM_SAMPLES = 200; 61 float g_Density = 1.0f; 62 float g_Weight = 1.0f; 63 float g_Decay = 0.98f; 64 float g_Exposure = 0.05f; 65 66 bool g_bLight; 67 68 struct VS_MODEL_INPUT 69 { 70 float4 Pos : POSITION; 71 float2 Tex : TEXCOORD0; 72 float3 Norm : NORMAL; 73 }; 74 75 struct PS_MODEL_INPUT 76 { 77 float4 Pos : SV_POSITION; 78 float2 Tex : TEXCOORD0; 79 float3 Norm : NORMAL; 80 }; 81 82 struct PS_MODEL_OUTPUT 83 { 84 float4 blackScene : SV_Target0; 85 float4 normalScene : SV_Target1; 86 }; 87 //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 88 struct VS_QUAD_INPUT 89 { 90 float4 Pos : POSITION; 91 float2 Tex : TEXCOORD0; 92 }; 93 94 struct PS_SCENE_INPUT 95 { 96 float4 Pos : SV_POSITION; 97 float2 Tex : TEXCOORD0; 98 float2 ScreenLightPos : TEXCOORD1; 99 };100 //---------------------------------------------------------------------------------------render black scene--------------------------------------------------------------------------------------------------------101 PS_MODEL_INPUT VS_SCENE(VS_MODEL_INPUT input)102 {103 PS_MODEL_INPUT output = (PS_MODEL_INPUT)0;104 output.Pos = input.Pos;105 output.Pos.w = 1;106 107 output.Pos = mul( output.Pos, g_World );108 output.Pos = mul( output.Pos, g_View );109 output.Pos = mul( output.Pos, g_Projection );110 output.Pos = output.Pos / output.Pos.w;111 112 output.Norm = input.Norm;113 output.Tex = input.Tex;114 return output;115 }116 117 PS_MODEL_OUTPUT PS_BLACK_SCENE(PS_MODEL_INPUT input)118 {119 PS_MODEL_OUTPUT output = (PS_MODEL_OUTPUT)0;120 121 if(g_bLight)122 {123 output.blackScene = float4(1.0f, 1.0f, 1.0f, 1.0f);124 output.normalScene = float4(0.0f, 0.0f, 0.0f, 0.0f);125 }126 else127 {128 output.blackScene = float4(0.0f, 0.0f, 0.0f, 1.0f);129 output.normalScene = dot(normalize(g_DirLightDir), input.Norm) * g_DirLightColor * g_ModelTexture.Sample( g_samWrap, input.Tex );130 output.normalScene.a = 1;131 }132 133 return output;134 }135 136 PS_SCENE_INPUT VS_VLS(VS_QUAD_INPUT input)137 {138 PS_SCENE_INPUT output = (PS_SCENE_INPUT)0;139 140 float2 Pos = input.Pos.xy;141 output.Pos = float4(Pos.xy, 0, 1);142 143 output.Tex =0.5 * (1 + Pos);144 145 float4 ScreenLightPos = g_LightPos;146 ScreenLightPos = mul( ScreenLightPos, g_World );147 ScreenLightPos = mul( ScreenLightPos, g_View );148 ScreenLightPos = mul( ScreenLightPos, g_Projection );149 ScreenLightPos = ScreenLightPos / ScreenLightPos.w;150 ScreenLightPos = (ScreenLightPos + 1.0f) / 2.0f;151 output.ScreenLightPos = ScreenLightPos;152 153 return output;154 }155 156 float4 PS_VLS(PS_SCENE_INPUT input) : SV_Target157 {158 float2 texCoord = input.Tex;159 160 float2 deltaTexCoord = (texCoord - input.ScreenLightPos); 161 deltaTexCoord *= 1.0f / NUM_SAMPLES * g_Density;162 163 float4 color = g_BlackSceneTexture.Sample(g_samClamp, float2(texCoord.x, 1 - texCoord.y));164 165 float illuminationDecay = 1.0f;166 167 for (uint i = 0; i < NUM_SAMPLES; i++)168 {169 texCoord -= deltaTexCoord;170 float4 sampleColor = g_BlackSceneTexture.Sample(g_samClamp, float2(texCoord.x, 1 - texCoord.y));//shift y after operation171 sampleColor *= illuminationDecay * g_Weight;172 color += sampleColor;173 illuminationDecay *= g_Decay;174 }175 176 color *= g_Exposure;177 color.a = 1;178 return color;179 }180 181 float4 PS_Blend(PS_SCENE_INPUT input) : SV_Target182 {183 float2 texCoord = input.Tex;184 return g_NormalSceneTexture.Sample(g_samClamp, float2(texCoord.x, 1 - texCoord.y));185 }186 187 technique10 RenderBlackScene188 {189 pass p0190 {191 SetVertexShader( CompileShader( vs_4_0, VS_SCENE() ) );192 SetGeometryShader( NULL );193 SetPixelShader( CompileShader( ps_4_0, PS_BLACK_SCENE() ) );194 195 SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );196 }197 }198 //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------199 technique10 VLS200 {201 pass p0202 {203 SetVertexShader( CompileShader( vs_4_0, VS_VLS() ) );204 SetGeometryShader( NULL );205 SetPixelShader( CompileShader( ps_4_0, PS_VLS() ) );206 207 SetBlendState( NoBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );208 }209 }210 211 technique10 BlendScene212 {213 pass p0214 {215 SetVertexShader( CompileShader( vs_4_0, VS_VLS() ) );216 SetGeometryShader( NULL );217 SetPixelShader( CompileShader( ps_4_0, PS_Blend() ) );218 219 SetBlendState( AdditiveBlending, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );220 SetDepthStencilState( EnableDepth, 0 );//set depth test to less_equal221 }222 }
页:
[1]