Working Alchemy SSAO shaders

This commit is contained in:
Robert Beckebans 2016-01-08 19:30:21 +01:00
parent 8a861c7914
commit 94c28fa8ff
9 changed files with 1345 additions and 71 deletions

View file

@ -60,7 +60,7 @@ const float METERS_TO_DOOM = ( 1.0 / DOOM_TO_METERS ); // meters to doom
/** Used for preventing AO computation on the sky (at infinite depth) and defining the CS Z to bilateral depth key scaling.
This need not match the real far plane but should not be much more than it.*/
const float FAR_PLANE_Z = -4000.0;
const float FAR_PLANE_Z = -16000.0;
/** World-space AO radius in scene units (r). e.g., 1.0m */
const float radius = 1.0 * METERS_TO_DOOM;
@ -71,7 +71,7 @@ const float invRadius2 = 1.0 / radius2;
const float bias = 0.01 * METERS_TO_DOOM;
/** intensity / radius^6 */
const float intensity = 0.5;
const float intensity = 0.3;
const float intensityDivR6 = intensity / ( radius* radius* radius* radius* radius* radius );
const float projScale = 300.0;// * METERS_TO_DOOM;
@ -119,6 +119,19 @@ float CSZToKey( float z )
return clamp( z * ( 1.0 / FAR_PLANE_Z ), 0.0, 1.0 );
}
/** Used for packing Z into the GB channels */
void packKey( float key, out float2 p )
{
// Round to the nearest 1/256.0
float temp = floor( key * 256.0 );
// Integer part
p.x = temp * ( 1.0 / 256.0 );
// Fractional part
p.y = key * 256.0 - temp;
}
/** Reconstructs screen-space unit normal from screen-space position */
float3 reconstructCSFaceNormal( float3 C )
{
@ -135,14 +148,23 @@ float3 reconstructNonUnitCSFaceNormal( float3 C )
/** Read the camera-space position of the point at screen-space pixel ssP */
float3 getPosition( float2 ssP, sampler2D cszBuffer )
{
#if 1
// derive clip space from the depth buffer and screen position
float windowZ = tex2D( cszBuffer, ssP ).x;
float3 ndc = float3( ssP * 2.0 - 1.0, windowZ * 2.0 - 1.0 );
//float clipW = -rpProjectionMatrixZ.w / ( -rpProjectionMatrixZ.z - ndc.z );
//float4 P = float4( ndc * clipW, clipW );
float4 P = float4( ndc, 1.0 );
#else
float4 P;
P.z = tex2D( cszBuffer, ssP ).r;
P.xy = float2( ssP ); //+ float2( 0.5 ) );
P.w = 1.0;
#endif
// offset to pixel center
//P = reconstructCSPosition( float2( ssP ) + float2( 0.5 ), P.z, projInfo );
#if 1
float4 csP;
csP.x = dot4( P, rpProjectionMatrixX );
csP.y = dot4( P, rpProjectionMatrixY );
@ -150,6 +172,7 @@ float3 getPosition( float2 ssP, sampler2D cszBuffer )
csP.w = dot4( P, rpProjectionMatrixW );
csP.xyz /= csP.w;
#endif
#if 0
float4 wP;
@ -186,7 +209,17 @@ float3 getOffsetPosition( ivec2 issC, vec2 unitOffset, float ssR, sampler2D cszB
float2 ossC = float2( ssP ) * rpScreenCorrectionFactor.xy;
P.z = texture( cszBuffer, ossC, 0.0 ).r;
float windowZ = texture( cszBuffer, ossC, 0.0 ).r;
#if 1
float3 ndc = float3( ossC * 2.0 - 1.0, windowZ * 2.0 - 1.0 );
//float clipW = -rpProjectionMatrixZ.w / ( -rpProjectionMatrixZ.z - ndc.z );
//P = float4( ndc * clipW, clipW );
P = float4( ndc, 1.0 );
//return P.xyz;
#else
//P.z = texture( cszBuffer, mipP, 0.0 ).r;
//P.z = texture( cszBuffer, mipP, mipLevel ).r;
@ -194,13 +227,16 @@ float3 getOffsetPosition( ivec2 issC, vec2 unitOffset, float ssR, sampler2D cszB
//P = reconstructCSPosition( ( vec2( ssP ) + vec2( 0.5 ) ) * invCszBufferScale, P.z, projInfo );
P.xy = ossC; //+ float2( 0.5 ) ) * invCszBufferScale;
P.w = 1.0;
#endif
#if 1
float4 csP;
csP.x = dot4( P, rpProjectionMatrixX );
csP.y = dot4( P, rpProjectionMatrixY );
csP.z = dot4( P, rpProjectionMatrixZ );
csP.w = dot4( P, rpProjectionMatrixW );
csP.xyz /= csP.w;
#endif
#if 0
float4 wP;
@ -294,7 +330,7 @@ float sampleAO( ivec2 issC, in float3 C, in float3 n_C, in float ssDiskRadius, i
const float MIN_RADIUS = 3.0; // pixels
#define visibility result.color.r
#define bilateralKey result.color.g
#define bilateralKey result.color.gb
void main( PS_IN fragment, out PS_OUT result )
{
@ -321,7 +357,8 @@ void main( PS_IN fragment, out PS_OUT result )
vec3 C = getPosition( ssC, CS_Z_buffer );
//float z = length( C - rpGlobalEyePos.xyz );
bilateralKey = CSZToKey( C.z );
//bilateralKey = CSZToKey( C.z );
packKey( CSZToKey( C.z ), bilateralKey );
visibility = 0.0;
@ -406,13 +443,14 @@ void main( PS_IN fragment, out PS_OUT result )
visibility = lerp( 1.0, A, saturate( ssDiskRadius - MIN_RADIUS ) );
//visibility = A;
#if defined(BRIGHTPASS)
//result.color = float4( visibility, bilateralKey, 0.0, 1.0 );
//result.color = float4( bilateralKey, bilateralKey, bilateralKey, 1.0 );
//result.color = float4( visibility, visibility, visibility, 1.0 );
result.color = float4( visibility, visibility, visibility, 1.0 );
//result.color = float4( n_C * 0.5 + 0.5, 1.0 );
//result.color = float4( n_C, 1.0 );
//result.color = texture( samp0, fragment.texcoord0 ).rgba;
#endif
// derive clip space from the depth buffer and screen position
// float windowZ = tex2D( samp1, fragment.texcoord0 ).x;
// float3 ndc = float3( fragment.texcoord0 * 2.0 - 1.0, windowZ * 2.0 - 1.0 );

View file

@ -75,7 +75,7 @@ struct PS_OUT
#define VALUE_IS_KEY 0
/** Channel encoding the bilateral key value (which must not be the same as VALUE_COMPONENTS) */
#if 0 //NUM_KEY_COMPONENTS == 2
#if 1 //NUM_KEY_COMPONENTS == 2
#define KEY_COMPONENTS gb
#else
#define KEY_COMPONENTS g
@ -97,9 +97,9 @@ struct PS_OUT
#define aoResult result.color.VALUE_COMPONENTS
#define keyPassThrough result.color.KEY_COMPONENTS
#if 0 //NUM_KEY_COMPONENTS == 2
#if 1 //NUM_KEY_COMPONENTS == 2
/** Returns a number on (0, 1) */
float unpackKey( vec2 p )
float unpackKey( float2 p )
{
return p.x * ( 256.0 / 257.0 ) + p.y * ( 1.0 / 257.0 );
}

View file

@ -8,6 +8,10 @@ return
-- shaders
"ambient_lighting.pixel",
"ambient_lighting.vertex",
"AmbientOcclusion_AO.pixel",
"AmbientOcclusion_AO.vertex",
"AmbientOcclusion_blur.pixel",
"AmbientOcclusion_blur.vertex",
"bink.pixel",
"bink.vertex",
"bink_gui.pixel",

View file

@ -149,6 +149,7 @@ void idRenderProgManager::Init()
{ BUILTIN_SMAA_NEIGHBORHOOD_BLENDING, "SMAA_final", "", 0, false },
{ BUILTIN_AMBIENT_OCCLUSION, "AmbientOcclusion_AO", "", 0, false },
{ BUILTIN_AMBIENT_OCCLUSION_AND_OUTPUT, "AmbientOcclusion_AO", "_write", BIT( BRIGHTPASS ), false },
{ BUILTIN_AMBIENT_OCCLUSION_BLUR, "AmbientOcclusion_blur", "", 0, false },
{ BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT, "AmbientOcclusion_blur", "_write", BIT( BRIGHTPASS ), false },
// RB end

View file

@ -458,6 +458,11 @@ public:
BindShader_Builtin( BUILTIN_AMBIENT_OCCLUSION );
}
void BindShader_AmbientOcclusionAndOutput()
{
BindShader_Builtin( BUILTIN_AMBIENT_OCCLUSION_AND_OUTPUT );
}
void BindShader_AmbientOcclusionBlur()
{
BindShader_Builtin( BUILTIN_AMBIENT_OCCLUSION_BLUR );
@ -592,6 +597,7 @@ protected:
BUILTIN_SMAA_NEIGHBORHOOD_BLENDING,
BUILTIN_AMBIENT_OCCLUSION,
BUILTIN_AMBIENT_OCCLUSION_AND_OUTPUT,
BUILTIN_AMBIENT_OCCLUSION_BLUR,
BUILTIN_AMBIENT_OCCLUSION_BLUR_AND_OUTPUT,
// RB end

File diff suppressed because it is too large Load diff

View file

@ -262,6 +262,7 @@ idCVar r_forceAmbient( "r_forceAmbient", "0.2", CVAR_RENDERER | CVAR_FLOAT, "ren
idCVar r_useSSGI( "r_useSSGI", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "use screen space global illumination and reflections" );
idCVar r_ssgiDebug( "r_ssgiDebug", "0", CVAR_RENDERER | CVAR_INTEGER, "" );
idCVar r_ssaoFiltering( "r_ssaoFiltering", "1", CVAR_RENDERER | CVAR_BOOL, "" );
// RB end
const char* fileExten[3] = { "tga", "png", "jpg" };

View file

@ -1841,6 +1841,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs
//}
//else
{
#if 0
if( r_useSSGI.GetBool() )
{
// fill geometry buffer with normal/roughness information
@ -1854,6 +1855,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs
}
}
else
#endif
{
// draw Quake 4 style ambient
if( drawSurf->jointCache )
@ -2101,6 +2103,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs
renderLog.CloseBlock();
renderLog.CloseMainBlock();
#if 0
if( r_useSSGI.GetBool() )
{
GL_SelectTexture( 0 );
@ -2124,6 +2127,7 @@ static void RB_AmbientPass( const drawSurf_t* const* drawSurfs, int numDrawSurfs
globalImages->BindNull();
}
#endif
}
// RB end
@ -4614,12 +4618,23 @@ void RB_SSAO()
const bool hdrIsActive = ( r_useHDR.GetBool() && globalFramebuffers.hdrFBO != NULL && globalFramebuffers.hdrFBO->IsBound() );
globalFramebuffers.ambientOcclusionFBO[0]->Bind();
glClearColor( 1, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT );
renderProgManager.BindShader_AmbientOcclusion();
if( r_ssaoFiltering.GetBool() )
{
globalFramebuffers.ambientOcclusionFBO[0]->Bind();
glClearColor( 1, 0, 0, 1 );
glClear( GL_COLOR_BUFFER_BIT );
renderProgManager.BindShader_AmbientOcclusion();
}
else
{
if( r_ssgiDebug.GetInteger() <= 0 )
{
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
}
renderProgManager.BindShader_AmbientOcclusionAndOutput();
}
float screenCorrectionParm[4];
screenCorrectionParm[0] = 1.0f / glConfig.nativeScreenWidth;
@ -4628,10 +4643,7 @@ void RB_SSAO()
screenCorrectionParm[3] = glConfig.nativeScreenHeight;
SetFragmentParm( RENDERPARM_SCREENCORRECTIONFACTOR, screenCorrectionParm ); // rpScreenCorrectionFactor
// let the fragment program know how many samples we are going to use
idVec4 samples( ( float )( 1 << r_motionBlur.GetInteger() ) );
SetFragmentParm( RENDERPARM_OVERBRIGHT, samples.ToFloatPtr() );
#if 0
// RB: set unprojection matrices so we can convert zbuffer values back to camera and world spaces
idRenderMatrix modelViewMatrix;
idRenderMatrix::Transpose( *( idRenderMatrix* )backEnd.viewDef->worldSpace.modelViewMatrix, modelViewMatrix );
@ -4643,9 +4655,10 @@ void RB_SSAO()
SetVertexParms( RENDERPARM_MODELMATRIX_X, cameraToWorldMatrix[0], 4 );
//SetVertexParms( RENDERPARM_MODELMATRIX_X, backEnd.viewDef->unprojectionToWorldRenderMatrix[0], 4 );
#endif
SetVertexParms( RENDERPARM_PROJMATRIX_X, backEnd.viewDef->unprojectionToCameraRenderMatrix[0], 4 );
float jitterTexOffset[4];
if( r_shadowMapRandomizeJitter.GetBool() )
{
@ -4669,58 +4682,64 @@ void RB_SSAO()
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
float jitterTexScale[4];
// AO blur X
if( r_ssaoFiltering.GetBool() )
{
float jitterTexScale[4];
// AO blur X
#if 1
globalFramebuffers.ambientOcclusionFBO[1]->Bind();
renderProgManager.BindShader_AmbientOcclusionBlur();
//const idScreenRect& viewport = backEnd.viewDef->viewport;
//globalImages->currentAOImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() );
// set axis parameter
jitterTexScale[0] = 1;
jitterTexScale[1] = 0;
jitterTexScale[2] = 0;
jitterTexScale[3] = 0;
SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale
GL_SelectTexture( 0 );
globalImages->ambientOcclusionImage[0]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
globalFramebuffers.ambientOcclusionFBO[1]->Bind();
renderProgManager.BindShader_AmbientOcclusionBlur();
//const idScreenRect& viewport = backEnd.viewDef->viewport;
//globalImages->currentAOImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() );
// set axis parameter
jitterTexScale[0] = 1;
jitterTexScale[1] = 0;
jitterTexScale[2] = 0;
jitterTexScale[3] = 0;
SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale
GL_SelectTexture( 0 );
globalImages->ambientOcclusionImage[0]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
#endif
// AO blur Y
if( hdrIsActive )
{
globalFramebuffers.hdrFBO->Bind();
// AO blur Y
if( hdrIsActive )
{
globalFramebuffers.hdrFBO->Bind();
}
else
{
Framebuffer::Unbind();
}
if( r_ssgiDebug.GetInteger() <= 0 )
{
GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO | GLS_DEPTHMASK | GLS_DEPTHFUNC_ALWAYS );
}
//globalImages->currentAOImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() );
renderProgManager.BindShader_AmbientOcclusionBlurAndOutput();
// set axis parameter
jitterTexScale[0] = 0;
jitterTexScale[1] = 1;
jitterTexScale[2] = 0;
jitterTexScale[3] = 0;
SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale
GL_SelectTexture( 0 );
globalImages->ambientOcclusionImage[1]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
}
else
{
Framebuffer::Unbind();
}
//globalImages->currentAOImage->CopyFramebuffer( viewport.x1, viewport.y1, viewport.GetWidth(), viewport.GetHeight() );
renderProgManager.BindShader_AmbientOcclusionBlurAndOutput();
// set axis parameter
jitterTexScale[0] = 0;
jitterTexScale[1] = 1;
jitterTexScale[2] = 0;
jitterTexScale[3] = 0;
SetFragmentParm( RENDERPARM_JITTERTEXSCALE, jitterTexScale ); // rpJitterTexScale
GL_SelectTexture( 0 );
globalImages->ambientOcclusionImage[1]->Bind();
RB_DrawElementsWithCounters( &backEnd.unitSquareSurface );
GL_CheckErrors();

View file

@ -1104,6 +1104,7 @@ extern idCVar r_forceAmbient;
extern idCVar r_useSSGI;
extern idCVar r_ssgiDebug;
extern idCVar r_ssaoFiltering;
// RB end
/*