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

Resolved 2D animations, sprite sheets and Shader Graph workflow

Discussion in '2D' started by -Shimrod-, Sep 6, 2020.

  1. -Shimrod-

    -Shimrod-

    Joined:
    Jul 19, 2016
    Posts:
    5
    Hi,

    I apologize as this thread is basically a repost of mine here in the Shader Graph sub-section. I was thinking than the 2D section might be more appropriate and hope I'm not breaking any rules of the forum.


    I'm requesting here mostly guidelines than specific answers. :)

    In a personal self-teaching (and challenging !) approach, I'm trying to create a kind of 2D experience (a platformer, for instance) and I really am a newcomer in this field. So far, I have my controller and animator for a player character, I already created a few sprites sheets (from 3D renderings) and they work great, but I'd like to enhance these with additional passes, like normals to take profit of 2D lights, and probably more.

    Most of the examples I found about the Sprite Lit Graph are using the same pipeline :
    1 set of sprites sheets -> 1 shader -> 1 material
    These examples are 2D rigs or pixel art animation, where one character has its entire moveset in one sprite sheet, but I'm looking for HD visuals and not targeting mobile.

    In my case, I use 1 spritesheet for 1 animation, all linked in my animator, which I think is a traditionnal approach.

    How should I create a set of animations, each using through SG a comp of beauty renders + normal + ... + etc. ?
    I don't really get how to input a specific set of frames (ie: walking_beauty_xxx + walking_normal_xxx or jump_beauty_xxx + jump_normal_xxx) depending of the animation running at a time.

    Thanks for reading and for your clues. ;)


    For the background :
    I'm a 3D artist and not a developer/technical artist/etc., so I'm mostly skilled in modeling, texturing, and rendering/compositing pictures and short movies. In the past few years, I've used Unity for a few projects, mostly VR experiences with animated assets and characters and I really enjoy what the engine offers. But my main skills here are more in creating content and delivering a working product than coding from scratch, although I can now read and write some at a basic level.
     
    AtomicIsland likes this.
  2. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,315
    The first thing is you need to be able to supply the normal map and other textures to the shader/material. The intended workflow is to make use of Secondary Textures. These are "parallel" textures to the main texture (_MainTex).

    https://docs.unity3d.com/Manual/SpriteEditor-SecondaryTextures.html
    https://github.com/Unity-Technologies/2d-renderer-samples

    This is as simple as selecting the Secondary Texture dropdown in SpriteEditor and labeling it _NormalMap. This then gives you access to it from Shader Graph if you a Texture2D's Reference field on the Blackboard is "_NormalMap".

    https://docs.unity3d.com/Packages/com.unity.shadergraph@8.1/manual/Blackboard.html

    You can make your own textures and give them their own "_TextureName" and access that from the Shader Graph blackboard, e.g. Emissive, Metallic - whatever beautifying textures you want.

    If you are using a spritesheet with a secondary textures for that same sheet, these secondary textures should automatically be made available to your Shader by virtue of being "parallel" to your _MainTex. So going from frame 1 to frame 2 of a spritesheet requires no more effort than making sure your normal and main texture are aligned, which shouldn't be difficult in any image editing software: keep them on separate layers and export them separately into Unity. Be sure in the Texture Importer settings you set it appropriately for whatever it is.
     
    Last edited: Sep 6, 2020
    -Shimrod- likes this.
  3. -Shimrod-

    -Shimrod-

    Joined:
    Jul 19, 2016
    Posts:
    5
    Thanks for your answer. I already set my animation cycles with references to _MainTex and _NormalMap from the same multiple Sprite using secondary texture, and it works like a charm in Shader Graph.

    But my main concern is that I eventually end up with a shader "Idle", a shader "Walk", a shader "Jump", etc., each of one composed of the corresponding _MainTex and _NormalMap cycles.

    I don't see the link with the animation clips and the animator and this is where I'm confused... T_T
     
  4. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,315
    The beauty of _NormalMap and _MainTex is that it'll automatically collect those and supply it to your shader without you needing separate materials per texture change. You can have one Material for different spritesheets. What sprites you're setting to the SpriteRenderer determines what spritesheets and their secondary textures are sent over.

    From animation clip/animator perspective, you shouldn't need to think about it. This should be automatic and in the background. When you change states in animator and play through a different spritesheet on the SpriteRenderer, it should automatically supply things correctly, accessible in your shader.
     
    -Shimrod- likes this.
  5. -Shimrod-

    -Shimrod-

    Joined:
    Jul 19, 2016
    Posts:
    5
    Aaaaah that's the point I didn't figure out !! I quickly tested it and it works. So basically, the cycle (beauty + normal) I use to create my shader acts as a placeholder, as it will be updated by the animator.
    I was so focused on the usual way of creating a material (purposely selecting the input) that I didn't even think of that. These mechanics are yet quite new to me.

    So, if I get it right (and for further readers, if necessary) :
    - comp passes in Sprite Editor, with correct references for the Secondary Textures
    - create animation clips in the usual way from the multiple sprites
    - take one of these to create the shader and the material and assign it to the sprite renderer.
    - the animator will update the input sprites depending on the state.

    Thank you so much Lo-renzo, that's really helpful. :)
     
    ASK3R likes this.