naelstrof / SkinnedMeshDecals

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

Decaled normal maps #8

Open iatenothingbutriceforthreedays opened 2 years ago

iatenothingbutriceforthreedays commented 2 years ago

Hey, not really an issue but I wanted to be able to decal normal maps for bullet holes, I modified DecalableLit.shader to make that possible, it's not a huge change but it took me a while to figure out and it must be a common use-case so it might be useful to have it as a built-in example. Let me know if you're interested in a PR, I can clean up my changes and make sure it works in HDRP and URP as well (i am using the built-in pipeline). I could also add some convenience methods to PaintDecal.cs to allow for painting the color + normal decals in one call.

naelstrof commented 2 years ago

Oh yeah that sounds great, you don't have to go through the effort of making sure it supports all pipelines-- a simple example would be awesome!

damiannnnnn commented 2 years ago

Hey, not really an issue but I wanted to be able to decal normal maps for bullet holes, I modified DecalableLit.shader to make that possible, it's not a huge change but it took me a while to figure out and it must be a common use-case so it might be useful to have it as a built-in example. Let me know if you're interested in a PR, I can clean up my changes and make sure it works in HDRP and URP as well (i am using the built-in pipeline). I could also add some convenience methods to PaintDecal.cs to allow for painting the color + normal decals in one call.

@iatenothingbutriceforthreedays hi!, I'm trying to do the same thing as you ... I'm trying to create a normal map with the texture of the decal, but I can't get it to look correctly on the character's mesh. I would like to know what you did to get the decal to display correctly with normal maps.

iatenothingbutriceforthreedays commented 2 years ago

hey @damiannnnnn i apologize for the really late reply - after i posted i realized that my solution didn't work as well as I thought it did, which is why i never pushed the change. I modified DecalableLit.shader to look like this:

            float4 baseColor = tex2D( _BaseColorMap, i.uv_BaseColorMap ) * _BaseColor;
            float4 decalColor = tex2D( _DecalColorMap, i.uv2_DecalColorMap); // tex2Dlod( _DecalColorMap, float4( i.uv2_texcoord2, 0, 0.0) );
            float4 mixedColor = lerp(baseColor, decalColor, decalColor.a);
            o.Albedo = mixedColor.rgb;

            float3 baseNormal = UnpackNormalWithScale(tex2D(_NormalMap, i.uv_BaseColorMap), _NormalScale);
            float4 decalNormal = tex2D( _DecalNormalMap, i.uv2_DecalColorMap);
            // float3 decalNormal = UnpackNormalWithScale(decalNormalPacked, _NormalScale);
            float3 mixedNormal = lerp(baseNormal, decalNormal, decalNormal.a*_DecalNormalStrength);
            o.Normal = mixedNormal;

And then for each impact make two calls to SkinnedMeshDecals.PaintDecal.RenderDecal:

decalProjector.SetTexture("_Decal", bulletHoleFleshColor);
SkinnedMeshDecals.PaintDecal.RenderDecal(decalProjector, ..., "_DecalColorMap");
decalProjector.SetTexture("_Decal", bulletHoleFleshNormal);
SkinnedMeshDecals.PaintDecal.RenderDecal(decalProjector, ..., "_DecalNormalMap");

But I realized that normal textures are stored ('packed') differently to color textures, and I'm not sure I was using 'UnpackNormalWithScale' correctly. It did look fine for small bullet holes but there were some minor artifacts IIRC. I never had time to look into it more.

Hope that helps a little.

damiannnnnn commented 2 years ago

Hi @iatenothingbutriceforthreedays , thanks for the change! I'll try it in the next few days! Thank you very much for answering!!