#include "res://addons/rokojori_action_library/Runtime/Shading/Library/Colors.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Depth.gdshaderinc" uniform sampler2D depthTexture:hint_depth_texture; uniform vec4 color : source_color = vec4( 0.887, 0.434, 0.233, 1.0 ); uniform float alphaScale = 1; uniform float circleAmount = 1; uniform float circleDistortion = 1; uniform float ellipseAmount = 1; uniform float ellipseDistortion = 1; uniform vec2 ellipseScale = vec2( 1, 0.5 ); uniform float add_vs_max:hint_range(0,1) = 0.5; uniform vec4 centerHSL = vec4( 0.08, 0.0, 0.18, 1.0 ); varying vec4 centerColor; uniform vec4 outsideHSL = vec4( -0.05, 1.65, 0.02, 0.0 ); varying vec4 outsideColor; uniform float sizeX:hint_range(1,100) = 10; uniform float sizeY:hint_range(1,100) = 1; uniform float scaleAll = 1; uniform float worldSize_vs_screenSize:hint_range(0,1) = 1; varying vec2 stretch; uniform bool usSpectralsNoise = false; uniform vec3 spectralsAmount = vec3( 0.1, 0.05, 0.02 ); uniform float nonSpectralAmount = 0.95; uniform vec3 spectralsSize = vec3( 1,0.8, 0.5 ); uniform vec3 spectralsSharpness = vec3( 0, 0, 0 ); uniform vec3 spectralsFrequency = vec3( 50.0, 200.0, 500.0 ); uniform vec3 spectralsSpeed = vec3( 5.0, -3.0, -2.0 ); uniform sampler2D fading; uniform sampler2D sizeXfading; uniform sampler2D sizeYfading; uniform bool useQuickOcclusionTest = false; uniform float occlusionZOffset:hint_range(-30,30) = 0; uniform int occlusionTestMaxSteps = 10; uniform float occlusionTestStepStride = 1; uniform float occlusionTest_ViewDependingScaleAmount:hint_range(0,1) = 0.5; uniform float occlusionTest_ViewDependingDistance = 100; varying float occlusionAlpha; void vertex() { vec3 viewOffset = viewToWorldDirection( vec3( 0, 0, occlusionZOffset ), INV_VIEW_MATRIX ); vec3 nodePositionView = worldToView( NODE_POSITION_WORLD + viewOffset, VIEW_MATRIX ); vec2 screenPosition = viewToScreen( nodePositionView, PROJECTION_MATRIX ); float fadeValue = textureLod( fading, screenPosition, 0.0 ).r; float sizeXFade = textureLod( sizeXfading, screenPosition, 0.0 ).r; float sizeYFade = textureLod( sizeYfading, screenPosition, 0.0 ).r; float nodeScale = length( extractScale( MODEL_MATRIX ) ); float sX = sizeX * sizeXFade; float sY = sizeY * sizeYFade; vec2 uvPixelSize = vec2( 1.0, 1.0 ) / VIEWPORT_SIZE ; vec2 scaledUVPixelSize = uvPixelSize * max( 1.0, nodePositionView.z / occlusionTest_ViewDependingDistance ); uvPixelSize = mix( uvPixelSize, scaledUVPixelSize, occlusionTest_ViewDependingScaleAmount ); float occlusionValue = useQuickOcclusionTest ? getQuickOcclusionAt( depthTexture, nodePositionView, uvPixelSize, occlusionTestMaxSteps, occlusionTestStepStride, PROJECTION_MATRIX, INV_PROJECTION_MATRIX ) : getOcclusionAt( depthTexture, nodePositionView, uvPixelSize, occlusionTestMaxSteps, occlusionTestStepStride, PROJECTION_MATRIX, INV_PROJECTION_MATRIX ); occlusionAlpha = occlusionValue * fadeValue; float camDist = length( NODE_POSITION_WORLD - CAMERA_POSITION_WORLD ); vec2 sizeScaled = vec2( sX, sY ) * scaleAll * occlusionAlpha * nodeScale; vec2 size = mix( sizeScaled, sizeScaled * camDist * 0.1, worldSize_vs_screenSize ); stretch = vec2( sX, sY ); vec3 worldOffset = billboardWorldOffsetWithSize( size, UV, INV_VIEW_MATRIX, MODEL_MATRIX ); VERTEX += worldOffset; vec3 hsl = RGBtoHSL( color.rgb ); vec3 shiftedHSL = shiftHSL( hsl, centerHSL.rgb, 60.0 ); vec3 shiftedRGB = HSLtoRGB( shiftedHSL ); centerColor = vec4( shiftRGBwithHSL( color.rgb, centerHSL.rgb, 60.0 ), centerHSL.a * color.a); outsideColor = vec4( shiftRGBwithHSL( color.rgb, outsideHSL.rgb, 60.0 ), outsideHSL.a * color.a ); } float psin( float x, float power ) { float v = sin( x ) * 0.5 + 0.5; return mix( v, v * v * v, power ); } void fragment() { vec2 circleUV = ( UV - vec2( 0.5 ) ) * stretch + vec2( 0.5 ); vec2 centerUV = UV - vec2( 0.5 ); float angle = atan( centerUV.y, centerUV.x ); vec3 sizes = vec3( 1.0 ) * length( circleUV ) / 0.701; float distanceToCircle = 1.0 - min( 1, length( circleUV - vec2( 0.5, 0.5 ) ) / 0.5 ); float noise = 1.0; if ( usSpectralsNoise ) { noise = nonSpectralAmount; float spX = max( 0, mix( psin( TIME * spectralsSpeed.x + angle * spectralsFrequency.x, spectralsSharpness.x ) * spectralsAmount.x, 0.0, -spectralsSize.x - distanceToCircle ) ); float spY = max( 0, mix( psin( TIME * spectralsSpeed.y + angle * spectralsFrequency.y, spectralsSharpness.y ) * spectralsAmount.y, 0.0, -spectralsSize.y - distanceToCircle ) ); float spZ = max( 0, mix( psin( TIME * spectralsSpeed.z + angle * spectralsFrequency.z, spectralsSharpness.z ) * spectralsAmount.z, 0.0, -spectralsSize.z - distanceToCircle ) ); float oa = occlusionAlpha * occlusionAlpha; noise += spX * oa; noise += spY * oa; noise += spZ * oa; noise = mix( noise, 1.0, 1.0 - oa ); } vec2 ellipseUV = ( UV - vec2( 0.5 ) ) / ellipseScale + vec2( 0.5 ); float distanceToEllipse = 1.0 - min( 1, length( ellipseUV - vec2( 0.5, 0.5 ) ) / 0.5 ); distanceToCircle = clamp01( distanceToCircle * noise ); distanceToEllipse = clamp01( distanceToEllipse ); distanceToCircle = pow( distanceToCircle, circleDistortion ); distanceToEllipse = pow( distanceToEllipse, ellipseDistortion ); distanceToCircle *= circleAmount; distanceToEllipse *= ellipseAmount; float addResult = min( 1, distanceToEllipse + distanceToCircle ); float maxResult = min( 1, max( distanceToEllipse, distanceToCircle ) ); float t = mix( addResult, maxResult, add_vs_max ); vec4 mixedColor = mixThreeColors( outsideColor, color, centerColor, t ); ALBEDO = mixedColor.rgb; ALPHA = mixedColor.a * occlusionAlpha * alphaScale; }