Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade to a geometry or compute shader for line drawing, using only a single line points array for input. #7

Open
trusktr opened this issue Jan 20, 2023 · 4 comments

Comments

@trusktr
Copy link
Member

trusktr commented Jan 20, 2023

To fix #5, we need to take advantage of WebGL 2 geometry shading (generate the vertices in the shader) or WebGPU compute shading (similar, but different), so that the only thing we need to pass in is the user line points.

Ultimately the user will provide only a single array of line points, then shading handles the rest, which includes generating points or pixels around the user points to draw the region of the line, including joint miters, rounded corners, end caps, etc.

This will be better for both drawing fidelity and performance because,

  • only a single array of user line points needs to be uploaded, and all line drawing options are provided as uniforms
  • geometry is no longer computed on the CPU
  • more possibilities in line drawing options are easily possible without much performance loss, whereas adding things like better miters, line caps, etc, will more drastically decrease performance if calculated on the CPU

closes #5

@LeXXik
Copy link

LeXXik commented Sep 5, 2023

I don't want to be that guy, but there are no geometry shaders in WebGL.

@trusktr
Copy link
Member Author

trusktr commented Nov 4, 2023

@LeXXik I meant "generating vertices/geometry with the vertex shader" rather than the traditional approach where all points are passed in as attributes up front.

Example:

https://webgl2fundamentals.org/webgl/lessons/webgl-drawing-without-data.html

I wasn't aware I was referring to a native non-ES OpenGL feature! :)

For thick line drawing, we'd send in only the points along the line (the user's line path), and then we send in a number indicating the number of points we will "generate" (the number of times the vertex shader should be invoked where we calculate the line points including end caps, etc, all in the shader).

Thus, we'd be "generating geometry with the vertex shader", thus I was calling it "geometry shader".

But I'm not sure if there will be a performance gain if we calculate the line points every frame. I suppose it could be a win for animated lines, otherwise if a line is not animated we might want to calculate on the CPU once up front.

@LeXXik
Copy link

LeXXik commented Nov 5, 2023

Ah, I see where I got confused. Thank you for the explainer!

For a static line (where points don't move/change), the CPU side will be cheaper, I suppose, as the calculations would be done only once and stored in the vertex buffer with a simple shader. As opposed to being calculated on GPU every frame.

@trusktr
Copy link
Member Author

trusktr commented Nov 5, 2023

A use case I'm imagining is for realtime plotting systems that have plot lines with lots of points, and having to upload data to the GPU each frame. In that case I wonder if uploading the only the path each frame would be faster than calculating/uploading all line vertices each frame.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants