#DARE (Danny's Awesome Rendering Engine)
1 messages · Page 3 of 1
epic
I just don't render my surfaces if normals are missing kek
based
Or any of the other attributes (position, uvs, tangents)
don't waste your precious cpu cycles on them
should i just blindly
believe that all my positions + normals will be vec3f32
and my texcoords uh
it is invalid by gltfspec
to have anything else
If your gltf has vec4 positions or vec2 positions, you can safely delete it
As it is invalid
understood
unsigned byte normalized huh
eh i'll ignore it and if it becomes an issue then i'll worry about it later
the only other accessor types that are accepted are for quantized meshes
for example you could have positions be a vec3 of integers or unsigned integers
but that doesn't matter right now
And it is an extension so
quantization means you take continuous values and discretize them to save space and compute
ohhh
so you take floats which are big 4 byte values
and you put them into unsigned shorts
yaa that makess sense
which are epic 2 byte values
so is that the main application of stuff like sparse accessors?
hmm i see
Mesh quantization works with regular accessors
cool ill care about that feature one day...
but it is not important now ye
kekw another rewrite incoming
yeah
heh so funny problemo #2
how am i supposed to indicate
the generated normal buffer is binded to the primitive
i refuse to do vertex struct mainly because i wanna have the later flexibility of being able to modify all of stuff en-masse
i never understood peopl who keep attributes in separate buffers : >
iirc some nvidia slide explaining
you should keep your attributes in seperate suballocations
you still make a vertex struct except now you put vectors instead of attributes
both ways have their pros and cons
and no, interleaved vs separate performance is meaningless
oh kekw i might to interleaved then since it's easier
AMD recommends separate yes, but I can guarantee you will never, ever see a difference in a profiler
but wouldn't that making modifying the buffer a bit harder however?
no and you usually don't modify vertex data
unless you're doing per vertex dynamic displacement or ridiculously fancy stuff like that
that would mean rebuilding your whole BLAS every time too
i just have a realization
revelation
How can I uh
know what my 2 next other vertices are gonna be?
Can I just assume they're the next 2 in the index buffer?
why the fuck am i asking this
ofc it is am i stupid
no worries, im also asking dumb things all the time
for v in vertices {
v.n = vec3(0, 0, 0);
}
for t in triangles {
n = normalize(cross(t.b - t.a, t.c - t.a));
// add the normal to each vertex such that smooth normals are generated
t.a.n += n;
t.b.n += n;
t.c.n += n;
}
for v in vertices {
v.n = normalize(v.n);
}
what
here
my brain shutted off i was wondering how we were filling up all the normals
when the
when tringle has 3 points
4 pointed triangle 
tringle enough to me
hm
how to do images

guys
i might revert back 
i understand way more what i was doing
this feels like i'm fucking around
nah fuck that
ill find out
im him
im not him
NAH IM HIM. God the ability to modify the gltf document is so useful. I'm able to gaslight other parts of my program that things exist when they were just generated
also I think I know why the Sponza broke
I didn't add support for secondary texture coordinates
I don't have support for secondary texture coordinates and my sponza loads fine...
Nono i fucked up how I was selecting accessors @feral trellis
I didn't explicitly state 0 for the first set
So that is how I got into gambling there I think
theoretically i could reuse my old asset system
but it's a hot steaming pile of mess and I like the new one I made
combines what LVSTRI told me with some extra stuff he would scream at me for 
I'm 100% certain it is bad practice to be modifying your gltf json variable, but it works so nicely as an intermediate between gltf -> asset loader
ASSET IMPORTING WORKS!!
i need to get materials working
then we're good
wait it's 1am? ill just do some clean up work then
It doesn't feel okay so to
vertices.map(|x| {
x as u32
}).collect<Vec<u32>>();
eh why not 
though if you just want to reinterpret the bits bytemuck will do that for you
god i rewritten my entire asset loader within a day 
certainly not the last time youll do that
i have an abstraction layer that lets me make "virtual" buffers which sounds dumb as fuck but useful if I need to gaslight my asset loaders into thinking a normal buffer does indeed exist
https://github.com/NotAPenguin0/andromeda-rs/tree/master/crates/assets im actually pretty happy with my asset system
Oh
my asset system is very simple
I like mines a lot however. Everything is passed via handles
which makes it really easy to refactor
Yeah, same here
But the asset system has no loading logic
Everything revolves around
pub trait Asset {
type LoadInfo: Send + 'static;
fn load(info: Self::LoadInfo, bus: EventBus<DI>) -> Result<Self>
where
Self: Sized;
}
This trait
i should use rust traits 
I have it very traditionally where you just select a file to load then it creates a scene struct
"what if you had the concept of interfaces but not trash"
yeah im just not used to them yet
i'm mainly just confused how you deal with loading stuff mid way through
my system just handles storage and accessing of assets
The actual loader is for example https://github.com/NotAPenguin0/andromeda-rs/blob/master/crates/assets/src/texture/loader.rs
ohh i see
that's interesting
that would require me to rewrite my entire loader (again)
AHHHH fuck it
Okay excuse my stupiditiy
Oh ait
I can't asj how you load scenes as you just do terrain 
it'd work the same way though
I'd assume so a Scene struct then multiple scene loaders implenenting asset
add a Scene asset with some LoadInfo, probably a json
Which checks the json or gltf or whatever
Splits it into primitives/meshes
Then kicks of a bunch of loads for Mesh assets
hmm i see
so I guess all the metadata about the mesh is already done
it's just waiting on it's associated buffer to load in
hmmm
that makes sense
but also requires me to rework it (again) so it works with indices rather than the raw data

yea basically once you have the metadata (quick) you can kick of a bunch of tasks for the actual meshes
maybe
Where should you put your traits
eh traits.rs
Wait what should LoadInfo even have? Path to the data itself?
it could
pub enum TextureLoadInfo<F: TextureFormat> {
FromPath {
path: PathBuf,
// Callback to do extra processing on the image data on the CPU.
cpu_postprocess: Option<fn(u32, u32, &mut [F::Pixel]) -> Result<()>>,
// Additional usage flags
usage_flags: Option<vk::ImageUsageFlags>,
},
FromRawGpu {
image: PairedImageView,
},
}
This is my loadinfo for textures
cpu_postprocess? I assume this is for stuff like normalizing, changing types?
yep
im yoinking that 
its not amazing but it works
Exactly
Maybe I add a second layer 
File loading + interpretation since gltf has a bit of Base64 stuff
I'm gonna need a very valid reason for changing your gltf at runtime chief
I am already suing you
🫡
I am just using it as a way to temporarily hold information about loading
Right and why do you need that
Why not store the info into a vector
What kind of info are you storing
Because I would need to more or less recreate the exact same info the gltf_json struct is about
Buffer view offsets, stride, view length
Accessor format, offset
What exactly is the piece of code that requires you doing this
Get normals -> if normals don;t exist, generate -> push into scene normal vector -> create buffer view into normal
create buffer view into normal
why
Cuz my asset system works like that 
give me a github link rn
It’s why I;m in the middle of a rework 
I’m not using vertex structs 😭 I’m storing everything separately
Oh i haven’t pushed the new gltf loader yet @devout mesa
WAISIA my pc is still booting up
time's up

So long brothers
Aw fucj
I forgor I was refractoring it 
Turns out I am now moving everything into vecs
i can push it as is
@devout mesa Turns out you were right I didn't need to 
good
make it so you don't need it then
no
why do you like it
I'm not reinventing the wheel with my structs
yeah but it's not changed on the file system whatsoever
let mut document = document.into_json();
I'm mainly modifying that
So I can have indexing as well
so it can work with stuff gltf has already and anything I pre-generated
awaiting
yea wait im trying to get this one refactor to work kek
@devout mesa

its broken + incompleted mainly the buffer bits
i got sponza loading using it however i can't render it as i don't have images rn
So
The judgement is complete
The only reason you modify the JSON document
is because you can use it in add_attribute_to_scene
Correct?
What would you say I do then
You could've just sent a vector..
Do you have vectors or something
Yes 
You seem to have some kind of adversity against them
i think this is left over when i had to use maps from the other gltf loader
so there was a tiny tiny chance there would somehow be a gap
so i just mapped it all
okok ill just past it by vecs instead 
you can index into vecs just fine
vec[0]
it just panics if the index doesnt exist
if you want an error you use .get()
Theres no point in writing .get().unwrap()
If youre going to unwrap immediately just use []
What the hell does blob stand for
there is no way mfs are calling generic data loaded in blob because of the word
genius
binary large o bject
I don't understand one thing
is it that hard to make something in Rust that just works, even if it's botched together
It is easy, but I'm stupid
Like my """asset system""" literally is just a collection of vectors
also I overthink things
I'd say Rust makes it harder to write dumb things and expects you to write prim and proper code, but is it actually this bad
No
I'm just stupid lmao and don't know how to engineer
ask Penguin, he is more experienced
Just do the thing and make it work
Do the simple thing first
Why complicate life
Make shrimple code
cuz why not
Because no pretty effects on screen then
Do you have pretty effects on screen
yeah
I wanna see you work solely on main.rchit
🤝 back to vectors we go
rust-gpu 

Nope not hard for me at least
Uhh yea that works
yeah easy for everyone else
For me I have a vector that contains boxed trait objects of my Asset trait
Something like this
Vec<Box<dyn Asset>>
I'm still so lost wtf an asset trait does 
Traits are implemented for rust types
eh if i can't think of a reason to use it i probably shouldn't ig
idk i can't think of a relevant trait and what it would have that would apply to all my assets.
eh whatever who cares
its not that much harder
traits are like java interfaces
but not poop
hows schbondsa coming along
If I don't see sponza
i too agree
within the next 5 minutes

ill give you 15
I will deport you
ok wait
without random texture selects
fuck
fuck
where sponza
no
how to load images: don't
Should I just assume every texture is gonna be some variant of R8G8B8? plus or minus an A?
or should I go out of my way to ensure proper formatting, etc
A bit unsure how to go around materials? Ig just loop over the materials loop and assume each image referenced in it is unique
For my system I iterate over the textures first (since I know those are unique) then the materials
Since the material only contains like an index to whatever texture it's referencing
hmm alralr
Ahh the proper formatting piece is wasting so much cpu cycles
There has to be a faster way to normalized my types to 0-255
I use rayon to parallelise it
It very much iss
I am still waiting for sponza btw
lvstri is gonna hunt me down for sponza
I absolutely will and you can't hide
i am working on it pls wait
i have come to a brutal realization
materials provide you an index to your texture coordinate
that might be why my texture mapping was wacked
sponza has only one texture coordinate
wtf am i missing then
hmmm
texture transformations?
I haven't added support for that
Sponza has no texture transforms by default
that's it. im done. we're gonna make the first ever rng based gambling renderer
You keep rerunning it until your textures magically line up
99% of programmers stop before they hit it big
i geniunely have no clue why it is randomly selecting textures however 
Show me the shader
ik i f'd up the normal calculation for the world_normal if geom_normal is selected
but shhh
display material_resource.albedo_texture
wdym?
display a color for material_resource.albedo_texture
for each ID choose a different color
choose black for -1 or something
many
no
vec3 hsv_to_rgb(in vec3 hsv) {
const vec3 rgb = saturate(abs(mod(hsv.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0);
return hsv.z * mix(vec3(1.0), rgb, hsv.y);
}```
You use the good old fract * GOLDEN_CONJ trick to generate random colors of a certain saturation
o_pixel = vec4(hsv_to_rgb(vec3(float(meshlet_instance_id) * M_GOLDEN_CONJ, 0.875, 0.85)), 1.0);```
Use it like this
M_GOLDEN_CONJ? Some built-in param into glsl?
parallelizing slow code will not make fast code btw
it will just made slow code faster
which might seem like the same thing, but it's not
Yea esp on lower end hardware with not that many threads / cores
skill issue ig
Fair lol
no
just get faster hardware wdym you aren't using a 512 core supercomputer smh
I don't understand why you're keen on keeping your current architecture
which you know is too slow
it's not a skill issue
i'm still in the middle of a rewrite 
this is using my old stuff i made my new stuff faster
good
what happened to my function
murdered in cold blood
now run again
does it change
if so, congratulations, you managed to invoke UB in Rust
let me see

UB in rust goes wild
could be ub
just as equially the shit architecture
cuz i had to fix another instance of randomly selected textures cuz i said "fuck gltf's very reasonable standard of storing everything in vectors"
imagine using vectors
skill issue ngl
I store everything in spatio temporal 4D data structures
temporal
yes
(I have a burning hatred for temporal effects)
and there is no temporal or spatial stability
(I'm looking at you TAA)
TAA's great wym
look same-ish so it's clearly a skill issue for me then
holy shit
congratulations you managed to invoke UB in rust
wait no that current works fine
truly one of the achievements of all time
wdym
it's purple in the first image, orange in the second
yeah ik
but when rendering that renders perfectly fine
it is the walls, pots, and lion that is fucked
OHH cuz i store everything in a dictionary so it's randomized that is why
Someone should erase your right to hash maps
actually
I will pass a new international law I swear
please
hashmaps aren't ordered
it doesn't really matter the fact that it renders fine even if the ID is different tbh
The very thing that an ID is different from run to run is baaad
yeah ill change that 
I mean hashmaps are fine
Idk what danny's doing that are giving him randomzied results
Lol
okay let me explain how stupid this is
. > "Wow gltf stores everything in a vector!"
. > converts into hashmap
. > subsequently needs to make a lookup table as I sometimes may skip loading stuff so there is gonna be gaps (blud forgor Option<T> exists 💀)
At least its not webdev
so to access anything i need to do:
asset_scene.meshes[lookup_table.mesh[gltf_index]]
I spent 30 minutes centering a checkbox label today and it still doesn’t work
penguin
still better than game engine dev
It doesn’t work I swear
display flex?
Also @tropic vigil if you don't mind me I'm going to copy most of your settings from your blog post for mine
Ill look into it tomorrow, not gonna do that without getting paid for it 
body {
position: relative;
width: 100vw;
height: 100vh;
display: flex;
}
body > div {
position: relative;
display: flex;
flex: 1 0 auto;
align-items: center;
justify-content: center;
}```
Now all the things in DIVs children to body are centered
they must all be display flex though
Hmm
I have a little container with some content
I just want a list of checkboxes inside the container with the labels nicely aligned
put labels in a div
make div display flex and disable auto grow
center the div (with align-items, justify-content)
Alr
wtf mozilla added ai to their docs 
i mean useful as a glorified search engine
wooh
new gltf loader
lets see if this worked
it borked
oh i know why
Dammit
pub enum ImageLoadInfo<'a> {
FromFile {
name: Option<String>,
source: DataSource,
view: DataViewInfo<u64>,
},
FromBuffer {
context: &'a mut crate::app::Context,
name: Option<String>,
source: Box<dyn assets::buffer::Buffer>,
view: DataViewInfo<u64>,
},
}
So this struct has a lifetime yeah?
I wanna put this apart of my trait implentation
but that's not possible 💀
impl<'a> assets::loader::LoadableAsset for Image {
type LoadInfo = ImageLoadInfo<'a>;
}
In your LoadableAsset definition you have to do something like this then
trait LoadableAsset {
type LoadInfo<'a>;
... your old code
}
@dawn wave
It's what I have for my current asset system
I have a Context<'a> and Settings<'a> for each asset
tbfh would rather give image a lifetime but can't figure out where it would go but tbf I don't think image needs one
wdym Context<'a>?
Just fancy settings (since some of my assets need full references to the world and such)
ahh okok
Yea I typed that but then I realized it was dumb
No need to restrict the lifetime of a single struct just because one of it's constructor arguments needs a lifetime
So going with the LoadInfo<'a> method seems most appropriate
Yeah but why would you need a String that would last for the entire program
It saves you a heap allocation compared to String
So say I have just a simple string constants I would rather (and rust actually forces you) to use &'static str
ohhh so 'static is mainly used for constants
Mainly* yea
good enough for me
Or if you have a multitude of strings that you know will never get modified throughout their lifetimes
ohh yeah
Ahh I really don't like this 
Some of my structs don't even need lifetimes as they hold no references I guess functionally it shouldn't make a difference? At least the compiler should recognize "no lifetimes are being used here"
Depends on how your structs are used
If you have useless lifetimes I'd suggest removing them
Complicates the thing for no reason
yeah but I'm implementing a loading trait
tbfh
i think it would be smarter to remove the loading trait
it serves no purpose but to apply limitations onto my assets which can have different loading methods
if that's what you need then do what you must do tbh
Geh I should probably also merge them into one thing
rn I have the horrible if not horrendous paradigm of cpu_buffer and vulkan_buffer
cpu_image, vulkan_image etc....
idk how to solve it however ig I should bite the bullet and accept that I will store all my assets as vulkan stuff i.e. buffers, images since well I'm probably only gonna do it. The only reason why I didn't was for asset loaders
remove the mutable ref
its asking for trouble really
make your context send+sync+clone by wrapping its entire state in a big Arc<Mutex<InnerContext>> and pass it around all you want
Mhm alright
its how i handle all my global-ish state in andromeda
and in phobos too actually
Some stuff has a RwLock instead of a mutex because most accesses are read-only though
Like the asset store is inside a RwLock because you only need write access to load an asset
Iirc i am using it to handle my storage, handle classes
But god damn is having to change my ctx class gonna f everything over
holy shit
RwLock is revolutionary
if not innovative
holy shit
it just fucking works (nvm i deadlocked it)
Where sponza
bork
kekw you may suceed before i do
i am its just that i discovered my entire engine is shit
doesn't matter

my raytracer is literally a main function and a trace function
it's time to become italian and spaghetti
ok so update i got the Arc<RwLock<ctx>> refactor to work
wasn't as bad
In 🦀 we believe 🙏 it made handling memory fuckery so much easier
You guys think it would be a smart idea to add a weak ptr pointing to the original data my handle is pointing to?
Kinda ruins the purpose of a handle tbfh 💀
I wouldn’t
You rarely actually need the data inside except for right when you render it
Hmmm yeah
Ig ill rewirk it again so it just only includes the handle rather than the actual data
Then have the loader struct take in a pointer to the storage
I’m just confused how I would get it my struct to add to the storage class… Should I just pass it in the loader struct as a ref?
What I do is I have the storage call the loader
struct Texture {
}
impl Texture {
fn load(info: LoadInfo) -> Texture {
// all load logic
}
}
struct TextureStorage {
textures: SlotMap<Handle<Texture>, Texture>
}
impl TextureStorage {
pub fn load(&mut self, info: LoadInfo) -> Handle<Texture> {
let texture = Texture::load(info);
let handle = self.textures.insert(texture);
handle
}
}
@dawn wave simple not generic example to illustrate the idea
yep
Ohh this makes more sense now
well, it calls into the texture loading code
Then I make this more generic by having an Asset trait that abstracts this load function

Oppenshitter <<<< BarbiPeak 🙏
do we have sponza yet
time's officially up
He has sponza'd
Huston we have a problem windows 10 died>
Windows 10 fixed itself. i hate microsoft
sounds like a skill issue
@tropic vigil I'm so confused how to seemlessly convert one type to another with bytemuck
Afaik it seems like they don't actually cast it rather just use the existing bytes to reinterpret the data
hmm?
eh I'll just make a macro then iterate over the bytes then just individually cast each one good enough 
are you loading vertices from a gltf?
yeah I honeslty shouldn't worru too much about converting between types
I made some lambdas for converting between types before I used fastgltf
fastgltf has its own buffer tools that make this manual conversion unnecessary
yeah i'll figure something out with macros
I used a lambda template fyi
okok
It's what it does yes
Reinterprets the bytes from one Pod to another Pod type
If you want to actually "cast" types you can use the as keyword or the into() or from() methods from the std::convert traits
/// Convert a slice of bytes from one type to another
fn cast_bytes_slice_type<T: Into<U> + bytemuck::Pod, U: bytemuck::Pod>(
contents: &[u8],
) -> Vec<u8> {
let from_size = std::mem::size_of::<T>();
let target_size = std::mem::size_of::<U>();
assert_eq!(contents.len() % from_size, 0); // Must perfectly fit
// Cast contents (bytes) -> T -> Cast to U -> Reinterpret back to bytes
let contents: Vec<U> = bytemuck::cast_slice::<u8, T>(contents)
.iter()
.map(|x| (*x).into())
.collect();
bytemuck::cast_slice::<U, u8>(contents.as_slice()).to_vec()
}
Good enough 
I got two wolves in me:
One tells me to go fast and worry about it later
The other is telling to actually finish vulkan-tutorial
yes thats the point of bytemuck
no need to allocate new memory, just reinterpret old memory
in the texture loader imo
i have a standalone program that generates mipmaps
but it uses a custom texture format
eah i can't decipher wtf you did
it's magic ✨
don't have a need to create seperate texture types yet

https://github.com/notaPenguin0/mipgen this is the repo
it uses old c++ phobos i think
oh wait no
its pure vk
ok yeah you cna totally adapt that then
i havent even lartn compute shaders yet 
yeah theyre not hard really
im just lost what your compute shader is doing
i totally came up with this math myself dont worry

its just a cubic filter instead of a normal linear one
gives somewhat better results
1 thread per texel, apply cubic filtering in a 2x2 block, downsample
ye
🤔 blits seem good enough
blits are linear filter
cubic looks a tad better
but its more expensive to compute, hence offline preprocessing
blits are fine though
https://github.com/NotAPenguin0/mipgen/blob/9e05c4997ba607ba5b8bd6e0bc7fdd20564e9f38/src/mipgen.cpp#L753 the thing also has an impl using blits
my beloved blits
btw VK_EXT_filter_cubic totally exists
oh damn

since when
it is also totally supported 
yep
uh what does that mean
10%
oh only 10% of devices
i was confused with the 89.66
fellas I realized we’ll need egui support. Is there a way to manually add support or will I have to rely on the other crate.
can I has sponza first pls
🥄🇿🇦
egui-winit-phobos
already exists
just have to update it to latest phobos
its really easy to integrate though
what does the crate do differently from the existing egui-winit integration?
oh so the crate handles making the renderpass for egui. could i integrate egui into phobos myself or is that not possible?
i mean
i wouldnt add it to the core lib
but yeah the crate manages buffers/attachments for egui and creates the pass to insert into your graph
ooh
i gotta sponza first though 
i mean yeah but it'd just be rewriting the integration crate in the end
might as well use that
oh ok ill wait for the crate to update then
🙏
publishing rn
it re-exports egui, so make sure to use that one (use egui_winit_phobos::egui) instead of what you use if you get version conflicts
its pretty common to do
ill update to egui 0.22 later but i need to make sure egui-winit is also updated
Ahh I give up on images. I should probably get some sleep 
Okay so like how should I handle having no images to bind?
If I don’t bind any images, the validation layer will throw a fit as my shader expects it
remember to PARTIALLY_BOUND
I’ll check if that flag was enabled
phobos enables it for unbounded arrays
ayymd
so it seems like gltf borked and for some reason is saying all of my matrices in my scene are identity matrices
Wait should my image types all be R8G8B8A8 as like R8G8B8 isn't supported as well iirc?
In terms of performance I think it depends on the hardware you're running on
Iirc I heard some things saying that internally everything is aligned to R8G8B8A8 size so it doesn't even matter
But yea in my engine I stick with those (WGPU doesn't even support R8G8B8 anyways lel)
kekw
ERROR phobos::core::debug > [VALIDATION]: VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251 (-1094930823): Validation Error: [ VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251 ] Object 0: handle = 0x246e0666970, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xbebcae79 | vkCreateImage(): Format VK_FORMAT_R8G8B8_UNORM is not supported for this combination of parameters and VkGetPhysicalDeviceImageFormatProperties returned back VK_ERROR_FORMAT_NOT_SUPPORTED. The Vulkan spec states: Each of the following values (as described in Image Creation Limits) must not be undefined : imageCreateMaxMipLevels, imageCreateMaxArrayLayers, imageCreateMaxExtent, and imageCreateSampleCounts (https://vulkan.lunarg.com/doc/view/1.3.250.1/windows/1.3-extensions/vkspec.html#VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251)
i think i have to do rgba
it doesn't like rgb
Yeap
It’s so joever. How the hell is my transfer buffer larger than my image buffer
I don't think the image is supposed to be rotated like that...
hmmm why... i think i got my world coordinate wrong
Oh also
The PR in phobos for a growable scratch buffer merged
So you could test that out and it should™️ work
should 
OHH WAIT
I DIDN'T NORMALIZE MY UV COORDINATES
BETWEEN 0-1
LAMOOO
what
that isn't the issue however they're incorrectly rotated somehow
ERROR phobos::core::debug > [VALIDATION]: VUID-VkWriteDescriptorSet-dstArrayElement-00321 (-1862672269): Validation Error: [ VUID-VkWriteDescriptorSet-dstArrayElement-00321 ] Object 0: handle = 0xb6bee80000000073, type = VK_OBJECT_TYPE_DESCRIPTOR_SET; | MessageID = 0x90f9e073 | vkUpdateDescriptorSets() pDescriptorWrites[2] failed write update validation for VkDescriptorSet 0xb6bee80000000073[] with error: Attempting write update to descriptor set VkDescriptorSet 0xb6bee80000000073[] binding #3 with #4 descriptors being updated but this update oversteps the bounds of this binding and the next binding is not consistent with current binding (update past the end of the descriptor set) so this update is invalid. The Vulkan spec states: The sum of dstArrayElement and descriptorCount must be less than or equal to the number of array elements in the descriptor set binding specified by dstBinding, and all applicable consecutive bindings, as described by consecutive binding updates
Uh is this phobos?
im gonna go insane
this issue has to be related to the incorrectly rotated textures
dawg wtf
shwo code
ahh that might be why. What should it changed to be then
it magically fixed itself 
geniunely have no clue what caused it or why it was caused
new bindless system coming soon ™️
keep track of a bindless descriptor set for you
let samplers: Vec<phobos::Sampler> = vec
it's the same bug
despite it being a different gltf loader
it's the same bug
hmmmm maybe I'm handling it entirely wrong?
waut a minute
no way 
Is it because of multiuvs?
sponza has only one set of uvs
yes
.bind_bindless_pool(pool) is all you need
Hmmm is it instancing?
irc I didn't implement that which is probably why deccer's complex cubes isn't 100% correct
🤔 This bug is affecting just one triangle??
It has to be UV related as you can see patterns in the stretched texture
Seems to me like your UVs are being clamped
Is that related to the sampler?
Just display the UVs
Indeed, here's a correct reference
do these barycentrics seem right?
yeah i've omitted the 1 - x - y
It should be vec3(1 - u - v, u, v)
hmmm i'm really stumped on this bug wtff
i'll try other meshes with multiple uv textures and see if the issue continues are there any others?
how are you getting the uvs, in the hit shader that is
vec2 t_v0 = tex_coords.v[ind.x];
vec2 t_v1 = tex_coords.v[ind.y];
vec2 t_v2 = tex_coords.v[ind.z];
vec2 tex_coords = t_v0 * barycentrics.x + t_v1 * barycentrics.y + t_v2 * barycentrics.z;
payload.hit_value = texture(texture_samplers[nonuniformEXT(material_resource.albedo_texture)], tex_coords).rgb
funny thing is that this only happens to sponza
show the whole shader
display normals
iirc these are gonna be normals provided either by the buffer or generated from geometry

I can't see anything wrong with the shader
is there a bistro file?
if you have >=32GB of ram you can convert it
i don't
eh that's fine
nah we ballin' we're gonna import all 32gb 🫡 say goodbye to my pc's memory
it crashed 
Wait is it because of merged texture atlases?
wat
nvm
ah fuck
bistro has multiple uvs
the uh texcoords(1) thingy. i haven't even implemented it yet 
doesn't matter, use only the first set
bistro loaded but i forgor to removed the normal shader
Huston, we got a problem
uhh 1) textures are f'd
- seems like the odd stretching bug no longer occurs
textures ids seem fine
i need a scene with like 2,3,4, and etc. different textures to just test it
this 100% is a uv issue
if it were textures there wouldn't be any sembelance of normalacy
OH WAIT
I'M STUPID
IS IT BECAUSE DOUBLE SIDED?
LMAOOO
nvm i am stupid
this is weird. I would get if it was black i.e. u is inverted, but instead the back wall is v.
i've tested the individual texcoords of each vertices
and it's still stating that the backwall is somehow v
when it really should be u
maybe i'll consult chatgpt 
i also realized some of the uvs are rotated horizontally and stretched too
YOOO THE FLOOR WORKS !!!
(everything else is completely broken beyond disrepair)
Lel
i'm gonna go insane
sounds about right 
this is 100%
if not 1000% some stupid fucking issue with memory limits
yet everything looks right
TEARS IN MY EYES
I FOUND A SMALLER MANAGEABLE MESH THAT I CAN DEBUG
OH MY GOD
shh
if deccer was here he would've blasted you one thousand times over
thank god he isn't

it's probably? down to indexing issues
oh.
oh
oh
oh
ha
heh
no way
ah nvm
huston we have a problem
Primitive name: Some("Unnamed 0") Texture name: Some("Unnamed image 1"). Texture index: 0
Primitive name: Some("Unnamed 1") Texture name: Some("Unnamed image 4"). Texture index: 7
Primitive name: Some("Unnamed 2") Texture name: Some("Unnamed image 7"). Texture index: 3
Primitive name: Some("Unnamed 3") Texture name: Some("Unnamed image 10"). Texture index: 10

this was 100% indexing issues
IT WAS NOT
WHAT
THIS IS NOT A LOADING ISSUE I REPEAT
THIS IS A SHADER ISSUE
WHAT
it is
it was
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `1`,
right: `102`', src\assets\scene\loader\gltf.rs:561:13
now fix
and the next time you abstract something without understanding how you want to use it I will be coming to your house personally.
but i did know :(
good
this was caused by doing what you did actually 
iterating over every mesh -> iterating over every accessor in that prim
cuz i returned a vector of buffer views
problem is that same order of the gltf ordering
is not assured
because i index that using the gltf information provided
I don't understand
where do you get the texture indices from?
actually scratch that
if you get the texture indices from anywhere you're doing it wrong
I am amazed
why did you not think of using the size of the vector at insertion time as your index
that's what i did
. it's just that it didn't lineup with the gltf
for each texture {
index = textures.size();
textures.emplace_back(texture);
}```
right, it should not matter that it doesn't line up with the gltf
wait fuck it doesn't
"it doesn't" what
the index of the accessors does not need to lineup with that in the gltf
accessor_struct_views.push(entry);
// Put index of the accessor struct in the vector
primitive
.accessors
.insert(semantic.clone(), accessor_struct_views.len() - 1);
so this stupidity arises from somewhere else
I fail to understand why you need to assign an index to a primitive's accessor but ok
so where's the actual issue
i got n o clue
i don't think it's accessor related? But also points to me that it is just because the UVs are horrendously wrong which are from the accessors. But if my accessors are wrong, then my vertices would be too, but they aren't
hash_map<texture*, uint32> texture_indices;
vector<texture> textures;
for each texture {
ptr = &textures.emplace_back(texture);
texture_indices[ptr] = textures.size() - 1;
}
// later
for each primitive {
if (primitive.material.has_texture) {
your_thing.texture_index = texture_cache[primitive.material.texture];
}
}
kekw will do
also for accessors
I dunno why you do any of that
I would suggest doing this
vector<vec3> positions;
vector<vec3> normals;
vector<vec2> uvs;
for (accessor in primitive.accessors) {
switch (accessor.type) {
case position:
positions.reserve(accessor.count);
memcpy(positions.data(), accessor.buffer_view ..., accessor.count * sizeof(vec3));
break;
...
}
}```
HMMMMM so this issue isn't accessor
and it isn't texture
so it must be
the shader
but my shaders looks right
AAAAAAAHHHHHHHHHHHHHH
maybe rendering everything assuming a white texture
isn't that bad
like when i add the lighting
it can't be that bad
sexy
See I don't think the issue would lie in my type conversions I do for the buffers
as they work with my vertices just fine and smaller meshes
Yeah my tests pass
Oh just pass it in without type conversion?
nuking the shit out of that code and just memcpy'ing vec2's like god intended

then you can plug it in again after you fixed the issue
ill try that
so you un-nuke the nuked code
trust me it won't work
yeah but if it works 
typically removing chunks of code what I do
print 🙏
it shrimplifies and removes points of failure

