Flickering of shapes. Problem with perspective?

Dear all, the little start up where I work is building a software. For this reason i cannot share with you all the code, but i could share some little pieces.

The problem: I’m trying to visualize a city in a 3d world, but I have a bad problem with the flickering of the strokes. The effect seems to be correlated with the command

perspective(FOV, (float) width / height, znear, zfar);

In particular, if znear is 1 the effect is terrible, if znear is 200 (for example) the effect disappear or it’s a lot reduced. I imagined that this situation could be caused by an overlap of strokes and I try to display 1 triangle by two, but the problem persist. I share with you two video that show the situation.
Of course one could say: where’s the problem, you can keep znear at 200 and your problem is resolved. That not so easy, because I need to zoom a lot for looking at some detail and i cannot do that with znear at 200.

Note that I’m using peasyCam library for moving the camera

Not flickering
Flickering example

1 Like

I have received no answer, this is just for putting up again the topic

I’ve just realized that the videos were private and no one could see them. I’ve just updated it

This is probably a problem with z-fighting. The z-buffer, or depth buffer, stores a depth for each pixel in the range from znear to zfar and if you draw two triangles that overlap each other at a shallow angle, their depths from a given camera angle might fall into the same depth value bucket. Small camera changes might then change the order causing the flickering at that pixel.

If you want a lot of depth range, you may have to chunk your scene between near and far objects and draw the distant parts first with a bigger znear, clear the depth buffer, and then reset the znear and draw the closer stuff over the previous part.

1 Like

Thank you for your answer, I’ve almost got it. The problem is that I’m not that pratical with these things. In true words, how can i do it?
My code is quite simple, I have some PShapes that are generated in different manners and I simply draw them.

It looks like the flickering is between your polygons and a wireframe, right? Try scaling the wireframe to be slightly bigger, say by 1.01 of the size of each building, so that the lines are “outside” of each building instead of embedded in the walls. And otherwise make sure that you are not trying to render any polygons that lie in exactly or nearly the same plane – if you are, move the one you more wish to see to be outside of the buildings. Also make sure that your objects are near the origin where floating-point numbers have the best precision.

So, I don’t think you should have to do the depth-chunking that I mentioned above. I think it’s more likely that you are drawing polygons (or lines) that are directly on top of each other and it becomes arbitrary from frame to frame which one gets drawn first. Scale your different pieces of geometry so they don’t lie on exactly the same plane, and hopefully you won’t have to play any complicated games with the rendering.

I tried scaling the triangles of the ground, i think that this solution could work, but there’s a problem. The ground disappear. That happen (I think) because the coordinates are about 10.000.000 and probably the command PShape.scale() move away my ground even if i’m scaling 0.99.

How can i scale a triangle keeping fixed the center (so that the vertices shrink a bit)?.
I’m creating triangles like that:

void createTriangle(PVector x, PVector y, PVector z) {
      PShape triangle = createShape();
        triangle.beginShape(PConstants.TRIANGLE);
        triangle.strokeWeight(0.7f);
        triangle.stroke(200);
        triangle.fill(250);

        triangle.vertex(x.x, x.y, x.z);
        triangle.vertex(y.x, y.y, y.z);
        triangle.vertex(z.x, z.y, z.z);
        triangle.endShape();
        //triangle.scale(0.99f);

        ground.addChild(triangle);
}

What is the source of your data and what size and scale are your numbers? Why are your coordinates as large as 10 million? That is almost certainly the source of your flickering.

PVectors (and all of Processing’s graphics commands) are using 32-bit floating point numbers which only have ~24 bits of precision (the rest is the exponent) which means they can only have values up to around 16 million before you start losing precision in the 1’s place. If you have a value at 10 million and try to add 0.5 to it, your answer will snap back to 10 million. Or if it works for 0.5, it won’t for 0.05 – I haven’t test it.

If you are trying to use data for an entire planet, you’ll only be able to describe features down to a certain size. Anything finer than that will snap to grid positions. To counter this, put all your visible geometry in a local coordinate system (near zero) at a much finer scale BEFORE sticking your data into PVectors.

Here’s http://cs.brown.edu/people/sdollins/world/home.html a virtual world generator I made 20 years ago that can outline the ground polygons and it works fine without any offsets. BUT, because I’m not using a localized coordinate system for the rendering, if I move the camera out ~2 million units from the origin, the camera motion becomes very choppy and then eventually, further out, the ground starts breaking apart as the floating-point resolution gets used up by the large scale of the numbers.

I’m using real data for mapping cities. The scale is 1:1, i’m not scaling the data that i retrieve. my coordinates are big because the first digit (1 or 2) map to x or y axis, and the rest of the number is the point in the swiss coordinate system. I just tried translating everything in the zero, but it doesn’t change. For simplifying my calculations and representations, I decided to leave the real coordinates.

Anyway I checked and I was wrong, the dimension is like 2700000 at the x axis and 150000 at y axis.

I think that the problem could be that my shapes stands one on the other. When I draw the ground for example, each triangle share a side with his neighbor. Also, the cubes and the buildings has the same problem. Maybe rescaling every single shape of 0.99 may move away shapes one each other. Note that if I draw buildings without stroke the flicker disappear.

My problem now is that is I use PShape.scale() I cannot keep the center of the shape fixed

So, you’ll want to subtract (2700000, 150000) from all of your coordinates before putting them into any of Processing’s data structures.

Try this code:

  float x = 2700000.0;
  println( x + 1.1 );

The answer you want is 2700001.1. Instead you get 2700001.0. The float doesn’t have enough precision to show the fine detail. At that scale, all of your data will snap to lie on a 1 meter scale grid. Any sub-meter building features will just get flattened onto your walls and that would cause flickering. When you read in your data from external sources, you’ll have to temporarily store it in doubles instead of floats if it has any decimal values or they will simply get lost.

Ideally, each building’s data should be relative to its own origin and you place the building as a whole using translate(). Even if it’s not, you can translate() the building so its center is at the origin, scale() it there and then translate() it back. But you shouldn’t need to scale anything if you have enough floating-point precision to make sure your surfaces aren’t snapping to lie in the same plane.

All my coordinates has at most 2 decimals. I tried this

float s = 2700000.0f;
 println( s + 1.111 );

output >>> 2700001.111

So it seems that the program can handle decimals even with float.

I had the idea to translate origin → scale() → translate back, but the fact is that it’s boring :smiling_face_with_tear:

There’s not a processing function that scales doing it internally? Otherwise i’m going to try that trick.

The reason why I cannot (I could, but is not a good idea) translate everything to origin is that my program often interface with positions that come from real world coordinates ( from example take a look to my site from that specific point of view). I know that I could save the center of the world and subtract every time I interface with real coordinates, but that would not be optimal. Also, my program is more than 10.000 lines of code, translate everything at this point would be quite painful :confounded:

That’s very interesting that you get 2700001.111. On my linux PC running Processing 4.0b6, I get 2700001.0. What hardware, OS, and Processing version are you running? In any case, the GPU may well have even lower resolution for its floats, especially as it transforms the points in the vertex shader.

If you can, as a hack, put a city near the origin and see how it renders there. If there is no flicker then you’ll know float resolution is the problem. If there is still flicker, then it’s probably that you have too many co-planar polygons that are fighting to be on top. Scaling was just a hack I was suggesting to nudge them out of the same plane. Better would be to tweak the models, if that’s the issue. Keep in mind that it’s fine if a back-facing polygon shares with a front-facing one – it’s okay to have two cubes sharing a wall as long as one isn’t inside the other.

I’m running it on mac os - 16gb ram, i’m using the same processing version of you. I’m not using the processing IDE but i’m using processing as external library inside a java project (idk if that could influence floats).
Anyway, I just saw that transposing everything near zero could help, I need to do some tests loading huge amount of data but it could work, thanks! I’m going to send a video without flicker

Edit:
Here the link . Do you think that it can be improved more than this? If you look at the strokes, there’s still some little flicker. Here I’ve just made a PShape.translate(-groundCenter)