guycalledfrank / bakery-issues

Bug tracker for Bakery
4 stars 0 forks source link

Alpha Meta Pass doesn't work properly for objects with Scale In Lightmap 0 #136

Closed originomeg closed 2 years ago

originomeg commented 2 years ago

Current behaviour: image

Expected result (i return 1 - texture.alpha in Alpha Meta Pass just to get a different shadows than in default bake behaviour without Alpha Meta Pass): image

Default behaviour without Alpha Meta Pass: image

Shader Code:

Shader "MyShader/AlphaTest"
{
    Properties
    {
        _MainTex("", 2D) = "white" { }

        [HideInInspector] BAKERY_META_ALPHA_ENABLE("Enable Bakery alpha meta pass", Float) = 1.0
    }

    SubShader
    {
        Tags { "RenderType" = "TransparentCutout" "Queue" = "Geometry" }
        LOD 200

        Pass
        {
            Tags { "LightMode" = "Always" }
            ColorMask 0

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            sampler2D   _MainTex;

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

            v2f vert(in float3 vertex : POSITION, in float2 uv : TEXCOORD0)
            {
                v2f o;
                o.vertex =  UnityObjectToClipPos(vertex);
                o.uv = uv;
                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                clip(tex2D(_MainTex, i.uv).a - 0.5);
                return 0;
            }
            ENDHLSL
        }

        Pass
        {
            Tags { "LightMode" = "ForwardBase" "OnlyDirectional" = "True" }
            ZTest Equal
            ZWrite Off

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            sampler2D _MainTex;

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

            v2f vert(in float3 vertex : POSITION, in float2 uv : TEXCOORD0)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(vertex);
                o.uv = uv;
                return o;
            }

            float4 frag(v2f i) : SV_Target
            {
                return float4(tex2D(_MainTex, i.uv).rgb, 1);
            }
            ENDHLSL
        }

        Pass
        {
            Name "META_BAKERY"
            Tags { "LightMode" = "Meta" }
            Cull Off

            HLSLPROGRAM
            #pragma vertex vert_meta
            #pragma fragment frag_meta
            #include "UnityCG.cginc"
            #include "UnityMetaPass.cginc"

            sampler2D   _MainTex;

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

            v2f vert_meta(in float4 vertex : POSITION, in float2 uv : TEXCOORD0)
            {
                v2f o;
                o.vertex = UnityMetaVertexPosition(vertex, uv, uv, unity_LightmapST, unity_DynamicLightmapST);
                o.uv = uv;
                return o;
            }

            float4 frag_meta(v2f i) : SV_Target
            {
                UnityMetaInput o;
                UNITY_INITIALIZE_OUTPUT(UnityMetaInput, o);

                if (unity_MetaFragmentControl.w)
                {
                    // Just to get a different shadows than in default 
                    // bake behaviour without Alpha Meta Pass
                    return 1 - tex2D(_MainTex, i.uv).a;
                }

                return UnityMetaFragment(o);
            }
            ENDHLSL
        }
    }
}
guycalledfrank commented 2 years ago

Yeah, it's expected :)

Meta pass is always rasterized in lightmap resolution, that's the idea. This is how Unity supplies all scene material data to the lightmappers.

Alpha meta pass extends the same technology with an additional alpha value. I also have an additional multiplier specifically for alpha meta pass resolution, so it can be 2x, 4x, etc larger than the lightmap.

When your scale in lightmap is 0, you have a zero-sized lightmap, so the meta pass is zero-sized as well. In this case Bakery supplies material albedo/emission per-vertex, and meta-alpha is just omitted.

Non-meta alpha always works because it doesn't rely on the meta pass. It uses the actual UV0 and the actual full-resolution alpha maps.

originomeg commented 2 years ago

Thanks for your explanation.