Spriter: Real-Time Sprite Imposter System

Discuss modding questions and implementation details.
User avatar
MasonFace
Posts: 543
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: Spriter: Real-Time Sprite Imposter System

Post by MasonFace »

Thanks! I've been meaning to get back on this project, but it will require that I get more familiar with DFTU and have some models available for testing. Kamer has been very generous in letting me use his Flesh Golem model (viewtopic.php?f=14&t=1580&start=50#p22031) for testing, but I haven't had a chance to do much with it yet.

As for Theseus3000, I understand that he's been MIA for years and his models were never released.

SubPixel-Chris
Posts: 5
Joined: Mon May 13, 2019 12:19 am

Re: Spriter: Real-Time Sprite Imposter System

Post by SubPixel-Chris »

#want ( for more than DFU ) lmao this looks great.

HeadClot
Posts: 11
Joined: Wed Jul 29, 2015 9:11 am

Re: Spriter: Real-Time Sprite Imposter System

Post by HeadClot »

Hey masonface,

I have a few questions for you -
1. Is Spriter compatible with the 2018 LTS releases?
2. How much or what would I need to do for an early copy of Spriter for a non-Daggerfall Unity project?
3. Are animation states supported in Spriter yet?

User avatar
MasonFace
Posts: 543
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: Spriter: Real-Time Sprite Imposter System

Post by MasonFace »

1. Is Spriter compatible with the 2018 LTS releases?
Yes. Any version of Unity that supports render textures will work.
2. How much or what would I need to do for an early copy of Spriter for a non-Daggerfall Unity project?
All you need is patience and to be willing to provide testing feedback.

The thing I had been struggling with before I decided to take a break from the project is getting two objects next to each other without rendering into each other's render texture. I think I will write some sort of singleton manager script to control the render texture update so no two sprites update on the same frame. If you're willing to work within this constraint in the meantime, then I could have the alpha packaged and available within a few weeks as I get time.
3. Are animation states supported in Spriter yet?
Yes, but this is also a little buggy. Each frame, the camera that renders the 3D model is panning and zooming to capture the extents of the renderer's bounding box, this way it captures only as many pixels as it needs to draw the sprite, consumes less VRAM, and reduces overdraw.

I have found that in cases where the 3D model's bounding box doesn't accurately capture the extents of the model for each frame of the animation, the resulting sprite doesn't capture the whole model.


So yeah, basically it's still rough around the edges. If you're okay with these current flaws, then I can have a package ready hopefully within a few weeks. I still need to create some documentation on how to use it and I'd like to add a tool in the Unity editor to "Add Spriter Component" to make it easier, but I may not have all that ready. Just ping me later on (just PM me) if you haven't heard from me to remind me. All I ask from you is to provide feedback and to not redistribute the code.
Last edited by MasonFace on Thu Jul 11, 2019 7:42 pm, edited 2 times in total.

HeadClot
Posts: 11
Joined: Wed Jul 29, 2015 9:11 am

Re: Spriter: Real-Time Sprite Imposter System

Post by HeadClot »

Check your PMs Masonface :)

User avatar
TheLacus
Posts: 1305
Joined: Wed Sep 14, 2016 6:22 pm

Re: Spriter: Real-Time Sprite Imposter System

Post by TheLacus »

MasonFace, I'm working on support for providers of mobile npcs to replace classic billboards. I remembered about this topic and wanted to let you know. 😉

Rumpiluren
Posts: 2
Joined: Fri Jan 03, 2020 3:44 pm

Re: Spriter: Real-Time Sprite Imposter System

Post by Rumpiluren »

Mason, would you mind doing a rough rundown on how you managed to achieve this? I've been wanting to make something quite similar to what you are doing here, and I'd greatly appreciate any tips you can throw my way.

User avatar
MasonFace
Posts: 543
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: Spriter: Real-Time Sprite Imposter System

Post by MasonFace »

Mason, would you mind doing a rough rundown on how you managed to achieve this?
Sure thing!

I was originally planning on selling this on the Unity Asset Store, but I realize now that I don't have nearly enough time to support it, so I'm just going to release what I have. Feel free to reverse engineer it, but I warn you in advance that the programming is a bit messy (I'm by no means a professional).

Below is a link to the latest packaged version of "SpriteWrite."

SpriteWrite V0.4

---------------------------------------------------------------------

I'll give you an overview of how it works below:

The main idea is that a camera on the object generates a render texture "selfie" of itself, then displays that render texture onto a quad. The player's camera culling mask is set to see the quad, but not the 3D object.

The 3D model that we want to capture as a sprite (let's call this object the subject) has a camera attached to it that is about a meter away, facing the subject, and pivots around the subject's center. Think of it like a selfie stick. The allowed angles arrayed around the subject are limited by script to give it that old school "snap" into discrete view angles.

This "subject camera" is set to only be able to see objects that are in a specific layer which I named "3D Models". The camera is set to orthographic projection and clear flags to "solid color" with the color being black with zero alpha ( rgba = (0,0,0,0) ) so that everything that a camera doesn't see gets drawn as fully transparent color. A script that is placed on the subject game object will read the render bounds and set the size and proportions of the camera to capture as much of the subject in the camera's view while trimming out as many empty pixels as possible. This also includes setting the near and far clipping planes correctly.

We also have a quad that is a child of the parent subject that will rotate about the Y axis to face the player at all times (billboard) and will have its texture replaced with the render texture "selfie" that the subject generated on that frame. This quad will be set to a layer named "2D Model". Again, the main camera can see objects on the "2D Model" layer, but not objects on the "3D Model" layer.

All this is also done only on specific frames depending on the chosen FPS (frames per second) parameter in the main script. So if the user selects 8 frames per second, the subject updates its render texture every 0.125 seconds. However, if the player moves to view the subject from another discrete view angle, then it will update the render texture, regardless of the previously mentioned schedule.

Whenever it's time to update the render texture, the subject game object is moved to the "3D Models" layer. Any frame that it's not updating the render texture, the subject is moved and kept on a layer named "Invisible" which no camera can see based on their culling mask settings. Because of this scheme, you only have the CPU/GPU load of the mesh renderer for the 1 frame where the render texture is being updated. The downfall is that you will have an extra draw call for every sprite since they each have their own unique texture.

---------------------------------------------------------------------

Caveats:

As I mentioned above, each sprite will generate a draw call since they don't share the same texture. I've considered making a sprite atlas of sorts using a large render texture created from all the selfies and having the individual sprites reference an index of that texture instead. Then many sprites can share the same texture and they would combine to one draw call. But that gets complicated fast and I don't know that it would help performance much in many cases.

Another issue is that if all the sprites have the same "FPS" value, then all the subject objects will try to update their render textures at the same time. If you have lots of sprite objects, then you could get a big spike in CPU/GPU load on the frame that all the sprite objects are updating.

A bigger issue is what happens when two subjects are close enough to each other that when they update their render textures, one of their "selfie cameras" sees the other object. This will cause artifacts where one (or sometimes both) of the resulting sprites has parts of the other subject visible in it.

There could be multiple solutions to this problem, but I chose to create a manager script that manages which game object gets to update it's render texture each frame. Each subject sends a request to this manager when it's time to update its render texture and the manager adds that game object to a Queue. At the end of each frame, the manager takes the game object on the top of the list and sends it a message to allow that subject to update its render texture. This effectively solves the two prior problems above since it spreads out the update over multiple frames, but it introduces another problem: no sprite object updates at the same time, which can look a bit odd sometimes. I plan on fixing this with a more sophisticated update management scheme, but what I have works for my intended purposes for now.

Anyhow, that's the rundown. Feel free to contact me if you have any other questions!

Rumpiluren
Posts: 2
Joined: Fri Jan 03, 2020 3:44 pm

Re: Spriter: Real-Time Sprite Imposter System

Post by Rumpiluren »

Snap! This is far more than I had hoped for. Thanks! Really appreciate it. :D

User avatar
MasonFace
Posts: 543
Joined: Tue Nov 27, 2018 7:28 pm
Location: Tennessee, USA
Contact:

Re: Spriter: Real-Time Sprite Imposter System

Post by MasonFace »

No problem! Let me know if you need more information on how it works or if you run into any issues.

And keep me posted if you make something cool with it! I'm currently using it on a retro FPS as a side project, but I've been recently struck with a creative block... trying to get more inspiration before I dive in too deep.

Post Reply