OpenGl/TF: Help with results i can't explain and centering geometry

    Misc

    luvulongtime's icon
    luvulongtime's icon
    luvulongtime
    Mar 28 2023 | 7:03 pm
    Hello,
    Still wet behind the ears in OpenGL land. As a first exercise i've decided to convert a patch from cpu to gpu but i'm running into an issue i can't explain and need some help with.
    I'm not using the velocity-buffer here so i thought it was a good idea to use the x-component to store the lifetime of a particle (0.-1.) and .yz-components as a spawnlocation.
    The issue here lies with the if-statement, there are some things going on i can't explain. After enabling jit.gl.tf for example i immediately see a steady stream of particles spawn from 0.5 0.5. Why is that? Even if i bang the jit.matrix instead of the jit.noise i still get particles spawn from that location from the start? I don't expect to see any particles come from that location for the first 10000 frames if i'm correct? I've added some comments in the jxs as well.
    How do you center geometry and still keep everything on the math-side between 0.-1.? On the cpu i would just keep all calculations between 0. and 1. and have a jit.gen on the end of the chain where i would do [(in1*2)-1] to center everything around 0. I fixed that with the camera in this patch but is there a good solution for this? I guess the desire for this comes from the convenience of using mod() to wrap the particles around so if anyone has a good aproach to that i'd love to hear it.
    Thanks a bunch! Save the shader as MeshTff.jxs or adjust the jit.gl.shader to your chosen filename
    Max Patcher
    In Max, select New From Clipboard.
    Show Text
    <jittershader name="TFFlowfield">
    	<description>Basic Transform Feedback Locomotion</description>
    	<param name="position" type="vec3" state="POSITION" />
    	<param name="velocity" type="vec3" state="NORMAL" />
    	<param name="speed" type="float" default="0.005" />
    	<param name="theta" type="float" default="0.0" />
    	
    	<param name="randomTex" type="int" default="0" />
    	
    	<language name="glsl" version="1.5">
    		<bind param="position" program="vp" />
    		<bind param="velocity" program="vp" />
    		<bind param="speed" program="vp" />
    		<bind param="theta" program="vp" />
    		
    		<bind param="randomTex" program="vp" />
    		
    		<program name="vp" type="vertex">
    <![CDATA[
    #version 330 core
    uniform float speed;
    uniform float theta;
    in vec3 position;
    in vec3 velocity;
    
    out vec3 Position1;
    out vec3 Velocity1;
    
    const float PI = 3.1415926535897932384626433832795;
    
    uniform sampler2DRect randomTex;
    
    void main() {
    	
    	vec2 texLookup = vec2(position.x * 99.0, position.y * 99.0);
    	float theta = texture(randomTex, texLookup).x;
    	
    	Position1.x = mod(1.0 + (position.x + (cos(theta * (PI * 2)) * speed)), 1.0);
    	Position1.y = mod(1.0 + (position.y + (sin(theta * (PI * 2)) * speed)), 1.0);
    	Position1.z = 0.0;
    	
    	Velocity1.x += 0.00001;
    	Velocity1.y = velocity.y;
    	Velocity1.z = velocity.z;
    	
    	if(Velocity1.x > 1.0) 
    		{
    			Position1 = vec3(0.5, 0.5, 0.0);
    
    			//Position1 = vec3(velocity.y, velocity.z, 0.0); // Why doesn't this line work but line 48 does?
    				
    			
    			//Position1.x = velocity.y; //And why doesn't this work when it does on line 38?
    			//Position1.y = velocity.z;
    			//Position1.z = 0.0;
    			
    			Velocity1.x = 0.0;
    		}
    	
    }
    
    ]]>
    		</program>
    		<program name="fp" type="fragment"  >
    		<![CDATA[
    #version 330 core
    void main() 
    {
    }
    		]]>
    		</program>
    	</language>
    </jittershader>

    • Rob Ramirez's icon
      Rob Ramirez's icon
      Rob Ramirez
      Mar 30 2023 | 2:27 pm
      couple things I noticed:
      jit.gl.buffer @type attribute determines which jit.gl.mesh buffer to enable for transform feedback, and must be one of the available types that are displayed in the attrui menu, as well as correspond to the state you are mapping it to in the JXS param tag. There is no "velocity" type, and since your mapping your velocity input to NORMAL in the JXS, this type attribute should be set to normal.
      I believe this line is not going to work, since you never set the output value before incrementing it: Velocity1.x += 0.00001;
      instead it should be something like: Velocity1.x = velocity.x + 0.00001; Let me know if that gets you farther along. Also for future help with shaders, please just attach a zip of your patch and shader
      Share
    • luvulongtime's icon
      luvulongtime's icon
      luvulongtime
      Mar 31 2023 | 10:05 am
      Hey Rob,
      Awesome! Thanks it's working! There are little things going on for which im still searching an explanation for but other than that it works fine. Sorry for the sloppyness with the "@type" btw, i should've caught basic stuff like that!
      "Velocity1.x = velocity.x + 0.00001;" Yeah, i can see how this makes sense. My assumption with "velocity1.x + 0.001" was that it would display the previous value like [history] in Gen but i take it it's just literally only output.
      (and if you don't mind i also shared the jxs and patch seperately. Speaking for myself here but i'm always a bit wary with downloading archives and imo this also makes it more accessible for people to see what the post is about and how the code relates to that instead of having to download the archive first, unzip, open max etc.)
      MeshTFF.zip
      application/x-zip-compressed 3.46 KB
      Save the shader as MeshTff.jxs
      Max Patcher
      In Max, select New From Clipboard.
      <jittershader name="TFFlowfield">
      	<description>Basic Transform Feedback Locomotion</description>
      	<param name="position" type="vec3" state="POSITION" />
      	<param name="velocity" type="vec3" state="NORMAL" />
      	<param name="speed" type="float" default="0.005" />
      	<param name="theta" type="float" default="0.0" />
      	
      	<param name="randomTex" type="int" default="0" />
      	
      	<language name="glsl" version="1.5">
      		<bind param="position" program="vp" />
      		<bind param="velocity" program="vp" />
      		<bind param="speed" program="vp" />
      		<bind param="theta" program="vp" />
      		
      		<bind param="randomTex" program="vp" />
      		
      		<program name="vp" type="vertex">
      <![CDATA[
      #version 330 core
      uniform float speed;
      uniform float theta;
      in vec3 position;
      in vec3 velocity;
      
      out vec3 Position1;
      out vec3 Velocity1;
      
      const float PI = 3.1415926535897932384626433832795;
      
      uniform sampler2DRect randomTex;
      
      void main() {
      	
      	vec2 texLookup = vec2(position.x * 99.0, position.y * 99.0);
      	float theta = texture(randomTex, texLookup).x;
      	
      	Position1.x = mod(1.0 + (position.x + (cos(theta * (PI * 2)) * speed)), 1.0);
      	Position1.y = mod(1.0 + (position.y + (sin(theta * (PI * 2)) * speed)), 1.0);
      	Position1.z = 0.0;
      	
      	Velocity1.x = velocity.x + 0.01;
      	Velocity1.y = velocity.y;
      	Velocity1.z = velocity.z;
      	
      	if(velocity.x >= 1.0) 
      		{
      			float modX = (velocity.y+1)*0.5;
      			float modY = (velocity.z+1)*0.5;
      			
      			Position1 = vec3(modX, modY, 0.0); 
      
      			
      			Velocity1.x = 0.0;
      		}
      	
      }
      
      ]]>
      		</program>
      		<program name="fp" type="fragment"  >
      		<![CDATA[
      #version 330 core
      void main() 
      {
      }
      		]]>
      		</program>
      	</language>
      </jittershader>