shader_type particles; #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Transform.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Math.gdshaderinc" #include "res://addons/rokojori_action_library/Runtime/Shading/Library/Textures.gdshaderinc" uniform vec3 cameraPosition; uniform float yaw; uniform float cellSize = 1.0; uniform int width = 10; uniform int height = 10; uniform sampler2D positionVariance; uniform vec3 maxPositionOffset = vec3(0,0,0); uniform vec2 positionUVScale = vec2( 1.0, 1.0 ); uniform vec2 positionUVOffset = vec2( 1.0, 1.0 ); uniform float heightOffset = 0; uniform sampler2D rotationVariance; uniform vec3 minRotation = vec3( 0, 0, 0 ); uniform vec3 maxRotation = vec3( 0, 1, 0 ); uniform vec2 rotationUVScale = vec2( 1.0, 1.0 ); uniform vec2 rotationUVOffset = vec2( 1.0, 1.0 ); uniform sampler2D scaleVariance; uniform vec3 minScale = vec3( 1, 1, 1 ); uniform vec3 maxScale = vec3( 1, 1, 1 ); uniform vec2 scaleUVScale = vec2( 1.0, 1.0 ); uniform vec2 scaleUVOffset = vec2( 1.0, 1.0 ); uniform float occupancyAmount = 0; uniform float occupancyPower = 0; uniform float occupancyTreshold = 0.5; uniform float occupancyHideOffset = -3; uniform float occupancyHideScale = 0.1; uniform sampler2D occupancyVariance; uniform vec2 occupancyUVScale = vec2( 1.0, 1.0 ); uniform vec2 occupancyUVOffset = vec2( 1.0, 1.0 ); uniform float hideStart = 40; uniform float hideMax = 60; uniform float hideOffset = -0.6; uniform vec2 mapSize = vec2(1024,1024); uniform vec2 mapCenter = vec2(0,0); vec2 indexToPosition( int index ) { int x = index % width; int y = index / height; return vec2( float(x), float(y) ); } void process() { vec2 position = indexToPosition( int(INDEX) ); float rotation = round( 4.0 * yaw / 360.0 ) * PI / 2.0; vec3 snappedCameraPosition = vec3( floor( cameraPosition.x / cellSize ) * cellSize, 0, floor( cameraPosition.z / cellSize ) * cellSize ); vec2 origin = vec2( float(width)/2.0, float(height)/2.0 ); position -= origin; position = rotate_v2( position, rotation ) * cellSize; vec3 position3D = vec3( position.x, heightOffset, position.y ) + snappedCameraPosition; float d = length( position3D - cameraPosition ); float yOffset = mapClamped( d, hideStart, hideMax, 0, hideOffset ); position3D.y += yOffset; vec2 mapOffset = mapCenter - mapSize/2.0; vec2 uv = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize; vec3 offset = (textureLod( positionVariance, tilingOffset( uv, positionUVScale, positionUVOffset ), 0 ).rgb - vec3(0.5,0.5,0.5) ) * maxPositionOffset; position3D += offset; vec3 rotSampled = textureLod( rotationVariance, tilingOffset( uv, rotationUVScale, rotationUVOffset ), 0 ).rgb; vec3 rot = ( rotSampled * ( maxRotation - minRotation ) + minRotation ) * PI * 2.0; // rot.y = round( 4.0 * rot.y / PI * 2.0 ) / 4.0 * PI * 2.0; vec3 sca = textureLod( scaleVariance, tilingOffset( uv, scaleUVScale, scaleUVOffset ), 0 ).rgb; sca = sca * ( maxScale - minScale ) + minScale; vec2 uv2 = ( vec2( position3D.x, position3D.z ) - mapOffset ) / mapSize; float occ = textureLod( occupancyVariance, tilingOffset( uv2, occupancyUVScale, occupancyUVOffset ), 0 ).r; occ = clamp( ( occ - occupancyTreshold ) * occupancyPower + occupancyTreshold, 0.0, 1.0 ); sca *= mix( 1.0, occupancyHideScale , ( 1.0 - occ ) * occupancyAmount ); position3D.y += ( 1.0 - occ ) * occupancyAmount * occupancyHideOffset; TRANSFORM = TRS( position3D, rot, vec3( sca.x , sca.y, sca.z ) ); }