Skip to content

Commit

Permalink
wip/gltf on the slab build out (#69)
Browse files Browse the repository at this point in the history
* Support for indexed vertices, ie native vertices can be indexed

* debugging gltf on-the-slab textures

* debugging gltf on-the-slab textures, still

* gltf on-the-slab can use textures

* porting over more gltf tests

* setting stage images resets the atlas size on the slab

* ported over more tests to the slab

* ported over atlas_uv_mapping test

* ported uv_wrapping test

* ported negative_uv_wrapping

* WIP porting scene_cube_directional (test of directional lighting)

* WIP CPU-side sampling for testing

* ported scene_cube_directional test of directional lighting

* fixed accessors, they now take their own offset into account

* fix accessors - view stuff shouldn't be in GltfAccessor, it should be in GltfBufferView

* WIP GLTF is the only internal representation

* WIP more work on GLTF is the only internal representation

* finished porting tests to gltf-on-the-slab

* criterion benchmark stub

* added criterion benchmark and ported scene_parent_sanity test

* ported pbr test minus bloom

* pbr metallic spheres test doesn't use bloom

* chore/remove bytemuck from renderling shader (#70)

* parted out slab into slabcrab

* parted out slab into crabslab

* parted out slab into crabslab

* Update README.md

* readme

* WIP part out crabslab, remove non-slab shaders, remove bloom (to be reimplemented later)

* WIP

* img-diff takes into account pixel threshold and image threshold

* fixed problems with the skybox after slabbing

* fixed tests to use explicit linear transfer where appropriate
  • Loading branch information
schell authored Jan 3, 2024
1 parent 180c325 commit a61fb1c
Show file tree
Hide file tree
Showing 104 changed files with 5,012 additions and 5,334 deletions.
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ members = [
"crates/renderling",
"crates/renderling-shader",
"crates/renderling-gpui",
"crates/renderling-derive",
"crates/crabslab",
"crates/crabslab-derive",
]

exclude = ["./shaders"]

resolver = "2"

[workspace.dependencies]
async-channel = "1.8"
bytemuck = { version = "1.13.0", features = ["derive"] }
futures-lite = "1.13"
gltf = { git = 'https://github.com/gltf-rs/gltf.git', features = ["KHR_lights_punctual", "KHR_materials_unlit", "KHR_materials_emissive_strength", "extras"] }
image = "0.24"
log = "0.4"
glam = "0.24.2"
glam = { version = "0.24.2", default-features = false }
snafu = "0.7"
winit = { version = "0.27" }
wgpu = { version = "0.17" }
113 changes: 113 additions & 0 deletions DEVLOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,118 @@
# devlog

## Sat Dec 23, 2023

I've ported over a majority of the tests to the GLTF-on-the-slab implementation.
I'm currently working on the big PBR test and having trouble with the skybox, which
is rendering all black...

Debugging rabbit hole:
* So is it even running?
- Yes, logging shows that it's running.
* Could it be it needs to be run in its own render pass?
* Before I even check that, I see that the skybox's vertex shader uses the `instance_index` as the `Id` of the camera, and I'm passing `0..1` as the instance range in the draw call.
- So we need a way to pass the camera's `Id` to the skybox.
- I just added it as a field on `Skybox`
- Using that new field fixed that issue. Now I have an issue with bloom.

After fixing the skybox rendering it seems bloom isn't running.

Debugging rabbit hole:
* So is it even running?
- Yes, logging shows that it's running.
* Is the result being used downstream during tonemapping?
- It seems to be.
* Let's check to see that there isn't something funky when configuring the graph.
- Nothing I can tell there.
* Maybe print out the brightness texture and make sure it's populated?
* Losing steam here, especially since bloom needs to be re-done as "physically based".

### Physically Based Bloom

## Thu Dec 21, 2023

It's the solstice! My Dad's birthday, and another bug hunt in `renderling`.

### Porting gltf_images test
The test `gltf_images` tests our image decoding by loading a GLTF file and then
creating a new staged object that uses the image's texture.

It's currently coming out all black, and it should come out like
![gltf_images test](test_img/gltf_images.png).

I recently got rid of the distinction between "native" vertex data and GLTF vertex
data. Now there is only GLTF vertex data and the "native" `Vertex` meshes can be
conveniently staged (marshalled to the GPU) using a helper function that creates
a `GltfPrimitive` complete with `GltfAccessors` etc.

Debbuging rabbit hole:
* Let's compare old vs new vertex shaders
- It doesn't seem to be the vertices, because the staged vertices (read from the GPU) are equal to the original mesh.
- The staged vertices are equal to the original CPU-side mesh, but the computed vertex values are different from legacy.
- It looks like transforms on `RenderUnits` are not transforming their child primitive's geometry
- Got it! It was because `GltfNode`'s `Default` instance was setting `scale` to `Vec3::ZERO`.

## Wed Dec 20, 2023

I think I'm going to keep going with this idea of making GLTF the internal representation of the
renderer.

## Tue Dec 19, 2023

### Thoughts on GLTF
GLTF on-the-slab has been a boon to this project and I'm tempted to make it the main way we do
rendering. I just want to write this down somewhere so I don't forget. Currently when loading
a GLTF file we traverse the GLTF document and store the whole thing on the GPU's slab. Then
the user has to specify which nodes (or a scene) to draw, which traverses one more time, linking
the `RenderUnit`s to the primitives within the GLTF. I _think_ it might be cognitively easier
to have GLTF nodes somehow be the base unit of rendering ... but I also have plans for supporting
SDFs and I'm not sure how that all fits together.

* [At least one other person is thinking about putting SDFs in GLTF using an extension](https://community.khronos.org/t/signed-distance-field-representation-of-geometry-extension/109575)

Anyway - I'll keep going with the momentum I have and think about refactoring towards this in the future.

## Mon Dec 18, 2023

### Simple Texture GLTF Example
* The `simple_texture` test is rendering the texture upside-down.
* There are _no rotation transformations_ in its node's hierarchy.
* What does the atlas look like?
- It's not the atlas, the two tests (slabbed and the previous non-slabbed) have
identical atlas images.
* So what about UV coords?
- Comparing runs of the vertex shaders shows that the UV coords' Y components are flipped.
- So, 0.0 is 1.0 and 1.0 is 0.0
* So is there something doing this intentionally?
- Nothing that I can easily see in the `gltf_support` modules...
- It has something to do with the accessor.
- I can see in the GLTF file that the accessor's byte offset is 48, but somehow in
my code it comes out 12...
- It was because the accessor's offset was not being taken into account.

### Analytical Directional Lights
I got analytical lighting working (at least for directional lights) on the stage.
The problem I was having was that the shaders use `Camera.position` in lighting
equations, but that was defaulting to `Vec3::ZERO`. Previously in the "scene"
version of the renderer (which I'm porting over to "stage") the camera's position
was set automatically when setting the projection and/or view.
I had to run both versions of the vertex AND fragement shaders to track this down. Ugh!

## Fri Dec 8, 2023

I've been having trouble getting the new GLTF files on-the-slab method to pass my
previous tests. Mainly because of little things I had forgotten. Little bits of
state that need to be updated to run the shaders. The most recent was that the
size of the atlas needs to be updated on the GPU when the atlas changes.

I'm moving over tests from `renderling/scene/gltf_support.rs` to
`renderling/stage/gltf_support.rs` one at a time.

## Thu Dec 7, 2023

Ongoing work to get GLTF files on-the-slab working. When this work is done GLTF
file imports should be lightening fast.

## Wed Nov 15, 2023

I resubmitted the NLNet grant proposal with expanded scope to take care of [the
Expand Down
2 changes: 2 additions & 0 deletions NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Just pro-cons on tech choices and little things I don't want to forget whil impl
- using cargo and Rust module system
- expressions!
- type checking!
- traits!
- editor tooling!

## cons / limititions
Expand All @@ -28,6 +29,7 @@ Just pro-cons on tech choices and little things I don't want to forget whil impl
* for loops are hit or miss, sometimes they work and sometimes they don't
- see [this rust-gpu issue](https://github.com/EmbarkStudios/rust-gpu/issues/739)
- see [conversation with eddyb on discord](https://discord.com/channels/750717012564770887/750717499737243679/threads/1092283362217046066)
* can't use `.max` or `.min`
* meh, but no support for dynamically sized arrays (how would that work in no-std?)
- see [conversation on discord](https://discord.com/channels/750717012564770887/750717499737243679/1091813590400516106)
* can't use bitwise rotate_left or rotate_right
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "renderling-derive"
name = "crabslab-derive"
version = "0.1.0"
edition = "2021"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn get_params(input: &DeriveInput) -> syn::Result<Params> {
_ => {
return Err(syn::Error::new(
name.span(),
"deriving Slabbed only supports structs".to_string(),
"deriving SlabItem only supports structs".to_string(),
))
}
};
Expand All @@ -41,7 +41,7 @@ fn get_params(input: &DeriveInput) -> syn::Result<Params> {
.map(|field| {
let ty = &field.ty;
quote! {
<#ty as renderling_shader::slab::Slabbed>::slab_size()
<#ty as crabslab::SlabItem>::slab_size()
}
})
.collect();
Expand Down Expand Up @@ -69,7 +69,7 @@ fn get_params(input: &DeriveInput) -> syn::Result<Params> {
})
}

#[proc_macro_derive(Slabbed)]
#[proc_macro_derive(SlabItem)]
pub fn derive_from_slab(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input: DeriveInput = syn::parse_macro_input!(input);
let name = &input.ident;
Expand All @@ -88,8 +88,7 @@ pub fn derive_from_slab(input: proc_macro::TokenStream) -> proc_macro::TokenStre
/// Adds a `CanFetch<'lt>` bound on each of the system data types.
fn constrain_system_data_types(clause: &mut WhereClause, tys: &[Type]) {
for ty in tys.iter() {
let where_predicate: WherePredicate =
syn::parse_quote!(#ty : renderling_shader::slab::Slabbed);
let where_predicate: WherePredicate = syn::parse_quote!(#ty : crabslab::SlabItem);
clause.predicates.push(where_predicate);
}
}
Expand Down Expand Up @@ -129,9 +128,11 @@ pub fn derive_from_slab(input: proc_macro::TokenStream) -> proc_macro::TokenStre
FieldName::Ident(field) => Ident::new(&format!("offset_of_{}", field), field.span()),
};
offsets.push(quote! {
pub fn #ident() -> usize {
#(<#offset_tys as renderling_shader::slab::Slabbed>::slab_size()+)*
0
pub fn #ident() -> crabslab::Offset<#ty> {
crabslab::Offset::new(
#(<#offset_tys as crabslab::SlabItem>::slab_size()+)*
0
)
}
});
offset_tys.push(ty.clone());
Expand All @@ -145,7 +146,7 @@ pub fn derive_from_slab(input: proc_macro::TokenStream) -> proc_macro::TokenStre
}

#[automatically_derived]
impl #impl_generics renderling_shader::slab::Slabbed for #name #ty_generics #where_clause
impl #impl_generics crabslab::SlabItem for #name #ty_generics #where_clause
{
fn slab_size() -> usize {
#(#sizes)+*
Expand Down
33 changes: 33 additions & 0 deletions crates/crabslab/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[package]
name = "crabslab"
version = "0.1.0"
edition = "2021"
description = "Slab allocator focused on GPU compute (rust-gpu)"
repository = "https://github.com/schell/renderling"
license = "MIT OR Apache-2.0"
keywords = ["game", "graphics", "shader", "rendering"]
categories = ["rendering", "game-development", "graphics"]
readme = "README.md"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
default = ["wgpu", "glam", "futures-lite"]
futures-lite = ["dep:futures-lite"]
glam = ["dep:glam"]
wgpu = ["dep:wgpu", "dep:bytemuck", "dep:snafu", "dep:async-channel", "dep:log"]

[dependencies]
async-channel = {workspace=true, optional=true}
bytemuck = {workspace=true, optional=true}
futures-lite = {workspace=true, optional=true}
log = {workspace=true, optional=true}
crabslab-derive = { version = "0.1.0", path = "../crabslab-derive" }
snafu = {workspace=true, optional=true}
wgpu = {workspace=true, optional=true}

[target.'cfg(not(target_arch = "spirv"))'.dependencies]
glam = { workspace = true, features = ["std"], optional = true }

[target.'cfg(target_arch = "spirv")'.dependencies]
glam = { version = "0.24.2", default-features = false, features = ["libm"], optional = true }
34 changes: 34 additions & 0 deletions crates/crabslab/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div align="center">
<img src="crabslab.png" alt="slabcraft for crabs" width="512" />
</div>

## what
`crabslab` is a slab implementation focused on marshalling data from CPUs to GPUs.

## why
### Opinion
Working with shaders is much easier using a slab.

### rust-gpu
This crate was made to work with [`rust-gpu`](https://github.com/EmbarkStudios/rust-gpu/).
Specifically, using this crate it is possible to pack your types into a buffer on the CPU
and then read your types from the slab on the GPU (in Rust).

### Other no-std platforms
Even though this crate was written with `rust-gpu` in mind, it should work in other `no-std`
contexts.

## how
`crabslab` includes:
* a few traits:
- `Slab`
- `GrowableSlab`
- `SlabItem`
* a derive macro for `SlabItem`
* a few structs for working with various slabs
- `Id`
- `Array`
- `Offset`
* a helper struct `CpuSlab`
* a feature-gated helper for using slabs with `wgpu` - `WgpuBuffer`
- [example](src/wgpu_slab.rs#L344)
Binary file added crates/crabslab/crabslab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit a61fb1c

Please sign in to comment.