Use a projector to cull pixels with alpha transparency.

Here is a screenshot taken from a GDC on Left 4 Dead 2's wound simulation and its many experimental iterations:


https://postimg.cc/image/feah5kgnv/

How would one replicate this effect within Unity? I'm assuming that you could use a projector to map a texture onto a mesh and use that texture's transparency in a custom shader to cull pixels on both materials. If someone could point me in the right direction that would be much appreciated, I am quite inexperienced when it comes to writing shaders.

Thanks!

In unity there is no option to killing pixel by projector component.Instead of using projector you can painting with Raycast and store painting as texture by using RenderTexture.

then you can use it to cutting mesh parts by multiplying alpha channel

also you can use use vertex shader to cutting body parts
https://en.wikibooks.org/wiki/Cg_Programming/Unity/Cutaways

another approach to making mask is using stencil buffer
I made tutorial that will show you how you can use it

suppose we have skeleton model that we want to place In above mask

masking again!

Stencil mask is done!

Stencil that I used to making this effect:

Human:

        Stencil {
            Ref 1
            Comp NotEqual
        }

Mask:

        Stencil
        {
            Ref 1
            Comp Always
            Pass Replace
        }

Skeleton:

        Stencil {
            Ref 1
            Comp Equal
        }

some examples in different games:

Mortal Kombat 9 Komplete Edition:

Sniper Elite 4:

[quote=“Seyed_Morteza_Kamaly”, post:2, topic: 703102]
You can use stencil buffer to masking body part
This tutorial will show you how you can use it

[/quote]
Thank you!!

1 Like

@Seyed_Morteza_Kamaly ,

Hello i have use your Tutorial from here : https://gamedev.stackexchange.com/questions/152824/how-can-i-create-a-see-behind-walls-effect, for the behind the wall effect. That works great but i have a question on the wall Shader from that tutorial i can only give color and texture, is it possibel to bring in AO,Normal,Roughnes,Metalic,Height in that WallShader? Iam not good in Shaderprog, can you help me on that, i looking for the wall shader with the standard shader or is that not possibel?

Thx for your help :smile:

[quote=“Pandur1982”, post:4, topic: 703102]
@Seyed_Morteza_Kamaly ,

Hello i have use your Tutorial from here : https://gamedev.stackexchange.com/questions/152824/how-can-i-create-a-see-behind-walls-effect, for the behind the wall effect. That works great but i have a question on the wall Shader from that tutorial i can only give color and texture, is it possibel to bring in AO,Normal,Roughnes,Metalic,Height in that WallShader? Iam not good in Shaderprog, can you help me on that, i looking for the wall shader with the standard shader or is that not possibel?

Thx for your help :smile:
[/quote]
Hello Pandur1982 yes It’s possible
this is a standard shader with all properties:
just add stencil above of CGPROGRAM

Shader "Custom/Standard" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _EmissionColor("EmissionColor",Color) = (1,0,0,1)
        _Emission("Emission",Range(0,1)) = 0.0
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _GlossMap("GlossMap",2D) = "white"{}
        _Glossiness ("Smoothness", Float) = 0.5
        _Metallic ("Metallic", Float) = 0.0
        _AO("AO",2D) = "white"{}
        _NormalMap("NormalMap",2D) = "bump"{}
        _NormalMapIntensity("NormalMapIntensity",Range(1,5)) = 1.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
   
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows

        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
            float2 uv_Gloss;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        float4 _EmissionColor;
        float _NormalMapIntensity;
        float _Emission;
        sampler2D _GlossMap,_AO,_NormalMap;

        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness*tex2D(_GlossMap,IN.uv_MainTex);
            o.Alpha = c.a;
            o.Occlusion = tex2D(_AO,IN.uv_MainTex);
            o.Emission = _Emission * _EmissionColor;
            fixed3 n = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex)).rgb;
            n.x *= _NormalMapIntensity;
            n.y *= _NormalMapIntensity;
            o.Normal = normalize(n);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

Wall:

// Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax.

Shader "Custom/Wall" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _EmissionColor("EmissionColor",Color) = (1,0,0,1)
        _Emission("Emission",Range(0,1)) = 0.0
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _GlossMap("GlossMap",2D) = "white"{}
        _Glossiness ("Smoothness", Float) = 0.5
        _Metallic ("Metallic", Float) = 0.0
        _AO("AO",2D) = "white"{}
        _NormalMap("NormalMap",2D) = "bump"{}
        _NormalMapIntensity("NormalMapIntensity",Range(1,5)) = 1.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
Stencil
{
    Ref 1 // ReferenceValue = 1
    Comp NotEqual // Only render pixels whose reference value differs from the value in the buffer.
}
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows

        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
            float2 uv_Gloss;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        float4 _EmissionColor;
        float _NormalMapIntensity;
        float _Emission;
        sampler2D _GlossMap,_AO,_NormalMap;

        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness*tex2D(_GlossMap,IN.uv_MainTex);
            o.Alpha = c.a;
            o.Occlusion = tex2D(_AO,IN.uv_MainTex);
            o.Emission = _Emission * _EmissionColor;
            fixed3 n = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex)).rgb;
            n.x *= _NormalMapIntensity;
            n.y *= _NormalMapIntensity;
            o.Normal = normalize(n);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

Mask:

Shader "Custom/SimpleMask"
{
   Properties
   {
       _MainTex ("Texture", 2D) = "white" {}
       _CutOff("CutOff", Range(0,1)) = 0
   }
   SubShader
   {
       LOD 100
       Blend One OneMinusSrcAlpha
       Tags { "Queue" = "Geometry-1" }  // Write to the stencil buffer before drawing any geometry to the screen
       ColorMask 0 // Don't write to any colour channels
       ZWrite Off // Don't write to the Depth buffer
       // Write the value 1 to the stencil buffer
       Stencil
       {
           Ref 1
           Comp Always
           Pass Replace
       }

       Pass
       {
           CGPROGRAM
           #pragma vertex vert
           #pragma fragment frag

           #include "UnityCG.cginc"

           struct appdata
           {
               float4 vertex : POSITION;
               float2 uv : TEXCOORD0;
           };

           struct v2f
           {
               float2 uv : TEXCOORD0;
               float4 vertex : SV_POSITION;
           };

           sampler2D _MainTex;
           float4 _MainTex_ST;
           float _CutOff;

           v2f vert (appdata v)
           {
               v2f o;
               o.vertex = UnityObjectToClipPos(v.vertex);

               o.uv = TRANSFORM_TEX(v.uv, _MainTex);

               return o;
           }

           fixed4 frag (v2f i) : SV_Target
           {
               fixed4 col = tex2D(_MainTex, i.uv);
               float dissolve = step(col, _CutOff);
               clip(_CutOff-dissolve);
               return float4(1,1,1,1)*dissolve;
           }
           ENDCG
       }
   }
}

Big Thx for your answer, that help me a lot.That is a TopNotch Asset, i think you must bring it to the asset store, that can help many peopel for aTopDown Game.

I have change a littel on the Wall Shader for emissionsTexture :

// Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax.
Shader "Custom/Wall" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _EmissionColor("EmissionColor",Color) = (1,0,0,1)
        _Emission("Emission",Range(0,100)) = 0.0
        _EmissionMap("Emissive", 2D) = "black" {}
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _GlossMap("GlossMap",2D) = "white"{}
        _Glossiness ("Smoothness", Float) = 0.5
        _Metallic ("Metallic", Float) = 0.0
        _AO("AO",2D) = "white"{}
        _NormalMap("NormalMap",2D) = "bump"{}
        _NormalMapIntensity("NormalMapIntensity",Range(1,5)) = 1.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
Stencil
{
    Ref 1 // ReferenceValue = 1
    Comp NotEqual // Only render pixels whose reference value differs from the value in the buffer.
}
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0
        sampler2D _MainTex;
        struct Input {
            float2 uv_MainTex;
            float2 uv_Gloss;
        };
        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        float4 _EmissionColor;
        float _NormalMapIntensity;
        float _Emission;
        sampler2D _GlossMap,_AO,_NormalMap,_EmissionMap;
        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)
        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness*tex2D(_GlossMap,IN.uv_MainTex);
            o.Alpha = c.a;
            o.Occlusion = tex2D(_AO,IN.uv_MainTex);
            o.Emission = _Emission * _EmissionColor*tex2D(_EmissionMap,IN.uv_MainTex);
            fixed3 n = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex)).rgb;
            n.x *= _NormalMapIntensity;
            n.y *= _NormalMapIntensity;
            o.Normal = normalize(n);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

I think its good do bring more in that shader like Mask.Roughness and so one :smile:

1 Like

[quote=“Pandur1982”, post:6, topic: 703102]
Big Thx for your answer, that help me a lot.That is a TopNotch Asset, i think you must bring it to the asset store, that can help many peopel for aTopDown Game.

I have change a littel on the Wall Shader for emissionsTexture :

// Upgrade NOTE: upgraded instancing buffer 'Props' to new syntax.
Shader "Custom/Wall" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _EmissionColor("EmissionColor",Color) = (1,0,0,1)
        _Emission("Emission",Range(0,100)) = 0.0
        _EmissionMap("Emissive", 2D) = "black" {}
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _GlossMap("GlossMap",2D) = "white"{}
        _Glossiness ("Smoothness", Float) = 0.5
        _Metallic ("Metallic", Float) = 0.0
        _AO("AO",2D) = "white"{}
        _NormalMap("NormalMap",2D) = "bump"{}
        _NormalMapIntensity("NormalMapIntensity",Range(1,5)) = 1.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
Stencil
{
    Ref 1 // ReferenceValue = 1
    Comp NotEqual // Only render pixels whose reference value differs from the value in the buffer.
}
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0
        sampler2D _MainTex;
        struct Input {
            float2 uv_MainTex;
            float2 uv_Gloss;
        };
        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        float4 _EmissionColor;
        float _NormalMapIntensity;
        float _Emission;
        sampler2D _GlossMap,_AO,_NormalMap,_EmissionMap;
        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)
        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness*tex2D(_GlossMap,IN.uv_MainTex);
            o.Alpha = c.a;
            o.Occlusion = tex2D(_AO,IN.uv_MainTex);
            o.Emission = _Emission * _EmissionColor*tex2D(_EmissionMap,IN.uv_MainTex);
            fixed3 n = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex)).rgb;
            n.x *= _NormalMapIntensity;
            n.y *= _NormalMapIntensity;
            o.Normal = normalize(n);
        }
        ENDCG
    }
    FallBack "Diffuse"
}

I think its good do bring more in that shader like Mask.Roughness and so one :smile:
[/quote]

why not? I like to publish it in assetstore but I need your help to make it possible. :slight_smile:

Unity’s Standard shader has the smoothness stored in the alpha channel of the metal texture (or optionally the albedo).
I explained Roughness here:
https://gamedev.stackexchange.com/questions/153619/how-can-i-make-a-wet-surface-shallow-puddle-shader-in-unity/153620#153620

but anyway if you like to have o.Roughness you can use this:
https://gist.github.com/smkplus/17fea90de9215b1f8e1085912d9e11dc

1 Like

Thx for it, very usefull links, yes how can i help you to bring that on the asset store?

[quote=“Pandur1982”, post:8, topic: 703102]
Thx for it, very usefull links, yes how can i help you to bring that on the asset store?
[/quote]

I just need a list of features to Implement because I want to make the complete asset not a simple asset
can you send image from your Top Down game?

Hello Seyed_Morteza_Kamaly , sry for my late answer at the moment i have many work at time. On the 17.4. iam back at home and i can create a list for you and some images from my project.
Wish you a nice day , see you later.

1 Like

So iam Back at home, so here 2 screens from a testlevel with the mask action.

So and here a littel list for it :

  • Noise Mask
  • Basic Mask

  • Standard Shader

  • Untilt Texture Shader

  • Nature Shader (speed Tree...)

At the moment i work with Raycast and Layers, on the Camera is a Littel Quad Object with the Basic Mask when the Raycast hit a Object with Layer "BlockObjects" the Quad Object will set on when the Raycast no more hit a Object with Layer "BlockObjects" the Quad Bject will set off.

So i hope that help you.

[quote=“Pandur1982”, post:11, topic: 703102]
So iam Back at home, so here 2 screens from a testlevel with the mask action.

So and here a littel list for it :

  • Noise Mask

  • Basic Mask

  • Standard Shader

  • Untilt Texture Shader

  • Nature Shader (speed Tree…)

At the moment i work with Raycast and Layers, on the Camera is a Littel Quad Object with the Basic Mask when the Raycast hit a Object with Layer “BlockObjects” the Quad Object will set on when the Raycast no more hit a Object with Layer “BlockObjects” the Quad Bject will set off.

So i hope that help you.
[/quote]

Hi thanks for adding wish list I will check it out
it seems your games is fun :slight_smile:

1 Like

Thx, but at the moment i have not so mutch time for my project, from time to time i work on the player Controller