diff --git a/Runtime/Math/Geometry/Pose.cs b/Runtime/Math/Geometry/Pose.cs index 40e576c..b5baf27 100644 --- a/Runtime/Math/Geometry/Pose.cs +++ b/Runtime/Math/Geometry/Pose.cs @@ -184,6 +184,7 @@ namespace Rokojori return p; } + public Vector3 Apply( Vector3 p ) { p = rotation * p; @@ -192,6 +193,12 @@ namespace Rokojori return p; } + public void Set( Node3D node ) + { + node.GlobalPosition = position; + node.SetGlobalQuaternion( rotation ); + } + public override string ToString() { return "Pose{" + RJLog.Stringify( position ) + RJLog.Stringify( rotation ) + "}"; diff --git a/Runtime/Procedural/Mesh/LODMultiMeshInstance3D.cs b/Runtime/Procedural/Mesh/LODMultiMeshInstance3D.cs index 8ae2111..df53e80 100644 --- a/Runtime/Procedural/Mesh/LODMultiMeshInstance3D.cs +++ b/Runtime/Procedural/Mesh/LODMultiMeshInstance3D.cs @@ -12,10 +12,10 @@ namespace Rokojori public partial class LODMultiMeshInstance3D:MultiMeshInstance3D { [Export] - public float cullDistance = 200; + public float cullDistance = 5000; [Export] - public float cullRange = 100; + public float cullRange = 2000; [Export] public Curve cullCurve = MathX.Curve( 0, 1 ); diff --git a/Runtime/Sensors/SensorManager.cs b/Runtime/Sensors/SensorManager.cs index 5dd4ce0..6468aaa 100644 --- a/Runtime/Sensors/SensorManager.cs +++ b/Runtime/Sensors/SensorManager.cs @@ -18,7 +18,7 @@ namespace Rokojori public SensorGroup[] sensorGroups = []; [Export] - public bool processSensors = false; + public bool processSensors = true; [Export] public Node[] autoScanForSensors = []; diff --git a/Runtime/Shading/Library/Colors.gdshaderinc b/Runtime/Shading/Library/Colors.gdshaderinc index 08c5135..b5c60be 100644 --- a/Runtime/Shading/Library/Colors.gdshaderinc +++ b/Runtime/Shading/Library/Colors.gdshaderinc @@ -36,6 +36,16 @@ vec3 HSLtoRGB( vec3 hsl ) return ( rgb - 0.5 ) * C + hsl.z; } +vec3 adjustHSL( vec3 color, vec3 hslAdjustment ) +{ + vec3 hsl = RGBtoHSL( color ); + hsl += hslAdjustment; + hsl.x = mod( hsl.x, 1.0 ); + hsl = clamp( hsl, 0, 1 ); + + return HSLtoRGB( hsl ); +} + vec3 toLinear( vec3 sRGB ) { return mix( pow( (sRGB + vec3( 0.055 )) * ( 1.0 / ( 1.0 + 0.055 )),vec3( 2.4 )),sRGB * ( 1.0 / 12.92 ),lessThan( sRGB,vec3( 0.04045 )) ); @@ -92,6 +102,13 @@ vec3 shiftHSL( vec3 hsl, vec3 offset, float blendRadius ) return hsl; } +vec3 shiftRGBwithHSL( vec3 rgb, vec3 offset, float blendRadius ) +{ + vec3 hsl = RGBtoHSL( rgb ); + hsl = shiftHSL( hsl, offset, blendRadius ); + return HSLtoRGB( hsl ); +} + vec3 RGBtoHSV( vec3 c ) { vec4 K = vec4( 0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0 ); @@ -161,3 +178,12 @@ vec4 blendMode_alpha( vec4 top, vec4 bottom ) return vec4( color, alpha ); } + +vec4 mixThreeColors( vec4 a, vec4 b, vec4 c, float t ) +{ + float wa = mapClamped( t, 0.0, 0.5, 1.0, 0.0 ); + float wb = triangle( t ); + float wc = mapClamped( t, 0.5, 1, 0.0, 1.0 ); + + return a * wa + b * wb + c * wc; +} \ No newline at end of file diff --git a/Runtime/Shading/Library/Depth.gdshaderinc b/Runtime/Shading/Library/Depth.gdshaderinc new file mode 100644 index 0000000..d88aa09 --- /dev/null +++ b/Runtime/Shading/Library/Depth.gdshaderinc @@ -0,0 +1,164 @@ +#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; +} \ No newline at end of file diff --git a/Runtime/Shading/Library/Depth.gdshaderinc.uid b/Runtime/Shading/Library/Depth.gdshaderinc.uid new file mode 100644 index 0000000..38e156d --- /dev/null +++ b/Runtime/Shading/Library/Depth.gdshaderinc.uid @@ -0,0 +1 @@ +uid://dlc8lsj6n22li diff --git a/Runtime/Shading/Library/Light.gdshaderinc b/Runtime/Shading/Library/Light.gdshaderinc index 147cb7e..efd9d3b 100644 --- a/Runtime/Shading/Library/Light.gdshaderinc +++ b/Runtime/Shading/Library/Light.gdshaderinc @@ -1,11 +1,11 @@ -float fresnel( vec3 _NORMAL, vec3 _VIEW, float amount ) +float fresnel( vec3 normal, vec3 view, float amount ) { - return pow( ( 1.0 - clamp( dot( normalize( _NORMAL ), normalize( _VIEW ) ), 0.0, 1.0 ) ), amount ); + return pow( ( 1.0 - clamp( dot( normalize( normal ), normalize( view ) ), 0.0, 1.0 ) ), amount ); } -float fresnelNormalized( vec3 _NORMAL, vec3 _VIEW, float amount ) +float fresnelNormalized( vec3 normal, vec3 view, float amount ) { - return pow( ( 1.0 - clamp( dot( _NORMAL, _VIEW ), 0.0, 1.0 ) ), amount); + return pow( ( 1.0 - clamp( dot( normal, view ), 0.0, 1.0 ) ), amount); } diff --git a/Runtime/Shading/Library/Transform.gdshaderinc b/Runtime/Shading/Library/Transform.gdshaderinc index b69d55d..3e1b06e 100644 --- a/Runtime/Shading/Library/Transform.gdshaderinc +++ b/Runtime/Shading/Library/Transform.gdshaderinc @@ -4,7 +4,7 @@ vec3 applyMatrix( vec3 v, mat4 m ) return ( m * vec4( v, 1.0 ) ).xyz; } -vec3 applyMatrixWithTranslation( vec3 v, mat4 m ) +vec3 applyMatrixWithoutTranslation( vec3 v, mat4 m ) { mat4 mw = m; mw[ 3 ][ 0 ] = 0.0; @@ -71,7 +71,7 @@ vec3 worldToViewDirection( vec3 direction, mat4 _VIEW_MATRIX ) vec3 viewToWorld( vec3 view, mat4 _INV_VIEW_MATRIX ) { - return ( _INV_VIEW_MATRIX * vec4( view, 1.0 ) ).xyz; + return applyMatrix( view, _INV_VIEW_MATRIX ); } vec3 viewToWorldDirection( vec3 view, mat4 _INV_VIEW_MATRIX ) @@ -83,7 +83,7 @@ vec3 viewToWorldDirection( vec3 view, mat4 _INV_VIEW_MATRIX ) mw[ 3 ][ 3 ] = 1.0; - return ( mw * vec4( view, 1.0 ) ).xyz; + return applyMatrix( view, mw ); } vec3 viewToLocal( vec3 view, mat4 _INV_VIEW_MATRIX, mat4 _MODEL_MATRIX ) @@ -98,6 +98,63 @@ vec3 viewToLocalDirection( vec3 view, mat4 _INV_VIEW_MATRIX, mat4 _MODEL_MATRIX return worldToLocalDirection( world, _MODEL_MATRIX ); } +vec4 viewToClip( vec3 view, mat4 _PROJECTION_MATRIX ) +{ + vec4 clip = _PROJECTION_MATRIX * vec4( view, 1.0 ); + clip /= clip.w; + return clip; +} + +vec2 clipToScreen( vec4 clip ) +{ + return ( clip.xy / clip.w ) * 0.5 + vec2( 0.5 ); +} + +vec4 screenToClip( vec2 screen, float z ) +{ + return vec4( screen * 2.0 - 1.0, z, 1.0 ); +} + +vec4 clipToView( vec4 clip, mat4 _INV_PROJECTION_MATRIX ) +{ + vec4 view = _INV_PROJECTION_MATRIX * clip; + view /= view.w; + return view; +} + +vec4 screenToView( vec2 screen, float z, mat4 _INV_PROJECTION_MATRIX ) +{ + vec4 clip = screenToClip( screen, z ); + vec4 view = clipToView( clip, _INV_PROJECTION_MATRIX ); + + return view; +} + +vec3 screenToWorld( vec2 screen, float z, mat4 _INV_PROJECTION_MATRIX, mat4 _INV_VIEW_MATRIX ) +{ + vec4 view = screenToView( screen, z, _INV_PROJECTION_MATRIX ); + + return viewToWorld( view.xyz, _INV_VIEW_MATRIX ); +} + +vec2 viewToScreen( vec3 view, mat4 _PROJECTION_MATRIX ) +{ + vec4 clip = viewToClip( view, _PROJECTION_MATRIX ); + + return clipToScreen( clip ); +} + + +vec2 worldToScreen( vec3 world, mat4 _VIEW_MATRIX, mat4 _PROJECTION_MATRIX ) +{ + vec3 view = worldToView( world, _VIEW_MATRIX ); + vec4 clip = viewToClip( view, _PROJECTION_MATRIX ); + vec2 screen = clipToScreen( clip ); + + return screen; +} + + vec3 extractScale( mat3 _MODEL_NORMAL_MATRIX ) { mat3 m = _MODEL_NORMAL_MATRIX; @@ -142,6 +199,23 @@ vec3 billboardWorldOffset( vec2 _UV, mat4 _INV_VIEW_MATRIX, mat4 _MODEL_MATRIX return worldOffset; } +vec3 billboardWorldOffsetWithSize( vec2 size, vec2 _UV, mat4 _INV_VIEW_MATRIX, mat4 _MODEL_MATRIX ) +{ + vec2 mappedUV = mix( vec2(-1,1), vec2( 1, -1 ), _UV ); + vec4 offset = vec4( mappedUV.x * size.x, mappedUV.y * size.y, 0, 0 ); + + offset = _INV_VIEW_MATRIX * offset; + mat4 mw = _MODEL_MATRIX; + mw[ 3 ][ 0 ] = 0.0; + mw[ 3 ][ 1 ] = 0.0; + mw[ 3 ][ 2 ] = 0.0; + + vec3 worldOffset = worldToLocal( offset.xyz, mw ); + // worldOffset = normalize( worldOffset ); + + return worldOffset; +} + vec2 rotate_v2( vec2 uv, float angle ) { float s = sin( angle );