Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: How to use shaders in a system with a variable amount of inputs?

  1. #1
    Newbie Newbie
    Join Date
    Dec 2017
    Posts
    1

    Question How to use shaders in a system with a variable amount of inputs?

    So I'm making an electric field simulation in which the user can dynamically create charges through a mouse click.Currently, the electric field is just calculated on the CPU with a pretty bad algorithm on every cell within a grid.https://i.imgur.com/BFtnkou.gifv

    To illustrate the equipotential lines, I have made a shader that computes the potential according to the charge position and q(electric charge).https://i.imgur.com/hipLStv.gifv

    This is the shader code for glslViewer:
    Code glsl:
    #ifdef GL_ES
    precision mediump float;
    #endif
    uniform vec2 u_resolution;
    uniform vec2 u_mouse;
    #define PI 3.14159265
     
    void main( void ) {
    	vec2 position = ( gl_FragCoord.xy / u_resolution.y );
    	vec2 mousePos = u_mouse/u_resolution.y;
            vec2 r = position - mousePos;
    	vec2 r2 = position - vec2(0.5, 0.5);
            float potential = 0.125/length(r) - 0.125/length(r2);
    	potential = clamp(potential, -1.0, 1.0);
            float cutoff = sin(2.0*PI*10.0*potential);
            cutoff = smoothstep(1.0,0.0, 0.5*abs(cutoff)/fwidth(cutoff));
    	//Maps negative potential to blue
    	// and positive potential to red
    	gl_FragColor =  cutoff * vec4(potential, 0.0, -potential, 1.0);
    }

    Quick edit: I know I'll have to modify the shader, obviously.
    My problem is: how do I use this shader with a dynamic amount of charges? One of the GLSL paradigms is that the shader can't just have a variable amount of inputs--therefore, I can't just throw in an array of vec3 to represent q and position of every charge and hope the shader knows how to sum up the electric potential without knowing the array size a priori.

    My two cents on solving the problem:
    • Use a floating point texture FPT.
    • Have two separate shaders:
      • One is used for every charge, and takes the charge's q and position as inputs.It outputs a "voltage" created by the charge and adds that value to the FPT(superposition principle).The iteration over every charge is done in a for loop, inside the application's update() method or something like that.
      • The other is used as a final step, to implement the clamping for very big potentials(in absolute value), the cutoff to make the equipotential lines and, lastly, to map negative values to blue and positive ones to red.
    • Render the final result to a sprite and draw it.


    That all sounds great in theory, but my attempts at implementing that were all failures.Namely, I don't think I understand the openGL functions, as I'm mostly inexperienced with pure openGL.

    Note: I'm using SFML, and this post is a copy of my SFML forums one.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,929
    Quote Originally Posted by AllergicGorilla View Post
    My problem is: how do I use this shader with a dynamic amount of charges? One of the GLSL paradigms is that the shader can't just have a variable amount of inputs--therefore, I can't just throw in an array of vec3 to represent q and position of every charge and hope the shader knows how to sum up the electric potential without knowing the array size a priori.
    Use a fixed-size array sufficient for the maximum number of charges you'll be using, and pass the number of valid array elements as a separate variable. Or size the array to the actual number of charges and re-compile the shader whenever the size of the array changes.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •