naelstrof / SkinnedMeshDecals

An example of rendering decals on SkinnedMesh Renderers in Unity.
MIT License
155 stars 24 forks source link

decal painted on opposite side of mesh #14

Open Squisics opened 1 year ago

Squisics commented 1 year ago

Hi! First off, awesome project, I'd looked through the l4d developer notes and this was exactly what I needed.

I'm painting a blood decal on an animated character, and having an issue where:

The depth value I set (5) was big enough to encompass the whole model as otherwise I was getting harsh cut-off lines where the decal was being clipped, but now I'm getting this new issue.

Would you have any ideas how this could be happening or how I could fix it?

naelstrof commented 1 year ago

Do you have backface culling enabled on the projector material?

Squisics commented 1 year ago

hiya, yes that's ticked. it seems that as I increase the depth value, if that encompasses the back too it just favours the back side of the mesh if shooting from the character's front. (unity -z) image image

EDIT: After hammering it with tests, it does sometimes also paint on the desired side too but it 60-80% of the time paints on the undesired far side if I just leave it running in a loop. The example projects have the painters up close to the meshes and with a smaller (0.6) depth, which may be why this hasn't come up before? EDIT: Also I'm using URP if it helps.

naelstrof commented 1 year ago

May I see the code you're using to render the decal? I am doing some somewhat janky backface culling since I can't use the built-in (because I'm flattening it onto the screen to render the decal).

Here's the part of the projector that determines if it's a backface or not: image

It hasn't really mattered much in my tests if it misbehaved since I'm mostly using it for Splatoon goop. However it seems to work correct in all my test cases.

I'll have a better idea of what might be going wrong if I see some code snippets, though.

Squisics commented 1 year ago

sure, for testing I'm just running the code from the example in a timer against anything (including my character model from blender with import settings set as described in the readme), even just a simple primitive capsule with a skinned-mesh-renderer produces the same results, so this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using SkinnedMeshDecals;

public class decal_example_painter: MonoBehaviour{
    public Renderer rend;
    public Material mat;

    // args
    private Vector3 pos{get=> transform.position;}
    private Quaternion rot{get=> transform.rotation;}
    private Vector3 size{get=> transform.localScale;}
    public float depth= 0.6f;

    // timer
    private static float time_interval= 2f;
    private float time_next= 0;
    private void Start (){ time_cooldown(); }
    private void time_cooldown(){ time_next= Time.time +time_interval; }
    void Update (){
        if(Time.time >=time_next){time_cooldown();

            PaintDecal.RenderDecal(rend, mat, pos, rot, size, depth: depth);
        }
    }
}

...though you can ignore most of the extra code in there I guess. and its using the "PaintDecal.cs" and "DecalableInfo.cs" from your repository here.

If i put the target object at say 0,0,0 and the painter script on something at say 0,0,1.4 and rotate it to look at the thing it wants to paint (y180) ...then set the depth to really anything between 3-5+ and let it run i get the issue i described in URP.

I'm using the shaders from this repository, "DecalProjector" for the decal, and "DecalableLit" from the urp package included in the repository for the target skinned-mesh

And of course no worries! I totally appreciate getting it to work for whatever you need it to and moving on, and to some extent I can pretend it's an exit would or something instead xD but I just thought I'd get your help to laser in on what's happening maybe. I've not had much experience making shaders though so I'll have to learn more about that backface culling stuff, or reverse engineer the shader creation process you used, to get it to work I'm assuming, as you seem to be honing in on that as the source of the issue.