# PixAnvil GPU N2 Gravity Compute Demo

Er, JavaScript or WebGL doesn't seem to be running, so basically all you're going to see is the bare code...

 // GLSL code, wrapped by PixAnvil's gFunction1D // Returns the new P positions as a Newtonian timestep. vec4 run(float index) { vec3 P=vec3(texP(index)); // fetch old position and velocity vec3 V=vec3(texV(index)); P+=dt*V; // Euler timestep return vec4(P,1.0); } // GLSL code, wrapped by PixAnvil's gFunction1D // Returns the new V velocities. vec4 run(float index) { vec3 P=vec3(texP(index)); // Compute gravity via naive N^2 sum vec3 F=vec3(0.0); // net force on us for (float i=0.0;i<16.0*16.0;i++) { float Gmm=0.1; // gravity constant * masses float soften=0.1; // avoid divide by zero vec3 R=vec3(texP(i))-P; // from us to them float Rlen=length(R); F+=R*(Gmm/(soften+Rlen*Rlen*Rlen)); } vec3 A=F/1.0; // F=mA, A=F/m vec3 V=vec3(texV(index)); V+=A*dt; return vec4(V,1.0); } // Take V step sim.fnV.set("dt",lib.dt); sim.fnV.set("texP",sim.P); sim.fnV.set("texV",sim.V); sim.fnV.run(sim.Vnext); // write to Vnext sim.Vnext.swap(sim.V); // ping-pong V and Vnext // Take P step sim.fnP.set("dt",lib.dt); sim.fnP.set("texP",sim.P); sim.fnP.set("texV",sim.V); sim.fnP.run(sim.Pnext); // write to Vnext sim.Pnext.swap(sim.P); // ping-pong P and Pnext // Load the GLSL code to update the P and V arrays sim.fnP=new gFunction1D(PixAnvil.loadTab('P')); sim.fnV=new gFunction1D(PixAnvil.loadTab('V')); // Allocate textures: var N=16; // texture is N x N pixels sim.nP=N*N; sim.P=new gVector1D(sim.nP); sim.Pnext=new gVector1D(sim.nP); sim.V=new gVector1D(sim.nP); sim.Vnext=new gVector1D(sim.nP); // Show textures onscreen sim.P.debugTo(scene,10.0,-6.0,10.0,5.0); sim.V.debugTo(scene,10.0,+6.0,10.0,5.0); // Run shaders to set initial conditions: // Initial positions are "random" var setupP=new gFunction1D( "float rand(float index) {\n"+ " float ret=fract(sin(index*123.4567)*12345.67);\n"+ " return (ret-0.5)*2.0;\n"+ "}\n"+ "vec4 run(float index) {\n"+ " return vec4(2.0*rand(index),\n"+ " 2.0*rand(index+0.3),\n"+ " 0.1+0.1*rand(index+0.6),\n"+ " 1.0); \n"+ "}"); setupP.run(sim.P); // Initial velocites are spinning var setupV=new gFunction1D( "vec4 run(float index) {\n"+ " vec3 P=vec3(texP(index));\n"+ " vec3 V=cross(P,vec3(0,0,0.8));\n"+ " return vec4(V,1.0); \n"+ "}"); setupV.set("texP",sim.P); setupV.run(sim.V); // Draw particles with position from texture // Make the particle locations as texture coordinates sim.particles=new THREE.Geometry(); for (var i=0;i