rj-action-library/Runtime/Shading/Library/Depth.gdshaderinc

164 lines
4.1 KiB
Plaintext
Raw Normal View History

2025-04-19 07:57:45 +00:00
#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc"
float getDepth( sampler2D _depthTexture, vec2 screenUV )
{
return textureLod( _depthTexture, screenUV, 0.0 ).r;
}
vec3 getDepthViewPositiontAtScreen( sampler2D _depthTexture, vec2 screenUV, mat4 _INV_PROJECTION_MATRIX )
{
float depthValue = getDepth( _depthTexture, screenUV );
return screenToView( screenUV, depthValue, _INV_PROJECTION_MATRIX ).xyz;
}
bool isVisibleAt( sampler2D _depthTexture, vec3 viewPosition, mat4 _PROJECTION_MATRIX, mat4 _INV_PROJECTION_MATRIX )
{
vec2 screenPosition = viewToScreen( viewPosition, _PROJECTION_MATRIX );
vec3 depthViewPosition = getDepthViewPositiontAtScreen( _depthTexture, screenPosition, _INV_PROJECTION_MATRIX );
float visible = viewPosition.z - depthViewPosition.z;
return visible > 0.0;
}
bool isInFrontOf( sampler2D _depthTexture, vec3 viewPosition, vec2 screenPosition, mat4 _INV_PROJECTION_MATRIX )
{
vec3 depthViewPosition = getDepthViewPositiontAtScreen( _depthTexture, screenPosition, _INV_PROJECTION_MATRIX );
float visible = viewPosition.z - depthViewPosition.z;
return visible > 0.0;
}
bool isInFrontOfDepth( sampler2D _depthTexture, float testDepth, vec2 screenPosition )
{
float screenDepth = getDepth( _depthTexture, screenPosition );
float visible = testDepth - screenDepth;
return visible > 0.0;
}
float getQuickOcclusionAt( sampler2D _depthTexture, vec3 viewPosition, vec2 uvPixelSize, int maxSteps, float stride,
mat4 _PROJECTION_MATRIX, mat4 _INV_PROJECTION_MATRIX )
{
vec4 clipPosition = viewToClip( viewPosition, _PROJECTION_MATRIX );
vec2 screenPosition = clipToScreen( clipPosition );
float depth = clipPosition.z;
bool isOccludedAtCenter = ! isInFrontOfDepth( _depthTexture, depth, screenPosition );
if ( isOccludedAtCenter )
{
return 0.0;
}
float offsetPerLevel = 1.0 / ( float( maxSteps ) + 1.0 );
float h2 = pow( 2.0, 0.5 ) / 2.0;
vec2[] offsets =
{
// vec2( -h2, -h2 ),
vec2( 0.0, -1.0 ),
// vec2( h2, -h2 ),
vec2( -1.0, 0.0 ),
vec2( 1.0, 0.0 ),
// vec2( -h2, h2 ),
vec2( 0.0, 1.0 )
// vec2( h2, h2 )
};
int angles = 4;
for ( int i = 0; i < maxSteps; i++ )
{
float occluded = 0.0;
vec2 rayScale = ( 1.0 + float( i ) ) * uvPixelSize * stride;
for ( int j = 0; j < angles; j++ )
{
vec2 rayOffset = offsets[ j ] * rayScale;
vec2 uvTestPosition = screenPosition + rayOffset;
bool stepVisible = isInFrontOfDepth( _depthTexture, depth, uvTestPosition );
occluded += stepVisible ? 0.0 : 1.0;
}
if ( occluded > 0.0 )
{
float occludedSteps = occluded / float( angles );
float levelOffset = ( float( i ) + 2.0 ) * offsetPerLevel;
return levelOffset - occludedSteps * offsetPerLevel;
}
}
return 1.0;
}
float getOcclusionAt( sampler2D _depthTexture, vec3 viewPosition, vec2 uvPixelSize, int maxSteps, float stride,
mat4 _PROJECTION_MATRIX, mat4 _INV_PROJECTION_MATRIX )
{
vec4 clipPosition = viewToClip( viewPosition, _PROJECTION_MATRIX );
vec2 screenPosition = clipToScreen( clipPosition );
float depth = clipPosition.z;
float maxOcclusion = 2.0 + float( maxSteps ) * 8.0;
float occlusion = 0.0;
bool centerVisible = isInFrontOfDepth( _depthTexture, depth, screenPosition );
if ( centerVisible )
{
occlusion += 2.0;
}
float h2 = pow( 2.0, 0.5 ) / 2.0;
vec2[] offsets =
{
vec2( -h2, -h2 ),
vec2( 0.0, -1.0 ),
vec2( h2, -h2 ),
vec2( -1.0, 0.0 ),
vec2( 1.0, 0.0 ),
vec2( -h2, h2 ),
vec2( 0.0, 1.0 ),
vec2( h2, h2 )
};
for ( int i = 0; i < maxSteps; i++ )
{
vec2 rayScale = ( 1.0 + float( i ) ) * uvPixelSize * stride;
for ( int j = 0; j < 8; j++ )
{
vec2 rayOffset = offsets[ j ] * rayScale;
vec2 uvTestPosition = screenPosition + rayOffset;
bool stepVisible = isInFrontOfDepth( _depthTexture, depth, uvTestPosition );
if ( stepVisible )
{
occlusion += 1.0;
}
}
}
return occlusion / maxOcclusion;
}