AnyPortrait > Scripting > Custom Shader

Custom Shader

It is a way to create and use the shader yourself, not the shader provided by AnyPortrait.

Please refer to the related page for how to apply and bake custom shaders.

There are two ways to write shader code depending on whether you have a clipping mask or not.

How to create a basic shader

Shader "Custom Shader/Sample Transparent"
{
           Properties
           {
                      _Color("2X Color (RGBA Mul)", Color) = (0.5, 0.5, 0.5, 1.0)
                      _MainTex("Main Texture (RGBA)", 2D) = "white" {}
           }
           

           SubShader
           {
        

                      Tags { "RenderType" = "Transparent" "Queue" = "Transparent" "PreviewType" = "Plane" }
                      Blend SrcAlpha OneMinusSrcAlpha

                      LOD 200

                      

                      CGPROGRAM
        

                      #pragma surface surf SimpleColor alpha

                      #pragma target 3.0

                      half4 LightingSimpleColor(SurfaceOutput s, half3 lightDir, half atten)
                      {
                                 half4 c;
                                 c.rgb = s.Albedo;
                                 c.a = s.Alpha;
                                 return c;
                      }

 

                      half4 _Color;
                      sampler2D _MainTex;

        

                      struct Input
                      {
                                 float2 uv_MainTex;
                                 float4 color : COLOR;
                      };

                      

                      void surf(Input IN, inout SurfaceOutput o)
                      {
                                 half4 c = tex2D(_MainTex, IN.uv_MainTex);


                                 c.rgb *= _Color.rgb * 2.0f;

                                 o.Alpha = c.a * _Color.a;
                                 o.Albedo = c.rgb;
                      }
                      ENDCG
           }
}

 

1. Properties

_Color("2X Color (RGBA Mul)", Color) = (0.5, 0.5, 0.5, 1.0)

_MainTex("Main Texture (RGBA)", 2D) = "white" {}

By default, AnyPortrait uses only two properties.

Declare _Color property for color animation and _MainTex property to apply texture.

Externally controlling these two properties may conflict with the logic of AnyPortrait.

2. Blending

Blend SrcAlpha OneMinusSrcAlpha : Alpha Blend

Blend One One : Additive

Blend OneMinusDstColor One : Soft Additive

Blend DstColor SrcColor : Multiplicative

 

Four blending methods used in AnyPortrait.

You can write as above or make other blending declarations as needed.

3. Albedo, Alpha

half4 c = tex2D(_MainTex, IN.uv_MainTex);


c.rgb *= _Color.rgb * 2.0f;

o.Alpha = c.a * _Color.a;
o.Albedo = c.rgb;

The color calculation applies 2X Multiply by default.

RGB is doubled, and Alpha is multiplied and applied.

You can change it as needed, but it may appear different from the render results in the editor.

How to Create a Clipping Mask Shader

Shader "Custom Shader/Sample Clipping Transparent"
{
           Properties
           {
                      _Color("2X Color (RGBA Mul)", Color) = (0.5, 0.5, 0.5, 1.0)
                      _MainTex("Base Texture (RGBA)", 2D) = "white" {}
                      _MaskTex("Mask Texture (A)", 2D) = "white" {}
                      _MaskScreenSpaceOffset("Mask Screen Space Offset (XY_Scale)", Vector) = (0, 0, 0, 1)
           }

           

           SubShader
           {
                      Tags{ "RenderType" = "Transparent" "Queue" = "Transparent" "PreviewType" = "Plane"}
                      Blend SrcAlpha OneMinusSrcAlpha
                      LOD 200

        

                      CGPROGRAM
                      #pragma surface surf SimpleColor alpha

                      #pragma target 3.0

                      half4 LightingSimpleColor(SurfaceOutput s, half3 lightDir, half atten)
                      {
                                 half4 c;
                                 c.rgb = s.Albedo;
                                 c.a = s.Alpha;
                                 return c;
                      }

 

                      half4 _Color;
                      sampler2D _MainTex;
                      sampler2D _MaskTex;
                      float4 _MaskScreenSpaceOffset;

        

                      struct Input
                      {
                                 float2 uv_MainTex;
                                 float4 screenPos;
                                 float4 color : COLOR;
                      };

                      

                      void surf(Input IN, inout SurfaceOutput o)
                      {
                                 half4 c = tex2D(_MainTex, IN.uv_MainTex);
 

                                 c.rgb *= _Color.rgb * 2.0f;

                                 float2 screenUV = IN.screenPos.xy / IN.screenPos.w;
            

                                 screenUV -= float2(0.5f, 0.5f);

                                 screenUV.x *= _MaskScreenSpaceOffset.z;
                                 screenUV.y *= _MaskScreenSpaceOffset.w;

                                 screenUV.x += _MaskScreenSpaceOffset.x * _MaskScreenSpaceOffset.z;
                                 screenUV.y += _MaskScreenSpaceOffset.y * _MaskScreenSpaceOffset.w;                                                                     screenUV += float2(0.5f, 0.5f);

                                 float mask = tex2D(_MaskTex, screenUV).r;


                                 c.a *= mask;

                                 o.Alpha = c.a * _Color.a;
                                 o.Albedo = c.rgb;
                      }
                      ENDCG
           }
}

1.Properties

_MaskTex("Mask Texture (A)", 2D) = "white" {}

_MaskScreenSpaceOffset("Mask Screen Space Offset (XY_Scale)", Vector) = (0, 0, 0, 1)

Add a mask texture to the property for clipping mask processing.

AnyPortrait automatically handles the clipping rendering by adding the above properties.

_MaskScreenSpaceOffset is a property for applying the clipping mask relative to the screen space (screen space).

2. Screen Space Semantic

struct Input

{

           float2 uv_MainTex;

           float4 screenPos;

           float4 color : COLOR;

};

The clipping mask is processed in the screen space.

Therefore, you must pass the screenPos variable used by Unity to the Fragment Shader or the Surface Shader.

3. Mask

float2 screenUV = IN.screenPos.xy / IN.screenPos.w;

            
screenUV -= float2(0.5f, 0.5f);

screenUV.x *= _MaskScreenSpaceOffset.z;
screenUV.y *= _MaskScreenSpaceOffset.w;

screenUV.x += _MaskScreenSpaceOffset.x * _MaskScreenSpaceOffset.z;
screenUV.y += _MaskScreenSpaceOffset.y * _MaskScreenSpaceOffset.w;                                                                    screenUV += float2(0.5f, 0.5f);

float mask = tex2D(_MaskTex, screenUV).r;


c.a *= mask;

An expression that calculates the clipping mask and applies it to the alpha channel.

This expression must be written in the same way to be processed normally.