grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

RP3 GL_LINES Problem

Sun Feb 16, 2020 7:47 pm

I have a GL_LINES that takes in a bunch of points that go from [0,0,0] to [1,0,0]. I then can call to draw that line as many times as I want passing in a few uniforms to control location on the screen (Y).

If I move the vertex inside the vertex shader with a color value from the texture going into the shader (so offsetting in the Z direction) what I am noticing is that on vertexes that are changing between frames, I am not getting the interpolation always working. It just doesn't call the frag shader (the frag shader is set to draw just vec4(1.0);

If I increase the behavior, I see like a 10x10 grid showing this strange behavior across the screen. I am using glm, so changing to either perspective or ortho, or changing the LookAt doesn't change this 10x10 grid.

I cannot for the life of me figure out what could cause this. My only guess would have been vertex caching but I cannot see a way to turn that off.

In my loop to draw each line, I call glUniform4f and glUniform4i to update followed by my glDrawArrays. Is there a problem with updating that so often?

The fact that the transforms or anything does't change this grid, makes me believe it is something GPU specific. I can also get this behavior on triangle strips that I am modifying the vertex locations

Here. the lines should all be touching, this was a straight line as described where I just modified the Z location by adding to the vertex value.
IMG_1381.JPG
IMG_1381.JPG (46.88 KiB) Viewed 1151 times
Here is a denser picture, again, each line is just from [0,0,0] to [1,0,0] where I am modifying the z value in the vertex shader (and y position). That square pattern you see, there is nothing in the math for the vertex movement that could create that. Zooming in and out, no difference, those squares stay right where they are and affect the lines that pass through those areas.

IMG_1396.JPG
IMG_1396.JPG (248.54 KiB) Viewed 1151 times
I've tried all kinds of different line widths (including 1). Blending on and off, Depth map on and off. Here all those are off. Culling is off. I clear the buffer each time.

Note this is rendered into a texture.

If anyone has ANY clue how I could resolve this, greatly appreciated.

Another interesting tidbit. This happens on the vertexes ANIMATING between frames. If I create these offsets and they are the same between frames, the rending is correct. So it's when the vertex are moving between frames that I see this problem occur.

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Sun Feb 16, 2020 7:51 pm

Ran the code with just drawing ONE line and still does the same thing.

User avatar
Paeryn
Posts: 2952
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: RP3 GL_LINES Problem

Sun Feb 16, 2020 8:21 pm

Can you provide a short (complete) program demonstrating this behaviour?
She who travels light — forgot something.

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 8739
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: RP3 GL_LINES Problem

Sun Feb 16, 2020 9:51 pm

Are you running with the legacy gles driver, or the vc4-kms-v3d mesa driver?
The former is unlikely to be fixed. The latter you have a fair chance if you can give us a simple test case.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Mon Feb 17, 2020 3:11 am

Let me build a test case, extract this code out of my larger program.

I am running and rendering direct to the frame buffer, not in x-windows, do you know how I can tell which driver I am running?

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Mon Feb 17, 2020 5:45 am

Okay, I basically took the picam_demo that is out there and stripped EVERYTHING out. What is left is a program that is generating a pattern that is changing into a texture, then that texture is fed into the next program and is used to offset vertex locations in just the Z direction.

I believe I have pulled out anything that is special in this. so as long as you have glm already, you should be good to go (obviously editing the CMakeList to fix any issues).

sample.zip
(6.98 KiB) Downloaded 39 times
I took a snapshot of the output of this running on a CRT display. In the top right, you'll see this black square pattern that emerges. If you modify lines or points down in the code, those squares ALWAYS remain exactly where they are. And why it happens at the top but not the bottom, no clue. It's not always consistent where it happens depending on the relative changes in the vertex locations.
IMG_1442.JPG
IMG_1442.JPG (144.36 KiB) Viewed 1071 times

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Mon Feb 17, 2020 6:39 am

Some additional notes:

If you change this line in the 3d vertex shader:

vec4 n = vec4(0.0,0.5*lum,0.0,0.0);

And move 'lum' as I have to the Y value (or X) to push the vertex, you still get the same dropped out pieces.

Now here is where it gets weird....

If I override the calculated value of 'lum' (so I still let there be a texture lookup) and just do some math for 'lum' to shift the vertex, like:

lum = (sin(40.*tcoord.x+9.0*time)+1.)/4. + (sin(30.*tcoord.x+9.0*time)+1.)/4.;
lum *= cos(35.*tcoord.y+5.0*time);

No missing lines....this just has me baffled. I though, maybe I am getting a bad texture value, so I put a clamp on lum, no difference. Definitely one of the weirdest scenarios I have come across!

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Mon Feb 17, 2020 7:16 am

If you replace "simplefragshader.glsl" with this texture generation code, you can see the problem even worse. This just generates mountains basically of shades of grey colors over each other (like a side scroller).

Code: Select all

varying vec2 tcoord;			// 
uniform sampler2D tex;			// texture one
uniform sampler2D tex2;			// texture two
uniform vec2 tres;			// size of texture (screen)
uniform vec4 fparams;			// 4 floats coming in 
uniform ivec4 iparams;			// 4 ints coming in
uniform float ftime;			// 0.0 to 1.0
uniform int itime;			// increases when ftime hits 1.0
//f0:foreground:
//f1:midground:
//f2:background:
	float f0 = mix(0.05, 0.95, fparams[0]);
	float f1 = mix(0.05, 0.95, fparams[1]);
	float f2 = mix(0.05, 0.95, fparams[2]);

//http://www.glslsandbox.com/e#43330.0

float time = float(itime) + ftime;
vec2 resolution = tres;		// for easier glslsandbox.com conversion

const int layers = 3;
const float speed = 0.8;

float sawTooth(float x) {
   return abs(mod(x, 2.0) - 1.0);
}

//---------------------------------------------------------------------------------------------------
void main(void) {

   vec2 position = (gl_FragCoord.xy - resolution / 2.) / resolution.x;
   position.x += mod(time,10.) * speed;
   
   float c = 0.;
   float k = 1.;
   bool brk = false;

    float h;
    float p;

// layer 1
    h = 0.;
    p = 1.;
    for (int i = 0; i < 4; i++) {
         p *= sin(position.x * f0 *0.03) + 1.5;
         h += abs(sin(p)) * (0.5*sawTooth(position.x*p) - 0.25 - position.y / sqrt(k)) / p;
    }
    c = ceil(sign(h)) * k *f0;
    if (c <= 0.) {
	      k -= 1. / float(layers);
	      position.x -= 10. +   speed / float(layers);
	      position.y -= 0.5 / float(layers);
    } else {
	brk = true;
    }


// layer 2
  if (!brk) {
      h = 0.;
      p = 1.;
      for (int i = 0; i < 4; i++) {
         p *= sin(position.x * f1 *0.09) +  1.5;
         h += abs(sin(p)) * (0.5*sawTooth(position.x*p) - 0.25 - position.y / sqrt(k)) / p;
      }
      c = ceil(sign(h)) * k *f1;
      if (c <= 0.) {
	      k -= 1. / float(layers);
	      position.x -= 50. * speed / float(layers);
	      position.y -= 0.6 / float(layers);
    } else {
	brk = true;
    }

  } //endof if brk 


// layer 3
  if (!brk) {
      h = 0.;
      p = 1.;
      for (int i = 0; i < 4; i++) {
         p *= sin(position.x * 0.1) * f2 + 1.5;
         h += abs(sin(p*.5)) * (0.5*sawTooth(position.x*p) - 0.25 - position.y / sqrt(k)) / p;
      }
      c = ceil(sign(h)) * k * f2;
      if (c <= 0.) {
	      k -= 1. / float(layers);
	      position.x -= 10. + time * speed / float(layers);
	      position.y -= 0.2 / float(layers);
    } else {
	brk = true;
    }

  } //endof if brk 


   gl_FragColor = vec2(c, 1.).xxxy;
} //endof main

6by9
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 8739
Joined: Wed Dec 04, 2013 11:27 am
Location: ZZ9 Plural Z Alpha, aka just outside Cambridge.

Re: RP3 GL_LINES Problem

Mon Feb 17, 2020 12:14 pm

grimepoch wrote:
Mon Feb 17, 2020 3:11 am
I am running and rendering direct to the frame buffer, not in x-windows, do you know how I can tell which driver I am running?
Do you have "dtoverlay=vc4-kms-v3d" or "dtoverlay=vc4-fkms-v3d" in /boot/config.txt? If so then you are using Mesa. If not then you are using the legacy GLES driver.

lsmod would also report "vc4" or "v3d".

Seeing as you're calling bcm_host_init and dispmanx, you're using the legacy driver.
Software Engineer at Raspberry Pi Trading. Views expressed are still personal views.
I'm not interested in doing contracts for bespoke functionality - please don't ask.

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Mon Feb 17, 2020 6:39 pm

Ahhh, well this is for an embedded system that is already deployed, so changing the driver/os isn't something easy for me to do. I just wanted to make sure I wasn't doing anything wrong.

I made another version of the code where after I do the first draw, I pull that whole frame buffer into memory with a glReadPixels. Then, before I draw the lines, I offset the vertex points on the c side and then draw, and no artifacts, lines are fully drawn.

Of course, this is VERY slow in comparison.

Very odd to say the least.

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Mon Feb 17, 2020 10:58 pm

Continued to experiment today. If I use ANY piece of the texture that is not 0 to offset the coordinate, this problem happens. My experiment was mixing shifting the vertex by math instead of the texture and no issues.

NO ARTIFACTS
vec4 c = texture2D(tex,tcoord);
float r = sin(6.28*v.x+time*10.)
v[3]=1.1+r

ARTIFACTS
vec4 c = texture2D(tex,tcoord);
float r = sin(6.28*v.x+time*10.) + c.r/10.
v[3]=1.1+r

So it isn't modifying the vertex position that is causing the problem. It's using the value from texture2D output. I tried to be smart, cast it to an int, modified it, cast it back, same problem. No matter what I do with that value from texture2D if it makes it's way into a math operation for the gl_Position output, it generates the artifacts shown. (Which as far as I can tell causes the fragments shader to not be called for the interpolation as the fragment shader is set to output vec4(1.0) no matter what.

I thought about using a texture to compute the offsets, but this version of the pi GLES doesn't support copying from a texture buffer to an array buffer, so that's out. (and we know pulling directly from a texture for offsets is not working which is the problem to begin with). Modifying the vertex array externally is very expensive. (as is the glReadPixels) performance drops to 1/4 to 1/8.

I think I've run out of things to try.

I guess I could try finding a newer version of the libs I am using and see if there is an update to the driver. Which library is responsible for compiling the shaders? Maybe the problem starts there?

Edit: I don't understand how the versioning works. If I download any other version of the GLES and EGL library than the 4.14.59 release, they just aren't seen / won't load.

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Tue Feb 18, 2020 2:02 am

Okay, I am pretty sure I know what the bug is, but obviously I have no access to the source on this stuff to determine why.

From what I can gather, the texture rendering is not complete yet from the previous draw function when the vertex shader is getting called for the next stage in the pipeline.

glFlush does not fix this.

glReadPixels does fix this. Even when I do NOTHING with the results I read in. I just read the texture on the C side before I call the functions that will invoke calls to the vertex shader and now the vertex are working properly.

The interesting thing is I can read just 1 pixel out (so much lower performance hit) and it works. I'll just use this for now.

Daniel Gessel
Posts: 121
Joined: Sun Dec 03, 2017 1:47 am
Location: Boston area, MA, US
Contact: Website Twitter

Re: RP3 GL_LINES Problem

Tue Feb 18, 2020 2:49 am

Can you try glFinish instead of glFlush, just as a sanity check?

grimepoch
Posts: 116
Joined: Thu May 12, 2016 1:57 am

Re: RP3 GL_LINES Problem

Tue Feb 18, 2020 5:56 am

Great suggestion! That works as well!

Daniel Gessel
Posts: 121
Joined: Sun Dec 03, 2017 1:47 am
Location: Boston area, MA, US
Contact: Website Twitter

Re: RP3 GL_LINES Problem

Tue Feb 18, 2020 10:57 am

Instead of glReadPixels, glCopyTexSubImage, of just 1 pixel to a dummy texture, might force the right synchronization on the gpu without the full synchronization with the cpu that glFinish does.

Return to “OpenGLES”