asny / three-d

2D/3D renderer - makes it simple to draw stuff across platforms (including web)
MIT License
1.24k stars 105 forks source link

Add a triangle example which uses `core` #350

Closed silverlyra closed 1 year ago

silverlyra commented 1 year ago

👋🏻 On the application I’m working on, we’re moving away from using renderer::InstancedMesh due to performance issues, and we’d like to switch to using lower-level primitives.

I’d like to use the mid-level core module because it’s more convenient than using glow directly, but I didn’t find any examples of how to use it. So I’ve tried to put together a version of the triangle demo, but which only uses core.

I say “tried to” because nothing appears except for the clear color 🥲. I used Spector to look at the commands generated by triangle and triangle_core, and I can’t find any meaningful difference between them. Still thought I’d open the PR anyway in the hope that I‘m just missing something simple.

asny commented 1 year ago

👋🏻 On the application I’m working on, we’re moving away from using renderer::InstancedMesh due to performance issues, and we’d like to switch to using lower-level primitives.

That probably makes sense, it's always easier to optimise for a specific use-case rather than a generic use-case. However, I would be very grateful if you could provide some insights into where there's performance issues? Is it rendering many instanced meshes, rendering many instances in few instanced meshes or is it something else, like updating the data?

I’d like to use the mid-level core module because it’s more convenient than using glow directly, but I didn’t find any examples of how to use it. So I’ve tried to put together a version of the triangle demo, but which only uses core.

Exactly how it's supposed to be used. The core module should be as fast as using glow directly, but way more convenient. Anyway, you're right, there's no examples so would be nice to add one. Actually, for a long time, the triangle example only used core but at some point I changed it to be more consistent. Never thought of having two examples, it's a good idea 👍

I say “tried to” because nothing appears except for the clear color 🥲. I used Spector to look at the commands generated by triangle and triangle_core, and I can’t find any meaningful difference between them. Still thought I’d open the PR anyway in the hope that I‘m just missing something simple.

It wasn't easy to find but I fixed it in 683e968. Basically, the camera needed to be moved back to see the triangle, so we need to multiply with the view matrix as well as the projection matrix.

Still, there's an issue, the triangle is all white except at the edge. I really don't know why 😬

silverlyra commented 1 year ago

🌈 ✨ Thank you for making the 🔺 visible! @asny

Still, there's an issue, the triangle is all white except at the edge. I really don't know why 😬

After looking into how core::Buffer::fill was actually implemented, I was able to figure that part out:

--- a/examples/triangle_core/src/main.rs
+++ b/examples/triangle_core/src/main.rs
@@ -28,9 +28,9 @@ pub fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
     let colors = VertexBuffer::new_with_data(
         &context,
         &[
-            Color::RED,   // bottom right
-            Color::GREEN, // bottom left
-            Color::BLUE,  // top
+            Color::RED.to_vec4(),   // bottom right
+            Color::GREEN.to_vec4(), // bottom left
+            Color::BLUE.to_vec4(),  // top
         ],
     );

It seems converting a Color to a Vec4 happens implicitly when using it as a uniform, but not when it’s in a vertex buffer.

https://user-images.githubusercontent.com/25393735/231334775-1ba02117-c8cf-4be4-a199-1c4c6b6a2546.mov

I haven’t updated the examples readme – not sure what your process is for building the examples site, but I could take a crack at it.

asny commented 1 year ago

🌈 ✨ Thank you for making the 🔺 visible! @asny

No problem, thanks for figuring out the color issue 🙂

It seems converting a Color to a Vec4 happens implicitly when using it as a uniform, but not when it’s in a vertex buffer.

That's definitely not very intuitive 😬 I changed it so that Color is normalized both when used as a uniform and when in a buffer in 5cb5c07. I merged it into this branch and reverted your fix.

I haven’t updated the examples readme – not sure what your process is for building the examples site, but I could take a crack at it.

Ah, no problem, I added the example to the readme in 4abe6df. And the process to build the examples is to run this fancy bash script locally 😆 I'll do that at some point, I just have to figure out how to reduce the size of the screenshots, the recent changes to the window module broke that 😞

asny commented 1 year ago

Made it similar to the triangle example with the last two commits, so I think it's good to merge, unless you have something else?

silverlyra commented 1 year ago

nope, LGTM!