UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

2 lines (1 loc) 2.39 kB
export default "// For PI declaration:\n#include <common>\n\n#define delta ( 1.0 / 60.0 )\n\nuniform float gravityConstant;\nuniform float density;\n\nconst float width = resolution.x;\nconst float height = resolution.y;\n\nfloat radiusFromMass( float mass ) {\n // Calculate radius of a sphere from mass and density\n return pow( ( 3.0 / ( 4.0 * PI ) ) * mass / density, 1.0 / 3.0 );\n}\n\nvoid main() {\n\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n float idParticle = uv.y * resolution.x + uv.x;\n\n vec4 tmpPos = texture2D( texturePosition, uv );\n vec3 pos = tmpPos.xyz;\n\n vec4 tmpVel = texture2D( textureVelocity, uv );\n vec3 vel = tmpVel.xyz;\n float mass = tmpVel.w;\n\n if ( mass > 0.0 ) {\n\n float radius = radiusFromMass( mass );\n\n vec3 acceleration = vec3( 0.0 );\n\n // Gravity interaction\n for ( float y = 0.0; y < height; y++ ) {\n\n for ( float x = 0.0; x < width; x++ ) {\n\n vec2 secondParticleCoords = vec2( x + 0.5, y + 0.5 ) / resolution.xy;\n vec3 pos2 = texture2D( texturePosition, secondParticleCoords ).xyz;\n vec4 velTemp2 = texture2D( textureVelocity, secondParticleCoords );\n vec3 vel2 = velTemp2.xyz;\n float mass2 = velTemp2.w;\n\n float idParticle2 = secondParticleCoords.y * resolution.x + secondParticleCoords.x;\n\n if ( idParticle == idParticle2 ) {\n continue;\n }\n\n if ( mass2 == 0.0 ) {\n continue;\n }\n\n vec3 dPos = pos2 - pos;\n float distance = length( dPos );\n float radius2 = radiusFromMass( mass2 );\n\n if ( distance == 0.0 ) {\n continue;\n }\n\n // Checks collision\n\n if ( distance < radius + radius2 ) {\n\n if ( idParticle < idParticle2 ) {\n\n // This particle is aggregated by the other\n vel = ( vel * mass + vel2 * mass2 ) / ( mass + mass2 );\n mass += mass2;\n radius = radiusFromMass( mass );\n\n }\n else {\n\n // This particle dies\n mass = 0.0;\n radius = 0.0;\n vel = vec3( 0.0 );\n break;\n\n }\n\n }\n\n float distanceSq = distance * distance;\n\n float gravityField = gravityConstant * mass2 / distanceSq;\n\n gravityField = min( gravityField, 1000.0 );\n\n acceleration += gravityField * normalize( dPos );\n\n }\n\n if ( mass == 0.0 ) {\n break;\n }\n }\n\n // Dynamics\n vel += delta * acceleration;\n\n }\n\n gl_FragColor = vec4( vel, mass );\n\n}";