//////////////////////////////////////////////////////////////////////////// // // Crytek Engine Shader Source File // Copyright (C), Crytek Studios, 2001-2007 // ------------------------------------------------------------------------- // File name: AmbientOcclusion.cfx // Version: v1.00 // Created: 04/12/2006 by Vladimir Kajalin // Description: Implementation of SSAO, TerrainAO (2.5 D maps), Fill lights // ------------------------------------------------------------------------- // History: // //////////////////////////////////////////////////////////////////////////// #include "Common.cfi" #include "ModificatorVT.cfi" // Shader global descriptions float Script : STANDARDSGLOBAL < string Script = "NoPreview;" "LocalConstants;" "ShaderDrawType = Custom;" "ShaderType = PostProcess;" >; // original depth target sampler2D sceneDepthSampler = sampler_state { Texture = $ZTarget; MinFilter = POINT; MagFilter = POINT; MipFilter = POINT; AddressU = Clamp; AddressV = Clamp; }; // downscaled depth target sampler2D sceneDepthSamplerAO = sampler_state { Texture = $ZTargetScaled; MinFilter = POINT; MagFilter = POINT; MipFilter = POINT; AddressU = Clamp; AddressV = Clamp; }; sampler2D depthTargetSampler : register(s0); sampler2D TerrainInfoSampler0 : register(s1); sampler2D TerrainInfoSampler1 : register(s2); #include "ShadowCommon.cfi" //=========================================================================== float4 AOSectorRange; float4 TerrainAOInfo; float4 FillLightPos; float4 FillLightColor; float4 SSAO_params float4x4 CompMatrix : PI_Composite; ///////////////////////////// // structs struct pixout_cl { float4 Color : COLOR0; }; struct vert2fragSSAO { float4 HPosition : POSITION; float4 ScreenTC : TEXCOORD0; float3 WS_ViewVect: TEXCOORD1; }; struct app2vertShadow { IN_P IN_TBASE float3 viewDir : TEXCOORD1; }; vert2fragSSAO Deferred_SSAO_Pass_VS(app2vertShadow IN) { vert2fragSSAO OUT; #ifndef OPENGL OUT = (vert2fragSSAO)0; #endif OUT.HPosition = mul(CompMatrix, IN.Position); OUT.ScreenTC.xy = IN.baseTC.xy; OUT.ScreenTC.zw = IN.baseTC.xy*g_VS_ScreenSize.xy/4; OUT.WS_ViewVect = IN.viewDir; return OUT; } ///////////////// shadows pixel shader ////////////////// /*pixout_cl AmbientShadowMaskPS(vert2fragShadowNew IN) { pixout_cl OUT; float SceneDepth = tex2D( sceneDepthSampler, IN.ScreenTC.xy ).r; float2 randTC; randTC.xy = IN.ScreenTC.xy*256; float3 rotSample = tex2D(sRotSampler AO, randTC+float2(SceneDepth,SceneDepth)).rgb; rotSample = 2.0 * rotSample - 1.0; rotSample.xyz = normalize(rotSample.xyz); // define kernel float scale = 0.02; float3 irreg_kernel[8] = { float3(0.527837, -0.085868 ,0.527837) * scale, float3(-0.040088, 0.536087, -0.040088) * scale, float3(-0.670445, -0.179949, -0.670445) * scale, float3(-0.419418, -0.616039, -0.419418) * scale, float3(0.440453, -0.639399, 0.440453) * scale, float3(-0.757088, 0.349334, -0.757088) * scale, float3(0.574619, 0.685879,0.574619) * scale, float3(0.03851, -0.939059, 0.03851) * scale }; // get rotatiojn matrix float3x3 rotMat; GetRotationV0Terrain(rotSample, rotMat); float fDistScale = 0.5 / saturate(SceneDepth); // sample float fSkyAccess = 0; for(float i=0; i<8; i++) { float3 irregSample = mul(irreg_kernel[i], rotMat); float2 ScreenTC2 = IN.ScreenTC.xy + irregSample.xy * fDistScale; float SceneDepth2 = tex2D( sceneDepthSampler, ScreenTC2 ).r; float fRange = abs(SceneDepth2-SceneDepth)*12; fSkyAccess += lerp(saturate(SceneDepth2>(SceneDepth+irregSample.z)), .75, saturate(fRange)); } OUT.Color = saturate(fSkyAccess*0.25); return OUT; }*/ sampler2D sRotSampler4x4_16 = sampler_state { Texture = $16PointsOnSphere; MinFilter = POINT; MagFilter = POINT; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; /* sampler2D sRotSampler4x4 = sampler_state { Texture = Textures/Defaults/noise4x4.dds; MinFilter = POINT; MagFilter = POINT; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; */ // vPlane should be normalized // the returned vector has the same length as vDir float3 mirror( float3 vDir, float3 vPlane ) { return vDir - 2 * vPlane * dot(vPlane,vDir); } /* float GetVarianceAO(sampler2D depthMap, float3 p) { float2 moments = tex2D( depthMap, p.xy ).xy; // Variance shadow mapping float M = moments.r; //mean //TD invesigate: we calculate variance in non-shifted by 0.5 space here //is it correct float E_x2 = moments.g; float Ex_2 = M * M; float variance = (E_x2 - Ex_2);//decrease range of variance to increase precision for 16-bit formats float m_d = M - p.z; float p_max = variance / (variance + m_d * m_d); // Standard shadow map comparison float lit_factor = m_d > -0.001; //select properly shadow region because of one-tailed version of inequality float shadow = max(lit_factor, p_max); return shadow; } */ /* sampler2D SSAO_Sampler_0 : register(s4); { MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; sampler2D SSAO_Sampler_1 : register(s5); { MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; sampler2D SSAO_Sampler_2 : register(s6); { MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; sampler2D SSAO_Sampler_3 : register(s7); { MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; sampler2D SSAO_Sampler_4 : register(s8); { MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; sampler2D SSAO_Sampler_5 : register(s9); { MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; sampler2D SSAO_Sampler_6 : register(s10); { MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; sampler2D SSAO_Sampler_7 : register(s11); { MinFilter = LINEAR; MagFilter = LINEAR; MipFilter = NONE; AddressU = Wrap; AddressV = Wrap; }; pixout_cl Deferred_SSAO_Pass_PS_DepthBlurBased(vert2fragSSAO IN) { pixout_cl OUT; // float3 p = float3( IN.ScreenTC.xy, tex2D( sceneDepthSampler, IN.ScreenTC.xy ).r ); //OUT.Color = GetVarianceAO( SSAO_Sampler_3, p ); float fSceneDepth = tex2D( sceneDepthSampler, IN.ScreenTC.xy ).r; float4 arrSceneDepthBlur[8]; arrSceneDepthBlur[0] = tex2D( SSAO_Sampler_0, IN.ScreenTC.xy ); arrSceneDepthBlur[1] = tex2D( SSAO_Sampler_1, IN.ScreenTC.xy ); arrSceneDepthBlur[2] = tex2D( SSAO_Sampler_2, IN.ScreenTC.xy ); arrSceneDepthBlur[3] = tex2D( SSAO_Sampler_3, IN.ScreenTC.xy ); arrSceneDepthBlur[4] = tex2D( SSAO_Sampler_4, IN.ScreenTC.xy ); arrSceneDepthBlur[5] = tex2D( SSAO_Sampler_5, IN.ScreenTC.xy ); arrSceneDepthBlur[6] = tex2D( SSAO_Sampler_6, IN.ScreenTC.xy ); arrSceneDepthBlur[7] = tex2D( SSAO_Sampler_7, IN.ScreenTC.xy ); OUT.Color = 0; int nSamples = 3; int nStart = 0; for(int t=nStart; t