mkrebser / GPUInstance

Instancing & Animation library for Unity3D
Other
228 stars 44 forks source link

This Project is the Bomb! Thank you! #3

Closed najak3d closed 1 year ago

najak3d commented 1 year ago

This isn't really an issue, but I wanted to leave you a positive review/comment. Not sure where else to leave this.

Compliment!: Comparing to the other competing solutions (where they bake vertex positions from each animation into a texture), this one appears to be superior, in that you bake the Bone Keyframes to the GPU and do animation normally using the bones. That's a LOT less data to be processed and sent to the GPU, and seems to me as a superior solution.

Question: How does your solution stack up against the "GPU Instancer" on the Asset Store (and it's add-on "Crowd Animations"?

BUG: I did find one bug -- the "Camera Culling" was only showing a "sliver" of content, instead of true "near to far distance of frustum" (was instead like distance 10 to 12, not 0.1 to 100 as I'd expect). So I nulled this out so that I could see more content.... and with 10,000 non-culled walking animated characters, I'm still running at 30 FPS.

najak3d commented 1 year ago

For me, FrustumCulling BUG exists for all scenes. The math "looks right" but for some reason isn't working for me. The computer shader's "signed_point_dist()" method isn't returning what I'd expect.

I tried toggling each Point's xyz (e.g. (-x, y, z), then (x, y, -z) then (z, y, x) ,etc) -- so see if maybe this was caused by some confusion of axes/polarity.

I'm using UNity3d 2021.3.1f16 as well as 2022.2.1f1. Both exhibit the same issue with Frustum culling.

mkrebser commented 1 year ago

I'm not able to repro this (in unity 2021.1). When I open the scenes the camera works as expected. eg, in crowddemo I am changing fov, near plane, far plane.

What are your camera settings/other changes to get it into this state?

To increase FPS, you can create less complex LODs. eg, all the least detailed LODs in in the skinned mesh characters will have around 200 vertices or less. They look horrible up-close- but far away it isn't noticeable

najak3d commented 1 year ago

I've narrowed it down to the 'cameraFrustum' Buffer. For some reason, the values we are setting in C# are not the same values being read by the Compute Shader.

I reduced the "outside_frustum_count()" method down to ONLY checking against the "Near" plane (meaning anything frontwards at all from camera would show up).... and this fails miserably.

To validate the rest of the logic, I then HARD-CODED the 2 values in the shader to the NearCenter and NearNormal that I'm setting in the C# from startup -- and THIS WORKS. Which leads me to conclude that the 'cameraFrustum' buffer is somehow corrupting the values.

I'm new to Unity Shader customizing/debugging -- so my methods here might be crude/ancient. I'm going to do some googling for tutorials for better methods to debug a compute shader, other than my very manual method. Mainly, I want to know what values are being read from this buffer.... all I've done so far is validate that "these values are NOT what I set from C#".

najak3d commented 1 year ago

I've found a few links on debugging shaders - what is your preferred method? (VStudio, or Unity RenderDocIntegration, or other?)

I tried to simply set values from the ComputeShader into a new RWBuffer called "cameraFrustum2" and read it back in C#... but for some reason this is failing inside your "instancemesh.compute" shader (note: it works if I create a separate shader that only does this; so not sure what it is about your compute shader that makes this not work for me).

najak3d commented 1 year ago

FIXED - via trial/error/experimentation.

For my setup, it only works if 'cameraFrustumBuffer' is a RWStructuredBuffer, instead of plain 'Buffer'.

RWStructuredBuffer cameraFrustumBuffer; //camera frustum buffer

When it's just a 'Buffer', the "Vector3.X" value becomes ALL values.... so if X = 1, then the Vec3 is (1, 1, 1). So my Plane Normals were either (x, x, x) or (-x, -x, -x).... yz values totally lost/ignored.

So the fix was literally just "one word change" from "Buffer" to "RWStructuredBuffer".

najak3d commented 1 year ago

Also confirmed that "StructuredBuffer" also works (the "RW" is not required here).

mkrebser commented 1 year ago

I've done some digging, it seems Buffer doesn't support vector types on some platforms (like most AMD GPUs for example) (which would explain why I cannot reproduce this issue 💯 )

StructuredBuffer should suffice instead (We don't need RW on this buffer since the entire buffer gets set before the kernel is invoked)

Wanna make a pull request?

najak3d commented 1 year ago

you wrote: "Wanna make a pull request?"

I haven't cloned your repo and am not set up for that here yet. For this "fix" it's only a 1 word change... making that one line read as:

StructuredBuffer<float3> cameraFrustumBuffer;

So my preference is for you to just make this first change on my behalf.

mkrebser commented 1 year ago

pushed fix, thanks for finding this issue and troubleshooting

najak3d commented 1 year ago

It's just a small thing compared to what you have already done for the rest of us!