Render a plane seen from the side as line?

Started by rkull, November 11, 2020, 12:49:17 PM

Previous topic - Next topic

rkull

My first post here! :)

Have been googling around alot looking for answers to this but no success yet. Maybe someone here have done something similar.

My problem:
I'm visualizing a vehicle moving around on a surface. In the app, I have added the possibility to split the view into smaller parts with other camera positions. Currently, the user can select to view the scene in 1-4 different views; 3d (where camera can be zoomed and rotated around vehicle), top (vehicle seen from above, only zoomable), side (only zooming) and rear (only zooming).
The problem I'm facing is when using the side and rear views. At some viewing angles, and depending on the surface (which is not flat), the surface will disappear (since the mesh has no thickness, I know this is how it works).

Wanted behavior:
When using the side and rear views, I would like to visualize the surface as a line below the vehicle, like a 2d scene. So, do anyone have any tips of how I can solve this? I've been trying some custom shaders but no luck (but I'm defenently no shader-expert ;)) Also, polyline seems to be out of the question since I would have to calculate the line coordinates which is too heavy for my hw.

In the desktop version, the drawWireframe(...) solves the problem for me if I set the near/far planes at the same distance (cam - vehicle distance). But the desktop drawWireframe() and Android drawWireframe() doesn't give the same results. Read somewhere that this was because of OpenGl ES but I don't know what in OpenGl ES that causes the problem..

Hope you guys understand my problem and what I'm trying to do!
I know this is not particularly a jpct question but more of a general opengl topic. But since I'm using jpct in my project, I thought this would be a good place to ask some questions :)

EgonOlsen

Yes, wireframes don't play well with the way OpenGL ES works. I don't remember the exact details of why that is, but IIRC, they omitted something from OpenGL that one would need to do it in the same way as it's done on the desktop. So that's out of question.

What kind of surface are we talking about here? Do you have a screen shot?

rkull

Thanks for the fast reply! :)

I generate the surface from landxml files, which are basically just xml files containing vertces and faces. The landxml files are generated by other companies and they represent some real terrain somewhere in the world.

Sorry, the project is for my work and I don't think I can share any screenshots of the real application. But I can share some image of a terrain from a simulator I'm running on my computer, hope that's of any use! In the attachment, you'll see a zoomed out image of a terrain. Note that this is just one example, the terrain could look pretty much like whatever real-world ground terrain where you can drive a car.

rkull

Here's the same terrain with wireframe turned on. Note that the triangles will not be uniform.

(Sorry about the small file size)

EgonOlsen

Yeah, as said: Wireframe isn't an option on ES. It would require a complete new model to render correctly (and I'm not sure how to even create that from the top of my head). Maybe cartoon rendering is an option? I'm not sure, maybe it fails in these edge cases as well. We have an old thread about such an approach here: http://www.jpct.net/forum2/index.php?topic=940.0. I've updated the zip in the link to work on modern systems (Windows at least).

MichaelJPCT

can you pre-create (before  runtime) a 3d model which looks like wireframe of desktop GL?

rkull

Quote from: EgonOlsen on November 11, 2020, 03:52:48 PM
Maybe cartoon rendering is an option? I'm not sure, maybe it fails in these edge cases as well. We have an old thread about such an approach here: http://www.jpct.net/forum2/index.php?topic=940.0. I've updated the zip in the link to work on modern systems (Windows at least).

I think I might have the same problem, but I will definently look it up! Thanks!

Quote from: MichaelJPCT on November 11, 2020, 04:33:24 PM
can you pre-create (before  runtime) a 3d model which looks like wireframe of desktop GL?


Unfortunately, that's not an option. I'll still have the same problem when looking on that model from the "side". Also, when using near/far planes to cut away stuff, the desktop wireframe does this wonderful thing of drawing the line along the clipping planes.
Check out the attachments, "Capture1" is a plane model with wireframe turned on and near/far planes set to fit the whole model. In "Capture2", I've moved the near plane forward to cut away a piece of the model but the line closest to the camera is still being drawn even though it's not really part of the triangles.

EgonOlsen

I've looked into the source code again to give some background on the wireframe problem: OpenGL has a polygon mode called GL_LINE. That means that polygons are not textured anymore but drawn as (out-)lines. That's what the desktop version uses.
OpenGL ES doesn't have this...because of...reason, I guess. What it has, is an option to render the geometry as GL_LINE_STRIP and that's what the Android version uses. But the geometry in a mesh that's supposed to form an object out of triangles usually doesn't work well as a line strip. That's why the wireframe mode on Android doesn't look good. You could either model your geometry in a way that it forms a line/triangle strip (which is possible to a degree depending on the model) or create a different, maybe simplified model that does. Or create a huge Polyline structure that does this, because Polylines are basically line strips. However, Polylines aren't really meant to be used for very large strips. I'm not sure how they behave performance and memory wise if you do.

EgonOlsen

Apart from all that, can't you just avoid the situation at all? If I got this right, what you basically do is to display a car driving on a terrain, right? If you prevent the camera from moving too close to the terrain (let alone beneath it), you shouldn't have this issue in the first place. Or isn't that an option for some other reason?

rkull

I checked the Android example of drawing a triangle at https://developer.android.com/training/graphics/opengl/draw. And more specific, the line

// Draw the triangle
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

Tried fiddling around with some other modes with the results attached. Seems like GL_LINES do exist as an option, but it's even wors than GL_LINE_STRIP.

rkull

But this result I got with GL_LINE_LOOP. Could that be used or do I not know what I'm talking about? I don't know what the result will be when having a mesh of many triangles. And I don't know if the moving of near/far plane will actually move the lines (as in my earlier post)

rkull

Quote from: EgonOlsen on November 11, 2020, 06:06:47 PM
Apart from all that, can't you just avoid the situation at all? If I got this right, what you basically do is to display a car driving on a terrain, right? If you prevent the camera from moving too close to the terrain (let alone beneath it), you shouldn't have this issue in the first place. Or isn't that an option for some other reason?

Yeah maybe, but since it's supposed to be a side 2D(-isch) view. I don't want to add too much height on the camera to get a good enough viewing angle... somthing tells me that I will have this problem at some angles and surface slopes anyway..

rkull

Quote from: rkull on November 11, 2020, 07:55:43 PM
But this result I got with GL_LINE_LOOP. Could that be used or do I not know what I'm talking about? I don't know what the result will be when having a mesh of many triangles. And I don't know if the moving of near/far plane will actually move the lines (as in my earlier post)

Now I know that it doesn't work when moving near plane. It just cuts away the line and doesn't move it like in desktop.. too bad..

EgonOlsen

What you are fiddling around there with is how to interpret the vertex data (either as triangles or as lines or as line strips or whatever). That will never look right on all models. What we actually need is a mode to interpret them as triangles but to render these as lines. And that's missing in ES. GL_LINES (which exists) isn't the same as GL_LINE (which doesn't exist). They are used in completely different contexts. I once saw a shader that did wireframe drawing, but it was quite complicated and used some calls to functions from another framework of some kind that was part of a 200mb download...so not really usable in this case, I'm afraid.

rkull

Ah, ok, I see, thanks for clearing that out :)

Yeah, I've also come across those aswell, but from what I've tried, a shader based solution that draws lines on the front facing triangles will give me the same problem when looking on the object from the side anyway. But now since we're talking about shaders; have you ever done any cross section shaders like described here https://codeburst.io/unity-cross-section-shader-using-shader-graph-31c3fed0fa4f (for unity but anyway). I'm thinking that if I have my surface duplicated in two layers (one straight under the other) but the same object, and then fill the area between the surfaces with some solid color in a shader it might give me the result I'm looking for. I have no clue of how to set that up though..