六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 358|回复: 0

Introduction to my galaxy engine 7: Volumetric Light Scattering

[复制链接]

升级  7.33%

72

主题

72

主题

72

主题

举人

Rank: 3Rank: 3

积分
222
 楼主| 发表于 2012-12-30 11:51:42 | 显示全部楼层 |阅读模式
Introduction to my galaxy engine 7: Volumetric Light Scattering

<div id="cnblogs_post_body">花了一天时间,给引擎中添加了Volumetric Light Scattering模块.
视频地址:https://vimeo.com/43232452

截屏图如下:

Volumetric Light Scattering又名god light,Crepuscular Rays 等等, 也是一个游戏中比较常见的效果,主要是用post process来实现的。
具体实现步骤如下:
1.渲染发光体和场景,场景不添加材质,只显示成黑色,将结果渲染到render target 1上。


2. 只渲染场景,添加材质和光照,将结果渲染到render target 2上。
3. 对render target 1 做采样处理,计算光照。原理见如下图:

在屏幕上每一点到光源中心点做射线,对射线上点做采样。如果采样点被物体遮住,自然光照亮会减少。具体计算公式见GPU GERM 3相关那一张。最近处理结果如下图所示:

4. 最后一步,将render target 2的贴图附在上图上,就是最后的结果了。

完整代码如下:
<div class="cnblogs_code">  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 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 Texture2D  g_ModelTexture; 47 48 Texture2D  g_BlackSceneTexture; 49 Texture2D  g_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 }
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表