164 lines
4.1 KiB
Plaintext
164 lines
4.1 KiB
Plaintext
#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;
|
|
} |