greggman / vertexshaderart

The repo for vertexshaderart.com
http://vertexshaderart.com
BSD 3-Clause "New" or "Revised" License
136 stars 16 forks source link

rendering issue? vertexCount problem? not sure what to call this #6

Open noisyneuron opened 7 years ago

noisyneuron commented 7 years ago

Just started looking at the tutorials, there's a weird issue with rendering the grid though. Copied your code exactly to be sure I wasn't doing something silly (though I might still be) - attached an image for you to see - note the bottom left corner.. the line is incomplete

screen shot 2017-08-02 at 15 19 14

Seems the vertexCount doesn't get fed correctly - either of the commented out solutions below work:

void main() {
  float down = floor(sqrt(vertexCount));
  float across = floor(vertexCount/down);

  // SOLUTION-1
  //down = floor(sqrt(200.));
  //across = floor(200./down);

  // SOLUTION-2
  //float c = 200.;
  //down = floor(sqrt(c));
  //across = floor(c/down);

  float x = mod(vertexId, across);
  float y = floor(vertexId / across);

  float u = x/(across-1.);
  float v = y/(across-1.);

  float ux = u*2.-1.;
  float vy = v*2.-1.;

  gl_Position = vec4(ux, vy, 0.,1.);

  gl_PointSize = 10.;
  gl_PointSize *= 20./across;
  gl_PointSize *= resolution.x/600.;

  v_color = vec4(1., 0., 0., 1.);

}

Hope this isn't me being silly and overlooking something - been trying to figure this out for some time now! (actually its probably better if its me and not a bug ;) )

noisyneuron commented 7 years ago

At count 144 it's even stranger (same code) :

screen shot 2017-08-02 at 15 19 37

greggman commented 7 years ago

That is strange. I don't know what would cause that. What GPU do you have? You're in which browser, what version?

The only thing I can think of is the math is getting slightly off from rounding errors but at those number that shouldn't be an issue.

Try this to see what happens

  float down = floor(sqrt(vertexCount + .1));
  float across = floor((vertexCount + .1)/(down + .1));

?

Seeing that you have 2 points on the left is really strange.

Although I think this is unrelated shouldn't this

  float u = x/(across-1.);
  float v = y/(across-1.);

be this?

  float u = x/(across-1.);
  float v = y/(down-1.);

That looks like my bad but I don't think it's related

greggman commented 7 years ago

well at the moment I'm too lazy to look into the math here but check this out

https://www.vertexshaderart.com/art/Ekz3YzPYcEQyhT2z7/revision/xYCqo3LfbNTdpYBgH

If I size the window from time to time I'll see an irregular arrangement like this

screen shot 2017-08-03 at 19 52 30

noisyneuron commented 7 years ago

aah, guessing some funky rounding/precision error or something? i'll scale up the grid and play for now :)

MacroMachines commented 7 years ago

Denormalized numbers?

MacroMachines commented 7 years ago

I believe the actual nature of your issue may be related to the specifics of the way that you have gone about things. Try taking out the floor() that you are using to make them flatten into the grid, everything ends up on an angle slant which makes me realize there is a natural shifted cadence causing song to loop around add a slightly different point

____prior reply: I thought this may be due to low/medium-precision being set by default. I have seen a ton of float rounding error come into play if you do not specify "precision highp float;" at the start of a GL ES shader. I think using this statement in non GL_ES can cause compile errors, so best to wrap it in a precompiler define to make it adaptive.

#ifdef GL_ES
precision highp float;
#endif

It's effect can be very pronounced in Fragment shaders that use Ray marching techniques, sometimes they will look like total madness in something such as GLSLsandbox.com, and I just change the top statement from mediump to highp and it looks perfect.

I haven't been using many integer based values in my GLS of work as of yet so I don't entirely know for certain what the type conversion from Int to float can do, but for certain I have found some very fascinating artifacts due to rounding errors in time driven shaders. Once the time value starts putting its definition in the higher values and dropping least significant bit resolution from the small decimal, camera movement can begin to become shaky and I even left one going long enough that a shadertoy cave became choppy and fragmented, which instantly was fixed by hitting the timer reset button.

MacroMachines commented 7 years ago

https://www.vertexshaderart.com/art/xsSZN6pMk7iANGyTE Just removing the floor statements made everything slanted, is there any detailed info on what is going on behind the scenes with the set up of the webGL scene before the shader?

img_2046

greggman commented 7 years ago

There is no reason to wrap this

#ifdef GL_ES
precision highp float;
#endif

Just

precision highp float;

is fine

The wrapping BS left over from before WebGL 1.0 shipped and people don't stop using it because they keep copying the old examples 🙄

Also, in a vertex shader, highp is the default so that's not the issue.

There's nothing special going on with the setup. This is just prepended in front of your shader code

attribute float vertexId;
uniform vec2 mouse;   // normalized mouse position -1 to 1
uniform vec2 resolution;  // resolution of canvas in pixels
uniform vec4 background;  // background color
uniform float time;  // time in seconds
uniform float vertexCount;
uniform sampler2D sound;  
uniform sampler2D floatSound;
uniform sampler2D touch;
uniform vec2 soundRes;  // resolution of sound textures 
varying vec4 v_color;
MacroMachines commented 7 years ago

My reason for mentioning the GL_ES wrapper was based around transferring shaders I had made on my ipad to my desktop, I would get errors on the precision line if I wasn't wrapping it. They were also fragment shaders, and I have just recently started working on vertex shaders again after realizing they are obviously better for some things. I had gotten caught up in the whole ShaderToy movement IQ started that "a quad and a frag shader is all you need" which I am glad I entertained, but some of my prior best work was done entirely in vertex shaders on super old hardware they ran fast as hell..

super glad you made a site with audio/vertex.. that was my old entire workflow and I realize now its worth merging the two for best of both worlds :P`

greggman commented 7 years ago

I see the GL_ES wrapper as including C/C++ in my JavaScript.

I wouldn't do this

// int main(int argc, const char* argv[]) {
//   .. 
//  ..
// }

function main() {
   ...
   ...

}

So similarly I don't put non-WebGL in my WebGL shaders. It's misleading IMO to most WebGL devs who are unlikely to ever touch OpenGL (there's several orders of magnitude more JS programmers than C/C++ programmers) so rather than clutter my code with stuff they'll never use I try to keep it as clean as possible.

It gets worse in WebGL2. The first line of the shader must be

#version 300 es

And there is no way to #if it out for desktop. Since It's going to have to be a WebGL only shader then I keep the non-WebGL stuff out.

but of course you're free to do whatever you want, just explaining my reasoning.

MacroMachines commented 7 years ago

@greggman Yes, I totally understand, and your reasoning is valid :)

My prior post was only to provide information as to why I use the precompiler ifdef, and that it has usefulness still. Though you may be correct that many people retain it due to copy/pasting or referencing older code, some of us are using it intentionally. Or perhaps when you were mentioning "the wrapping BS from before WebGL1.0 shipped ... people keep copying the old examples" you were referring specifically to the examples of your site?

I am curious if there has been any advancement in figuring out the cause for the inconsistent point placement that initiated this thread?

I had posted a link to my modification to the code removing the instances of floor(), and was wondering if there is an actual issue with some aspect of the site, or if it is a matter of that individual shader being somehow different from the tutorial?

Brilliant tutorials by the way, I learned some great new vertex-techniques. Cheers!

greggman commented 7 years ago

I don't know why. I tried making a sample in JS just to see if the error would stick out but no error there

https://jsfiddle.net/greggman/cjt1u905/

Of course JS is using doubles but it's not like the math used in that sample should fail period it seems to me. On the other hand it is doing math that ends up on the border of values. One way to fix it is to add .1 to vertexId so that it's never close to the border.

https://www.vertexshaderart.com/art/Ekz3YzPYcEQyhT2z7/revision/iXKwcqhgZCQnoJQv4

MacroMachines commented 7 years ago

attribute float vertexId; how are you passing in the vertexId?

greggman commented 7 years ago

it's just an array of increasing floats.

up to about 8million they should effectively be ints

greggman commented 7 years ago

make that 16 million

greggman commented 7 years ago

Well, here's the answer

https://stackoverflow.com/a/47422761/128511

ps: yes I know the site is down ... working on it 😓