Сделал сасао. Лепил по
статье Борескова. Взял предпоследний шейдер и перевел на HLSL.
texture depthTexture;
sampler depthSampler : register(s0) = sampler_state
{
texture = <depthTexture>;
};
texture rotateTexture;
sampler rotateSampler : register(s1) = sampler_state
{
texture = <rotateTexture>;
};
float4x4 invViewProj;
float screenWidth;
float screenHeight;
float rotateMapWidth;
float rotateMapHeight;
float radius;
float distScale;
float bias;
float4 main( float2 texCoord : TEXCOORD0 ) : COLOR0
{
float4 rndTable[8];
rndTable[0] = float4 ( -0.5, -0.5, -0.5, 0.0 );
rndTable[1] = float4 ( 0.5, -0.5, -0.5, 0.0 );
rndTable[2] = float4 ( -0.5, 0.5, -0.5, 0.0 );
rndTable[3] = float4 ( 0.5, 0.5, -0.5, 0.0 );
rndTable[4] = float4 ( -0.5, -0.5, 0.5, 0.0 );
rndTable[5] = float4 ( 0.5, -0.5, 0.5, 0.0 );
rndTable[6] = float4 ( -0.5, 0.5, 0.5, 0.0 );
rndTable[7] = float4 ( 0.5, 0.5, 0.5, 0.0 );
float depth = tex2D( depthSampler, texCoord ).r;
float4 screenPosition;
screenPosition.x = texCoord.x * 2.0f - 1.0f ;
screenPosition.y = -( texCoord.y * 2.0f - 1.0f);
screenPosition.z = depth;
screenPosition.w = 1.0f;
float4 position = mul( screenPosition, invViewProj );
position /= position.w;
float2 rotateMapCoord = float2( texCoord.x * screenWidth / rotateMapWidth, texCoord.y * screenHeight / rotateMapHeight );
float3 plane = tex2D( rotateSampler, rotateMapCoord ).xyz;
float attenuation = 0.0;
for( int i = 0; i < 8; i++ )
{
float3 sample = reflect( rndTable[ i ].xyz, plane );
float2 zSampleTexCoord = texCoord + ( radius * sample.xy ) / position.z;
float zSample = tex2D( depthSampler, zSampleTexCoord ).r;
screenPosition.x = zSampleTexCoord.x * 2.0f - 1.0f ;
screenPosition.y = -( zSampleTexCoord.y * 2.0f - 1.0f);
screenPosition.z = zSample;
screenPosition.w = 1.0f;
float4 iPosition = mul( screenPosition, invViewProj );
iPosition /= iPosition.w;
float dist = max ( iPosition.z - position.z, 0.0 ) / distScale;
float occl = 15 * max ( dist * (2.0 - dist), 0.0 );
attenuation += 1.0 / ( 1.0 + occl*occl );
}
attenuation = clamp ( attenuation / 8.0 + bias, 0.0, 1.0 );
return float4( attenuation, attenuation, attenuation, 1.0f );
};
Было несколько непонятных магических чисел, но порыскав по сурсам я понял что откуда идет.
Но результат как-то не очень ( картинка в аттаче результат AO ).
Киньте шейдер AO, который можно перевести ( или уже на HLSL ) без плясок с бубном.