Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to use shaders in a system with a variable amount of inputs?  (Read 1028 times)

0 Members and 1 Guest are viewing this topic.

AllergicGorilla

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
How to use shaders in a system with a variable amount of inputs?
« on: December 20, 2017, 03:06:29 am »
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:
#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.
« Last Edit: December 20, 2017, 03:14:15 am by AllergicGorilla »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: How to use shaders in a system with a variable amount of inputs?
« Reply #1 on: December 20, 2017, 06:31:21 am »
How is this related to SFML?
Laurent Gomila - SFML developer

AllergicGorilla

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: How to use shaders in a system with a variable amount of inputs?
« Reply #2 on: December 20, 2017, 12:22:18 pm »
Now that you ask that, it is just tangentially related to SFML.I'm going to post this question on the OpenGl forums.

I guess I asked this here because I'm not sure how to adapt pure openGL code that uses other libraries (such as glew or glfw) to SFML.I know SFML provides an environment to work with openGL, but I wanted to avoid pure openGL as much as possible.

In short: most of my code uses SFML, so I asked this question here.