Files
HL2Overcharged/materialsystem/stdshaders/ssao_ps30.fxc
2025-05-21 21:20:08 +03:00

134 lines
3.6 KiB
Plaintext

// Crossroads SSAO Shader based off Arkano22's GLSL Shader ( assembled by Martins Upitis )
#include "common_ps_fxc.h"
sampler FrameBufferSampler : register( s0 );
const float2 g_TexelSize : register( c0 );
const int g_SamplesCount : register( c1 ); // samples count
const float g_SSAO_Radius : register( c2 ); // ao radius
const float g_SSAO_Bias : register( c3 ); // self-shadowing reduction
const float g_lumInfluence : register( c4 ); // how much luminance affects occlusion
const float g_SSAOContrast : register( c5 );
const float g_SSAOZNear : register( c6 ); // Z-near
const float g_SSAOZFar : register( c7 ); // Z-far
const float g_SSAO_Bias_Offset : register( c8 );
#define PI 3.14159265
static float gdisplace = g_SSAO_Bias; // gauss bell center
float2 rand(float2 coord, float2 size) //generating noise texture for dithering
{
float noiseX = frac(sin(dot(coord, float2(12.9898,78.233))) * 43758.5453) * 2.0f-1.0f;
float noiseY = frac(sin(dot(coord, float2(12.9898,78.233)*2.0)) * 43758.5453) * 2.0f-1.0f;
return float2(noiseX,noiseY)*0.001;
}
float readDepth(in float2 coord, sampler tex)
{
return tex2Dlod(tex, float4(coord, 0, 0)).a * (g_SSAOZNear / g_SSAOZFar);
}
float compareDepths(in float depth1, in float depth2,inout int far)
{
float garea = 1.0; //gauss bell width
float diff = (depth1 - depth2)*100.0; //depth difference (0-100)
//reduce left bell width to avoid self-shadowing
if ( diff < gdisplace + g_SSAO_Bias_Offset )
{
garea = g_SSAO_Bias;
}
else
{
far = 1;
}
float gauss = pow(2.7182,-2.0*(diff-gdisplace)*(diff-gdisplace)/(garea*garea));
return gauss;
}
float calAO(float2 uv, float depth, float dw, float dh, sampler tex)
{
float dd = (1.0-depth)*g_SSAO_Radius;
float temp = 0.0;
float temp2 = 0.0;
float coordw = uv.x + dw*dd;
float coordh = uv.y + dh*dd;
float coordw2 = uv.x - dw*dd;
float coordh2 = uv.y - dh*dd;
float2 coord = float2(coordw , coordh);
float2 coord2 = float2(coordw2, coordh2);
int far = 0;
temp = compareDepths(depth, readDepth(coord,tex),far);
//DEPTH EXTRAPOLATION:
if (far > 0)
{
temp2 = compareDepths(readDepth(coord2,tex),depth,far);
temp += (1.0-temp)*temp2;
}
return temp;
}
void DoSSAO( in float2 uv, in float2 texelSize, in sampler color_depth, out float ao_out )
{
float2 size = 1.0f / texelSize;
float2 noise = rand(uv,size);
float depth = readDepth(uv, color_depth);
float w = texelSize.x/clamp(depth, 0.25f, 1.0)+(noise.x*(1.0f-noise.x));
float h = texelSize.y/clamp(depth, 0.25f, 1.0)+(noise.y*(1.0f-noise.y));
float pw;
float ph;
float ao = 0;
float dl = PI*(3.0-sqrt(5.0));
float dz = 1.0/float( g_SamplesCount );
float z = 1.0 - dz/1.0;
float l = 0.0;
for (int i = 1; i <= g_SamplesCount; i++)
{
float r = sqrt(1.0-z);
pw = cos(l)*r;
ph = sin(l)*r;
ao += calAO( uv, depth, pw*w, ph*h, color_depth );
z = z - dz;
l = l + dl;
}
ao /= float( g_SamplesCount );
ao = 1.0-ao;
float3 color = tex2D(color_depth,uv).rgb;
float3 lumcoeff = float3( 0.2126f, 0.7152f, 0.0722f );
float lum = dot( color.rgb, lumcoeff );
float3 luminance = float( lum );
ao_out = lerp( ao, 1.0f, luminance*g_lumInfluence );
ao_out = ((ao_out - 0.5f) * max(g_SSAOContrast, 0)) + 0.5f;
}
struct PS_INPUT
{
HALF2 vTexCoord : TEXCOORD0;
};
float4 main( PS_INPUT i ) : COLOR
{
float ssao_out = (float)0;
DoSSAO( i.vTexCoord, g_TexelSize, FrameBufferSampler, ssao_out );
float3 out_col = float( ssao_out.x );
out_col = out_col * float( 2.0 );
return FinalOutput( float4( out_col, 1.0f ), 0, PIXEL_FOG_TYPE_HEIGHT, TONEMAP_SCALE_LINEAR );
}