Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question DOOMSprite-Like effect for 3D Models

Discussion in 'Shader Graph' started by Sluggy, Sep 29, 2023.

  1. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    820
    I have a version of this working that uses render textures and cameras to essentially render 3D models to a section of a texture and then map the UVs back to their associated entity's quads. Then a simple script can force the quad to rotate on the Y-axis to face the camera. The 3D models are also rotated at quantized angles relative to the player's view so that they appear to be actual hand drawn 8-way sprites and not just low resolution renders of 3D objects. Works well enough but the performance gets hit pretty hard once I start to put a few hundred of these '3D sprites' on the screen since I'm now rendering many camera to many 2k RenderTextures.

    Instead, I'd like to get the effect working via shader to help improve the performance so that I can really push the number of characters on the screen.

    So far I've managed to hobble together something that gets me the billboarded look for the 3D model but I'm stuck trying to figure out how to apply the object transforma's y-rotation in order to rotate it within the shader. I have a subgraph that will supposedly help get access to the local rotation but I'm not actually sure where to apply that rotation.

    The sub-graph for the billboard itself looks like the following and gets plugged directly into the vertex position.
    billboard_shadergraph.PNG

    And the effect it gives looks pretty good so far.
    billboard.gif


    All I need to do is to figure out how to apply a rotation around y-axis and then I can start working on the next step which is to get the rotation relative to the view and quantize it. Any help with this step would be greatly appreciated.
     
  2. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    820
    The amazing thing about having a job that requires no brains and has you standing in one-spot for twelve hours straight doing absolutely nothing: You can solve problems in your head while you wait for nothing...

    Anyway, the solution was actually really really simple. I just had to multiply the object's transform's y-axis rotation with the result of the Rotation matrix rather than simply with the vert positions. A few adjustments later and I have a nice modular graph that allows me to plug in different billboarding algorithms as well as handle an easily adjustable rotation quantizer.

    billboard2.gif
     
  3. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,799
    I'm not sure you realize, because I haven't found any reference to it, but I think you're reinventing the thing called "impostors", objects' image taken from different angles stored on atlases and shown by shader in relation to the camera and the object supposed position.
    Anyway, if you weren't aware, here are some of those systems for reference:

    https://assetstore.unity.com/packages/tools/utilities/impostors-runtime-optimization-188562
    https://assetstore.unity.com/packages/tools/utilities/amplify-impostors-119877 (my favorite)
    Or free ones to be able to learn from them:
    https://github.com/hyjzRef/SimpleImposter
    https://github.com/hickVieira/URPIMP

    And great job!
     
  4. Sluggy

    Sluggy

    Joined:
    Nov 27, 2012
    Posts:
    820
    Thanks for the words of encouragement! And the links, they might be helpful later.

    I did want to clarify one important detail though. This isn't an imposter system. I'm not prerendering to a texture and then using that. This is the actual 3D model being projected in a way as to appear to be a 2D sprite billboard in 3D space. Effectively, I want to get that mid-to-late 90s aesthetic look of prerendered sprites but with all of the accoutrements of a proper 3D model so that I can use stuff like cloth physics, animation blending, lighting and shadows. The next part is the hard one, I need to find a way to render this object at a lower resolution but in a pixel-stable way. Like I said before I was able to do this by rendering to a texture and then rendering that to a quad but I was loosing out on stuff like cloth physics (because the real 3d model never moved, only rotated in place) and proper lighting ( again, because the real model stayed in a fixed place in the scene). It was also killing performance when I had more than 500 of these on screen since I would 3nd up with close to a dozen off-screen cameras! With this shader though I'm one step closer to solving all of those issues I hope. Wish me luck, if I get it cracked I post here again.