mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-04-24 02:32:18 +00:00
Some experiments similar to Obra Dinn and fixed old SSAO
This commit is contained in:
parent
cebba26908
commit
a3a52c97fe
9 changed files with 611 additions and 37 deletions
|
@ -1528,6 +1528,43 @@ void idRenderBackend::GetCurrentBindingLayout( int type )
|
|||
desc[1].bindings[1].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_POST_PROCESS_FINAL2 )
|
||||
{
|
||||
if( desc[0].bindings.empty() )
|
||||
{
|
||||
desc[0].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::ConstantBuffer( 0, paramCb, range ),
|
||||
nvrhi::BindingSetItem::Texture_SRV( 0, ( nvrhi::ITexture* )GetImageAt( 0 )->GetTextureID() ),
|
||||
nvrhi::BindingSetItem::Texture_SRV( 1, ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID() ),
|
||||
nvrhi::BindingSetItem::Texture_SRV( 2, ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID() ),
|
||||
nvrhi::BindingSetItem::Texture_SRV( 3, ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID() )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[0].bindings[0].resourceHandle = paramCb;
|
||||
desc[0].bindings[0].range = range;
|
||||
desc[0].bindings[1].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 0 )->GetTextureID();
|
||||
desc[0].bindings[2].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 1 )->GetTextureID();
|
||||
desc[0].bindings[3].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 2 )->GetTextureID();
|
||||
desc[0].bindings[4].resourceHandle = ( nvrhi::ITexture* )GetImageAt( 3 )->GetTextureID();
|
||||
}
|
||||
|
||||
if( desc[1].bindings.empty() )
|
||||
{
|
||||
desc[1].bindings =
|
||||
{
|
||||
nvrhi::BindingSetItem::Sampler( 0, commonPasses.m_LinearClampSampler ),
|
||||
nvrhi::BindingSetItem::Sampler( 1, commonPasses.m_LinearWrapSampler )
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
desc[1].bindings[0].resourceHandle = commonPasses.m_LinearClampSampler;
|
||||
desc[1].bindings[1].resourceHandle = commonPasses.m_LinearWrapSampler;
|
||||
}
|
||||
}
|
||||
else if( type == BINDING_LAYOUT_NORMAL_CUBE )
|
||||
{
|
||||
if( desc[0].bindings.empty() )
|
||||
|
|
|
@ -6259,6 +6259,34 @@ void idRenderBackend::PostProcess( const void* data )
|
|||
GL_SelectTexture( 1 );
|
||||
globalImages->blueNoiseImage256->Bind();
|
||||
|
||||
GL_SelectTexture( 2 );
|
||||
globalImages->gbufferNormalsRoughnessImage->Bind();
|
||||
|
||||
GL_SelectTexture( 3 );
|
||||
if( r_useHierarchicalDepthBuffer.GetBool() )
|
||||
{
|
||||
commandList->clearTextureFloat( globalImages->hierarchicalZbufferImage->GetTextureHandle(), nvrhi::AllSubresources, nvrhi::Color( 1.f ) );
|
||||
|
||||
// build hierarchical depth buffer
|
||||
renderLog.OpenBlock( "Render_HiZ" );
|
||||
|
||||
commonPasses.BlitTexture(
|
||||
commandList,
|
||||
globalFramebuffers.csDepthFBO[0]->GetApiObject(),
|
||||
globalImages->currentDepthImage->GetTextureHandle(),
|
||||
&bindingCache );
|
||||
|
||||
hiZGenPass->Dispatch( commandList, MAX_HIERARCHICAL_ZBUFFERS );
|
||||
|
||||
renderLog.CloseBlock();
|
||||
|
||||
globalImages->hierarchicalZbufferImage->Bind();
|
||||
}
|
||||
else
|
||||
{
|
||||
globalImages->currentDepthImage->Bind();
|
||||
}
|
||||
|
||||
float jitterTexScale[4] = {};
|
||||
|
||||
if( r_renderMode.GetInteger() == RENDERMODE_C64 || r_renderMode.GetInteger() == RENDERMODE_C64_HIGHRES )
|
||||
|
@ -6308,6 +6336,73 @@ void idRenderBackend::PostProcess( const void* data )
|
|||
|
||||
SetFragmentParm( RENDERPARM_JITTERTEXOFFSET, jitterTexOffset ); // rpJitterTexOffset
|
||||
|
||||
#if 1
|
||||
//SetVertexParms( RENDERPARM_MODELMATRIX_X, viewDef->unprojectionToCameraRenderMatrix[0], 4 );
|
||||
SetVertexParms( RENDERPARM_MODELMATRIX_X, viewDef->unprojectionToWorldRenderMatrix[0], 4 );
|
||||
|
||||
//R_MatrixMultiply( viewDef->worldSpace.modelViewMatrix, viewDef->projectionMatrix, viewDef->unprojectionToWorldMatrix );
|
||||
///R_MatrixFullInverse( viewDef->unprojectionToWorldMatrix, viewDef->unprojectionToWorldMatrix );
|
||||
|
||||
//idRenderMatrix::Transpose( *( idRenderMatrix* )viewDef->unprojectionToWorldMatrix, viewDef->unprojectionToWorldRenderMatrix );
|
||||
#else
|
||||
idRenderMatrix matClipToView;
|
||||
idRenderMatrix::Inverse( *( idRenderMatrix* ) viewDef->projectionMatrix, matClipToView );
|
||||
|
||||
SetVertexParms( RENDERPARM_MODELMATRIX_X, matClipToView[0], 4 );
|
||||
#endif
|
||||
|
||||
{
|
||||
// transform by the camera rotation
|
||||
const idVec3& origin = viewDef->renderView.vieworg;
|
||||
const idMat3& axis = viewDef->renderView.viewaxis;
|
||||
|
||||
float viewerMatrix[16];
|
||||
viewerMatrix[0 * 4 + 0] = axis[0][0];
|
||||
viewerMatrix[1 * 4 + 0] = axis[0][1];
|
||||
viewerMatrix[2 * 4 + 0] = axis[0][2];
|
||||
viewerMatrix[3 * 4 + 0] = - origin[0] * axis[0][0] - origin[1] * axis[0][1] - origin[2] * axis[0][2];
|
||||
|
||||
viewerMatrix[0 * 4 + 1] = axis[1][0];
|
||||
viewerMatrix[1 * 4 + 1] = axis[1][1];
|
||||
viewerMatrix[2 * 4 + 1] = axis[1][2];
|
||||
viewerMatrix[3 * 4 + 1] = - origin[0] * axis[1][0] - origin[1] * axis[1][1] - origin[2] * axis[1][2];
|
||||
|
||||
viewerMatrix[0 * 4 + 2] = axis[2][0];
|
||||
viewerMatrix[1 * 4 + 2] = axis[2][1];
|
||||
viewerMatrix[2 * 4 + 2] = axis[2][2];
|
||||
viewerMatrix[3 * 4 + 2] = - origin[0] * axis[2][0] - origin[1] * axis[2][1] - origin[2] * axis[2][2];
|
||||
|
||||
viewerMatrix[0 * 4 + 3] = 0.0f;
|
||||
viewerMatrix[1 * 4 + 3] = 0.0f;
|
||||
viewerMatrix[2 * 4 + 3] = 0.0f;
|
||||
viewerMatrix[3 * 4 + 3] = 1.0f;
|
||||
|
||||
float mvp[16];
|
||||
float modelViewdMatrix[16];
|
||||
float unprojectionToWorldMatrix[16];
|
||||
|
||||
static float s_flipMatrix[16] =
|
||||
{
|
||||
// convert from our coordinate system (looking down X)
|
||||
// to OpenGL's coordinate system (looking down -Z)
|
||||
0, 0, -1, 0,
|
||||
-1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 0, 1
|
||||
};
|
||||
|
||||
// convert from our coordinate system (looking down X)
|
||||
// to OpenGL's coordinate system (looking down -Z)
|
||||
R_MatrixMultiply( viewerMatrix, s_flipMatrix, modelViewdMatrix );
|
||||
|
||||
R_MatrixMultiply( modelViewdMatrix, viewDef->projectionMatrix, mvp );
|
||||
R_MatrixFullInverse( mvp, unprojectionToWorldMatrix );
|
||||
|
||||
idRenderMatrix unprojectionToWorldRenderMatrix;
|
||||
idRenderMatrix::Transpose( *( idRenderMatrix* )unprojectionToWorldMatrix, unprojectionToWorldRenderMatrix );
|
||||
//SetVertexParms( RENDERPARM_MODELMATRIX_X, unprojectionToWorldRenderMatrix[0], 4 );
|
||||
}
|
||||
|
||||
// Draw
|
||||
DrawElementsWithCounters( &unitSquareSurface );
|
||||
}
|
||||
|
|
|
@ -822,6 +822,7 @@ enum bindingLayoutType_t
|
|||
// NO GPU SKINNING ANYMORE
|
||||
BINDING_LAYOUT_POST_PROCESS_INGAME,
|
||||
BINDING_LAYOUT_POST_PROCESS_FINAL,
|
||||
BINDING_LAYOUT_POST_PROCESS_FINAL2,
|
||||
|
||||
BINDING_LAYOUT_BLIT,
|
||||
BINDING_LAYOUT_DRAW_AO,
|
||||
|
|
|
@ -327,8 +327,8 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
|
|||
auto pp3DBindingLayout = nvrhi::BindingLayoutDesc()
|
||||
.setVisibility( nvrhi::ShaderType::All )
|
||||
.addItem( renderParmLayoutItem )
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // current render
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // normal map
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // HDR _currentRender
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // normal map
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ); // mask
|
||||
|
||||
bindingLayouts[BINDING_LAYOUT_POST_PROCESS_INGAME] = { device->createBindingLayout( pp3DBindingLayout ), samplerOneBindingLayout };
|
||||
|
@ -336,11 +336,21 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
|
|||
auto ppFxBindingLayout = nvrhi::BindingLayoutDesc()
|
||||
.setVisibility( nvrhi::ShaderType::All )
|
||||
.addItem( renderParmLayoutItem )
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) )
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) );
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // LDR _currentRender
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ); // _blueNoise
|
||||
|
||||
bindingLayouts[BINDING_LAYOUT_POST_PROCESS_FINAL] = { device->createBindingLayout( ppFxBindingLayout ), samplerTwoBindingLayout };
|
||||
|
||||
auto ppFxBindingLayout2 = nvrhi::BindingLayoutDesc()
|
||||
.setVisibility( nvrhi::ShaderType::All )
|
||||
.addItem( renderParmLayoutItem )
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // LDR _currentRender
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 1 ) ) // _blueNoise
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 2 ) ) // _currentNormals
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 3 ) ); // _currentDepth
|
||||
|
||||
bindingLayouts[BINDING_LAYOUT_POST_PROCESS_FINAL2] = { device->createBindingLayout( ppFxBindingLayout2 ), samplerTwoBindingLayout };
|
||||
|
||||
auto normalCubeBindingLayoutDesc = nvrhi::BindingLayoutDesc()
|
||||
.setVisibility( nvrhi::ShaderType::Pixel )
|
||||
.addItem( nvrhi::BindingLayoutItem::Texture_SRV( 0 ) ) // cube map
|
||||
|
@ -522,7 +532,7 @@ void idRenderProgManager::Init( nvrhi::IDevice* device )
|
|||
{ BUILTIN_WOBBLESKY, "builtin/legacy/wobblesky", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_DEFAULT },
|
||||
{ BUILTIN_POSTPROCESS, "builtin/post/postprocess", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_C64, "builtin/post/retro_c64", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_CPC, "builtin/post/retro_cpc", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_CPC, "builtin/post/retro_cpc", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL2 },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_GENESIS, "builtin/post/retro_genesis", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_POSTPROCESS_RETRO_PSX, "builtin/post/retro_ps1", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
{ BUILTIN_CRT_MATTIAS, "builtin/post/crt_mattias", "", {}, false, SHADER_STAGE_DEFAULT, LAYOUT_DRAW_VERT, BINDING_LAYOUT_POST_PROCESS_FINAL },
|
||||
|
|
|
@ -160,18 +160,21 @@ float3 reconstructNonUnitCSFaceNormal( float3 C )
|
|||
return n;
|
||||
}
|
||||
|
||||
float3 reconstructCSPosition( float2 S, float z )
|
||||
float3 reconstructCSPosition( float2 S, float depth )
|
||||
{
|
||||
float4 P;
|
||||
P.z = z;// * 2.0 - 1.0;
|
||||
P.xy = ( S * rpWindowCoord.xy ) * 2.0 - 1.0;
|
||||
P.w = 1.0;
|
||||
// derive clip space from the depth buffer and screen position
|
||||
float2 uv = S * rpWindowCoord.xy;
|
||||
float3 ndc = float3( uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth );
|
||||
float clipW = -rpProjectionMatrixZ.w / ( -rpProjectionMatrixZ.z - ndc.z );
|
||||
|
||||
float4 clip = float4( ndc * clipW, clipW );
|
||||
|
||||
// camera space position
|
||||
float4 csP;
|
||||
csP.x = dot4( P, rpModelMatrixX );
|
||||
csP.y = dot4( P, rpModelMatrixY );
|
||||
csP.z = dot4( P, rpModelMatrixZ );
|
||||
csP.w = dot4( P, rpModelMatrixW );
|
||||
csP.x = dot4( rpModelMatrixX, clip );
|
||||
csP.y = dot4( rpModelMatrixY, clip );
|
||||
csP.z = dot4( rpModelMatrixZ, clip );
|
||||
csP.w = dot4( rpModelMatrixW, clip );
|
||||
|
||||
csP.xyz /= csP.w;
|
||||
|
||||
|
@ -388,7 +391,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
}
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
float randomPatternRotationAngle = BlueNoise( float2( ssP.xy ), 10.0 ) * 10.0;
|
||||
//float randomPatternRotationAngle = InterleavedGradientNoise( ssP.xy ) * 10.0;
|
||||
#else
|
||||
|
|
|
@ -153,6 +153,8 @@ void main( VS_IN vertex, out VS_OUT result )
|
|||
result.texcoord1.x = dot4( vertex.texcoord.xy, rpBumpMatrixS );
|
||||
result.texcoord1.y = dot4( vertex.texcoord.xy, rpBumpMatrixT );
|
||||
|
||||
//result.texcoord1.xy = psxAffineTexMapping( result.texcoord1.xy, )
|
||||
|
||||
//# texture 2 has one texgen
|
||||
result.texcoord2 = defaultTexCoord;
|
||||
result.texcoord2.x = dot4( modelPosition, rpLightFalloffS );
|
||||
|
|
|
@ -33,9 +33,11 @@ If you have questions concerning this license or the applicable additional terms
|
|||
// *INDENT-OFF*
|
||||
Texture2D t_BaseColor : register( t0 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_BlueNoise : register( t1 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_Normals : register( t2 VK_DESCRIPTOR_SET( 0 ) );
|
||||
Texture2D t_Depth : register( t3 VK_DESCRIPTOR_SET( 0 ) );
|
||||
|
||||
SamplerState samp0 : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState samp1 : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
SamplerState s_LinearClamp : register(s0 VK_DESCRIPTOR_SET( 1 ) );
|
||||
SamplerState s_LinearWrap : register(s1 VK_DESCRIPTOR_SET( 1 ) ); // blue noise 256
|
||||
|
||||
struct PS_IN
|
||||
{
|
||||
|
@ -53,17 +55,6 @@ struct PS_OUT
|
|||
#define RESOLUTION_DIVISOR 4.0
|
||||
#define NUM_COLORS 32 // original 27
|
||||
|
||||
/*
|
||||
float LinearTweak1( float c )
|
||||
{
|
||||
return ( c <= 0.04045 ) ? c / 12.92 : pow( ( c + 0.055 ) / 1.055, 1.4 );
|
||||
}
|
||||
|
||||
float3 LinearTweak3( float3 c )
|
||||
{
|
||||
return float3( Linear1( c.r ), Linear1( c.g ), Linear1( c.b ) );
|
||||
}
|
||||
*/
|
||||
|
||||
float3 Average( float3 pal[NUM_COLORS] )
|
||||
{
|
||||
|
@ -119,7 +110,210 @@ float3 LinearSearch( float3 c, float3 pal[NUM_COLORS] )
|
|||
|
||||
#define RGB(r, g, b) float3(float(r)/255.0, float(g)/255.0, float(b)/255.0)
|
||||
|
||||
// http://www.cse.cuhk.edu.hk/~ttwong/papers/spheremap/spheremap.html
|
||||
float3 healpix( float3 p )
|
||||
{
|
||||
float a = atan2( p.z, p.x ) * 0.63662;
|
||||
float h = 3.0 * abs( p.y );
|
||||
float h2 = 0.75 * p.y;
|
||||
float2 uv = float2( a + h2, a - h2 );
|
||||
h2 = sqrt( 3.0 - h );
|
||||
float a2 = h2 * frac( a );
|
||||
uv = lerp( uv, float2( -h2 + a2, a2 ), step( 2.0, h ) );
|
||||
|
||||
#if 1
|
||||
return float3( uv, 1.0 );
|
||||
#else
|
||||
float3 col = spheretex( uv );
|
||||
col.x = a * 0.5;
|
||||
|
||||
return HSVToRGB( float3( col.x, 0.8, col.z ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
// can be either view space or world space depending on rpModelMatrix
|
||||
float3 ReconstructPosition( float2 S, float depth )
|
||||
{
|
||||
// derive clip space from the depth buffer and screen position
|
||||
float2 uv = S * rpWindowCoord.xy;
|
||||
float3 ndc = float3( uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0, depth );
|
||||
float clipW = -rpProjectionMatrixZ.w / ( -rpProjectionMatrixZ.z - ndc.z );
|
||||
|
||||
float4 clip = float4( ndc * clipW, clipW );
|
||||
|
||||
// camera space position
|
||||
float4 csP;
|
||||
csP.x = dot4( rpModelMatrixX, clip );
|
||||
csP.y = dot4( rpModelMatrixY, clip );
|
||||
csP.z = dot4( rpModelMatrixZ, clip );
|
||||
csP.w = dot4( rpModelMatrixW, clip );
|
||||
|
||||
csP.xyz /= csP.w;
|
||||
|
||||
return csP.xyz;
|
||||
}
|
||||
|
||||
float3 GetPosition( int2 ssP )
|
||||
{
|
||||
float depth = texelFetch( t_Depth, ssP, 0 ).r;
|
||||
|
||||
// offset to pixel center
|
||||
float3 P = ReconstructPosition( float2( ssP ) + _float2( 0.5 ), depth );
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
float BlueNoise( float2 n, float x )
|
||||
{
|
||||
float noise = t_BlueNoise.Sample( s_LinearWrap, n.xy * rpJitterTexOffset.xy ).r;
|
||||
|
||||
noise = frac( noise + c_goldenRatioConjugate * rpJitterTexOffset.z * x );
|
||||
|
||||
noise = RemapNoiseTriErp( noise );
|
||||
noise = noise * 2.0 - 0.5;
|
||||
|
||||
return noise;
|
||||
}
|
||||
|
||||
// Total number of direct samples to take at each pixel
|
||||
#define NUM_SAMPLES 11
|
||||
|
||||
// This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent
|
||||
// taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9
|
||||
#define NUM_SPIRAL_TURNS 7
|
||||
|
||||
// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
|
||||
// miplevel to maintain reasonable spatial locality in the cache
|
||||
// If this number is too small (< 3), too many taps will land in the same pixel, and we'll get bad variance that manifests as flashing.
|
||||
// If it is too high (> 5), we'll get bad performance because we're not using the MIP levels effectively
|
||||
#define LOG_MAX_OFFSET (3)
|
||||
|
||||
// This must be less than or equal to the MAX_MIP_LEVEL defined in SAmbientOcclusion.cpp
|
||||
#define MAX_MIP_LEVEL (5)
|
||||
#define MIN_MIP_LEVEL 0
|
||||
|
||||
#define USE_MIPMAPS 1
|
||||
|
||||
static const float radius = 1.0 * METERS_TO_DOOM;
|
||||
static const float radius2 = radius * radius;
|
||||
static const float invRadius2 = 1.0 / radius2;
|
||||
|
||||
/** Bias to avoid AO in smooth corners, e.g., 0.01m */
|
||||
static const float bias = 0.01 * METERS_TO_DOOM;
|
||||
|
||||
/** intensity / radius^6 */
|
||||
static const float intensity = 0.6;
|
||||
static const float intensityDivR6 = intensity / ( radius* radius* radius* radius* radius* radius );
|
||||
|
||||
/** The height in pixels of a 1m object if viewed from 1m away.
|
||||
You can compute it from your projection matrix. The actual value is just
|
||||
a scale factor on radius; you can simply hardcode this to a constant (~500)
|
||||
and make your radius value unitless (...but resolution dependent.) */
|
||||
static const float projScale = 500.0;
|
||||
|
||||
float fallOffFunction( float vv, float vn, float epsilon )
|
||||
{
|
||||
// A: From the HPG12 paper
|
||||
// Note large epsilon to avoid overdarkening within cracks
|
||||
// Assumes the desired result is intensity/radius^6 in main()
|
||||
// return float(vv < radius2) * max((vn - bias) / (epsilon + vv), 0.0) * radius2 * 0.6;
|
||||
|
||||
// B: Smoother transition to zero (lowers contrast, smoothing out corners). [Recommended]
|
||||
//
|
||||
// Epsilon inside the sqrt for rsqrt operation
|
||||
float f = max( 1.0 - vv * invRadius2, 0.0 );
|
||||
return f * max( ( vn - bias ) * rsqrt( epsilon + vv ), 0.0 );
|
||||
}
|
||||
|
||||
float aoValueFromPositionsAndNormal( float3 C, float3 n_C, float3 Q )
|
||||
{
|
||||
float3 v = Q - C;
|
||||
//v = normalize( v );
|
||||
float vv = dot( v, v );
|
||||
float vn = dot( v, n_C );
|
||||
const float epsilon = 0.001;
|
||||
|
||||
// Without the angular adjustment term, surfaces seen head on have less AO
|
||||
return fallOffFunction( vv, vn, epsilon ) * lerp( 1.0, max( 0.0, 1.5 * n_C.z ), 0.35 );
|
||||
}
|
||||
|
||||
void computeMipInfo( float ssR, int2 ssP, out int mipLevel, out int2 mipP )
|
||||
{
|
||||
// Derivation:
|
||||
// mipLevel = floor(log(ssR / MAX_OFFSET));
|
||||
#ifdef GL_EXT_gpu_shader5
|
||||
mipLevel = clamp( findMSB( int( ssR ) ) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL );
|
||||
#else
|
||||
mipLevel = clamp( int( floor( log2( ssR ) ) ) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL );
|
||||
#endif
|
||||
|
||||
// We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map.
|
||||
// Manually clamp to the texture size because texelFetch bypasses the texture unit
|
||||
|
||||
// used in newer radiosity
|
||||
//mipP = ssP >> mipLevel;
|
||||
|
||||
mipP = clamp( ssP >> mipLevel, _int2( 0 ), textureSize( t_Depth, mipLevel ) - _int2( 1 ) );
|
||||
}
|
||||
|
||||
float3 getOffsetPosition( int2 issC, float2 unitOffset, float ssR, float invCszBufferScale )
|
||||
{
|
||||
int2 ssP = int2( ssR * unitOffset ) + issC;
|
||||
|
||||
float3 P;
|
||||
|
||||
int mipLevel;
|
||||
int2 mipP;
|
||||
computeMipInfo( ssR, ssP, mipLevel, mipP );
|
||||
|
||||
#if USE_MIPMAPS
|
||||
// RB: this is the key for fast ambient occlusion - use a hierarchical depth buffer
|
||||
// for more information see McGuire12SAO.pdf - Scalable Ambient Obscurance
|
||||
// http://graphics.cs.williams.edu/papers/SAOHPG12/
|
||||
P.z = t_Depth.Load( int3( mipP, mipLevel ) ).r;
|
||||
#else
|
||||
P.z = t_Depth.Load( int3( mipP, 0 ) ).r;
|
||||
#endif
|
||||
|
||||
// Offset to pixel center
|
||||
P = ReconstructPosition( float2( ssP ) + _float2( 0.5 ), P.z );
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
float2 tapLocation( int sampleNumber, float spinAngle, out float ssR )
|
||||
{
|
||||
// Radius relative to ssR
|
||||
float alpha = ( float( sampleNumber ) + 0.5 ) * ( 1.0 / float( NUM_SAMPLES ) );
|
||||
float angle = alpha * ( float( NUM_SPIRAL_TURNS ) * 6.28 ) + spinAngle;
|
||||
|
||||
ssR = alpha;
|
||||
|
||||
return float2( cos( angle ), sin( angle ) );
|
||||
}
|
||||
|
||||
float sampleAO( int2 issC, float3 C, float3 n_C, float ssDiskRadius, int tapIndex, float randomPatternRotationAngle, float invCszBufferScale )
|
||||
{
|
||||
// Offset on the unit disk, spun for this pixel
|
||||
float ssR;
|
||||
float2 unitOffset = tapLocation( tapIndex, randomPatternRotationAngle, ssR );
|
||||
|
||||
// Ensure that the taps are at least 1 pixel away
|
||||
ssR = max( 0.75, ssR * ssDiskRadius );
|
||||
|
||||
// The occluding point in camera space
|
||||
float3 Q = getOffsetPosition( issC, unitOffset, ssR, invCszBufferScale );
|
||||
|
||||
return aoValueFromPositionsAndNormal( C, n_C, Q );
|
||||
}
|
||||
|
||||
float3 ditherRGB( float2 fragPos, float3 quantDeviation )
|
||||
{
|
||||
float2 uvDither = fragPos / ( RESOLUTION_DIVISOR / rpJitterTexScale.x );
|
||||
float dither = DitherArray8x8( uvDither ) - 0.5;
|
||||
|
||||
return float3( dither, dither, dither ) * quantDeviation * rpJitterTexScale.y;
|
||||
}
|
||||
|
||||
void main( PS_IN fragment, out PS_OUT result )
|
||||
{
|
||||
|
@ -155,10 +349,18 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
RGB( 255, 255, 128 ), // pastel yellow
|
||||
RGB( 255, 255, 255 ), // bright white
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
RGB( 16, 16, 16 ), // black
|
||||
RGB( 0, 28, 28 ), // dark cyan
|
||||
RGB( 112, 164, 178 ) * 1.3, // cyan
|
||||
|
||||
#else
|
||||
// https://lospec.com/palette-list/2bit-demichrome
|
||||
RGB( 33, 30, 32 ),
|
||||
RGB( 85, 85, 104 ),
|
||||
RGB( 160, 160, 139 ),
|
||||
RGB( 233, 239, 236 ),
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -266,8 +468,74 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
RGB( 120, 120, 120 ),
|
||||
};
|
||||
|
||||
#elif 1
|
||||
|
||||
// NES Advanced
|
||||
// https://lospec.com/palette-list/nes-advanced
|
||||
|
||||
const float3 palette[NUM_COLORS] = // 55
|
||||
{
|
||||
RGB( 0, 0, 0 ),
|
||||
RGB( 38, 35, 47 ),
|
||||
RGB( 49, 64, 71 ),
|
||||
RGB( 89, 109, 98 ),
|
||||
RGB( 146, 156, 116 ),
|
||||
RGB( 200, 197, 163 ),
|
||||
RGB( 252, 252, 252 ),
|
||||
RGB( 27, 55, 127 ),
|
||||
RGB( 20, 122, 191 ),
|
||||
RGB( 64, 175, 221 ),
|
||||
RGB( 178, 219, 244 ),
|
||||
RGB( 24, 22, 103 ),
|
||||
RGB( 59, 44, 150 ),
|
||||
RGB( 112, 106, 225 ),
|
||||
RGB( 143, 149, 238 ),
|
||||
RGB( 68, 10, 65 ),
|
||||
RGB( 129, 37, 147 ),
|
||||
RGB( 204, 75, 185 ),
|
||||
RGB( 236, 153, 219 ),
|
||||
RGB( 63, 0, 17 ),
|
||||
RGB( 179, 28, 53 ),
|
||||
RGB( 239, 32, 100 ),
|
||||
RGB( 242, 98, 130 ),
|
||||
RGB( 150, 8, 17 ),
|
||||
RGB( 232, 24, 19 ),
|
||||
RGB( 167, 93, 105 ),
|
||||
RGB( 236, 158, 164 ),
|
||||
RGB( 86, 13, 4 ),
|
||||
RGB( 196, 54, 17 ),
|
||||
RGB( 226, 106, 18 ),
|
||||
RGB( 240, 175, 102 ),
|
||||
RGB( 42, 26, 20 ),
|
||||
RGB( 93, 52, 42 ),
|
||||
RGB( 166, 110, 70 ),
|
||||
RGB( 223, 156, 110 ),
|
||||
RGB( 142, 78, 17 ),
|
||||
RGB( 216, 149, 17 ),
|
||||
RGB( 234, 209, 30 ),
|
||||
RGB( 245, 235, 107 ),
|
||||
RGB( 47, 84, 28 ),
|
||||
RGB( 90, 131, 27 ),
|
||||
RGB( 162, 187, 30 ),
|
||||
RGB( 198, 223, 107 ),
|
||||
RGB( 15, 69, 15 ),
|
||||
RGB( 0, 139, 18 ),
|
||||
RGB( 11, 203, 18 ),
|
||||
RGB( 62, 243, 63 ),
|
||||
RGB( 17, 81, 83 ),
|
||||
RGB( 12, 133, 99 ),
|
||||
RGB( 4, 191, 121 ),
|
||||
RGB( 106, 230, 170 ),
|
||||
RGB( 38, 39, 38 ),
|
||||
RGB( 81, 79, 76 ),
|
||||
RGB( 136, 126, 131 ),
|
||||
RGB( 179, 170, 192 ),
|
||||
};
|
||||
|
||||
#elif 0
|
||||
|
||||
// Atari STE
|
||||
// https://lospec.com/palette-list/astron-ste32
|
||||
const float3 palette[NUM_COLORS] = // 32
|
||||
{
|
||||
RGB( 0, 0, 0 ),
|
||||
|
@ -306,16 +574,31 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
|
||||
#elif 0
|
||||
|
||||
// Gameboy
|
||||
const float3 palette[NUM_COLORS] = // 4
|
||||
// Sega Genesis Evangelion
|
||||
// https://lospec.com/palette-list/sega-genesis-evangelion
|
||||
|
||||
const float3 palette[NUM_COLORS] = // 17
|
||||
{
|
||||
RGB( 27, 42, 9 ),
|
||||
RGB( 14, 69, 11 ),
|
||||
RGB( 73, 107, 34 ),
|
||||
RGB( 154, 158, 63 ),
|
||||
RGB( 207, 201, 179 ),
|
||||
RGB( 163, 180, 158 ),
|
||||
RGB( 100, 166, 174 ),
|
||||
RGB( 101, 112, 141 ),
|
||||
RGB( 52, 54, 36 ),
|
||||
RGB( 37, 34, 70 ),
|
||||
RGB( 39, 28, 21 ),
|
||||
RGB( 20, 14, 11 ),
|
||||
RGB( 0, 0, 0 ),
|
||||
RGB( 202, 168, 87 ),
|
||||
RGB( 190, 136, 51 ),
|
||||
RGB( 171, 85, 92 ),
|
||||
RGB( 186, 47, 74 ),
|
||||
RGB( 131, 25, 97 ),
|
||||
RGB( 102, 52, 143 ),
|
||||
RGB( 203, 216, 246 ),
|
||||
RGB( 140, 197, 79 ),
|
||||
};
|
||||
|
||||
#else
|
||||
#elif 0
|
||||
|
||||
// https://lospec.com/palette-list/existential-demo
|
||||
const float3 palette[NUM_COLORS] = // 8
|
||||
|
@ -330,6 +613,28 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
RGB( 46, 43, 18 ),
|
||||
};
|
||||
|
||||
#elif 0
|
||||
|
||||
// Gameboy
|
||||
const float3 palette[NUM_COLORS] = // 4
|
||||
{
|
||||
RGB( 27, 42, 9 ),
|
||||
RGB( 14, 69, 11 ),
|
||||
RGB( 73, 107, 34 ),
|
||||
RGB( 154, 158, 63 ),
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// https://lospec.com/palette-list/2bit-demichrome
|
||||
const float3 palette[NUM_COLORS] = // 4
|
||||
{
|
||||
RGB( 33, 30, 32 ),
|
||||
RGB( 85, 85, 104 ),
|
||||
RGB( 160, 160, 139 ),
|
||||
RGB( 233, 239, 236 ),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
float2 uv = ( fragment.texcoord0 );
|
||||
|
@ -339,7 +644,7 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
float3 quantDeviation = Deviation( palette );
|
||||
|
||||
// get pixellated base color
|
||||
float3 color = t_BaseColor.Sample( samp0, uvPixelated * rpWindowCoord.xy ).rgb;
|
||||
float3 color = t_BaseColor.Sample( s_LinearClamp, uvPixelated * rpWindowCoord.xy ).rgb;
|
||||
|
||||
float2 uvDither = uvPixelated;
|
||||
//if( rpJitterTexScale.x > 1.0 )
|
||||
|
@ -380,6 +685,12 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
{
|
||||
color = _float3( uv.x );
|
||||
color = floor( color * NUM_COLORS ) * ( 1.0 / ( NUM_COLORS - 1.0 ) );
|
||||
|
||||
color.rgb += float3( dither, dither, dither ) * quantDeviation * rpJitterTexScale.y;
|
||||
color = LinearSearch( color, palette );
|
||||
|
||||
result.color = float4( color, 1.0 );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -389,5 +700,114 @@ void main( PS_IN fragment, out PS_OUT result )
|
|||
// find closest color match from CPC color palette
|
||||
color = LinearSearch( color.rgb, palette );
|
||||
|
||||
#if 0
|
||||
// similar to Obra Dinn
|
||||
|
||||
// triplanar mapping based on reconstructed depth buffer
|
||||
|
||||
int2 ssP = int2( fragment.position.xy );
|
||||
float3 C = GetPosition( ssP );
|
||||
float3 n_C = t_Normals.Sample( s_LinearClamp, uv ).rgb;
|
||||
//float3 n_C = normalize( ( 2.0 * t_Normals.Sample( s_LinearClamp, uv ).rgb ) - 1.0 );
|
||||
|
||||
//result.color = float4( n_C * 0.5 + 0.5, 1.0 );
|
||||
//return;
|
||||
|
||||
#if 0
|
||||
// SSAO to test the ReconstructPosition function
|
||||
float vis = 1.0;
|
||||
|
||||
//float randomPatternRotationAngle = BlueNoise( float2( ssP.xy ), 10.0 ) * 10.0;
|
||||
float randomPatternRotationAngle = InterleavedGradientNoise( ssP.xy ) * 10.0;
|
||||
|
||||
float ssDiskRadius = -projScale * radius / C.z;
|
||||
|
||||
float sum = 0.0;
|
||||
for( int i = 0; i < NUM_SAMPLES; ++i )
|
||||
{
|
||||
sum += sampleAO( ssP, C, n_C, ssDiskRadius, i, randomPatternRotationAngle, 1.0 );
|
||||
}
|
||||
|
||||
float A = pow( max( 0.0, 1.0 - sqrt( sum * ( 3.0 / float( NUM_SAMPLES ) ) ) ), intensity );
|
||||
|
||||
const float minRadius = 3.0;
|
||||
vis = lerp( 1.0, A, saturate( ssDiskRadius - minRadius ) );
|
||||
result.color = float4( _float3( vis ), 1.0 );
|
||||
return;
|
||||
#endif
|
||||
|
||||
// triplanar UVs
|
||||
float3 worldPos = C;
|
||||
|
||||
float2 uvX = worldPos.zy; // x facing plane
|
||||
float2 uvY = worldPos.xz; // y facing plane
|
||||
float2 uvZ = worldPos.xy; // z facing plane
|
||||
|
||||
float2 suvX = round( float2( uvX.x, uvX.y ) );
|
||||
float2 suvY = round( float2( uvY.x, uvY.y ) );
|
||||
float2 suvZ = round( float2( uvZ.x, uvZ.y ) );
|
||||
|
||||
// offset UVs to prevent obvious mirroring
|
||||
//uvY += 0.33;
|
||||
//uvZ += 0.67;
|
||||
|
||||
float3 worldNormal = n_C;
|
||||
|
||||
float3 triblend = saturate( pow( worldNormal, 4.0 ) );
|
||||
triblend /= max( dot( triblend, float3( 1, 1, 1 ) ), 0.0001 );
|
||||
|
||||
float3 axisSign = sign( n_C );
|
||||
|
||||
//uvX.x *= axisSign.x;
|
||||
//uvY.x *= axisSign.y;
|
||||
//uvZ.x *= -axisSign.z;
|
||||
|
||||
//result.color = float4( suv.xy, 0.0, 1.0 );
|
||||
//return;
|
||||
|
||||
// FIXME get pixellated base color
|
||||
//color = t_BaseColor.Sample( s_LinearClamp, uvPixelated * rpWindowCoord.xy ).rgb;
|
||||
color = t_BaseColor.Sample( s_LinearClamp, uv ).rgb;
|
||||
|
||||
float3 colX = ditherRGB( uvX, quantDeviation );
|
||||
float3 colY = ditherRGB( uvY, quantDeviation );
|
||||
float3 colZ = ditherRGB( uvZ, quantDeviation );
|
||||
|
||||
float3 dither3D = colX * triblend.x + colY * triblend.y + colZ * triblend.z;
|
||||
color.rgb += dither3D;
|
||||
|
||||
// find closest color match from CPC color palette
|
||||
color = LinearSearch( color.rgb, palette );
|
||||
|
||||
#if 0
|
||||
colX = _float3( DitherArray8x8( suvX ) - 0.5 );
|
||||
colY = _float3( DitherArray8x8( suvY ) - 0.5 );
|
||||
colZ = _float3( DitherArray8x8( suvZ ) - 0.5 );
|
||||
|
||||
dither3D = colX * triblend.x + colY * triblend.y + colZ * triblend.z;
|
||||
color.rgb = dither3D;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
colX = float3( uvZ * 0.5 + 0.5, 0.0 );
|
||||
colY = _float3( 0 );
|
||||
colZ = _float3( 0 );
|
||||
|
||||
dither3D = colX * triblend.x + colY * triblend.y + colZ * triblend.z;
|
||||
color.rgb = dither3D;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
color = _float3( uvZ.x * 0.5 + 0.5 );
|
||||
color = dither3D;
|
||||
color = floor( color * NUM_COLORS ) * ( 1.0 / ( NUM_COLORS - 1.0 ) );
|
||||
color.rgb += dither3D;
|
||||
//color.rgb += float3( dither, dither, dither ) * quantDeviation * rpJitterTexScale.y;
|
||||
color = LinearSearch( color, palette );
|
||||
#endif
|
||||
|
||||
#endif // cubic mapping
|
||||
|
||||
//color.rgb = float3( suv.xy * 0.5 + 0.5, 1.0 );
|
||||
result.color = float4( color, 1.0 );
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ struct VS_IN
|
|||
struct VS_OUT {
|
||||
float4 position : SV_Position;
|
||||
float2 texcoord0 : TEXCOORD0_centroid;
|
||||
float3 texcoord1 : TEXCOORD1_centroid;
|
||||
};
|
||||
// *INDENT-ON*
|
||||
|
||||
|
|
|
@ -519,6 +519,11 @@ static float3 psxVertexJitter( float4 spos )
|
|||
return spos.xyz;
|
||||
}
|
||||
|
||||
static float2 psxAffineTexMapping( float2 uv, float4 spos )
|
||||
{
|
||||
return uv;
|
||||
}
|
||||
|
||||
#define BRANCH
|
||||
#define IFANY
|
||||
|
||||
|
|
Loading…
Reference in a new issue