Unity - Shader Graph 中的 Flipbook 节点算法BUG - Unity_Flipbook_float

141 篇文章 36 订阅
50 篇文章 2 订阅


环境

Unity : 2020.3.37f1


原因

比如,我有
flipx : 10,
flipy : 4,
flipidx : 10 (其实是编号,不是索引)

应该是采样到是 10 的位置
到时结果采样到的是:20 的位置


解决

在这里插入图片描述


Shader

// jave.lin 2022/12/15 Unlit, Texture, Fog toggle, Flipbook
// 优化点:props 中 _FlipX, _FlipY, _FlipIDX 都可以合并在一 vector
// 优化点:props 中 _FogIntensity, _ClampBrightness 都可以合并在一 vector

Shader "Game/Unlit_Tex_FogToggle_Flipbook"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
		_FlipX ("Flip X", Int) = 1
		_FlipY ("Flip Y", Int) = 1
		_FlipIDX ("Flip IDX", Int) = 1
        [HDR] _Color ("Color", Color) = (1, 1, 1, 1)
		//[Toggle(_IS_FOG_ON)] _IS_FOG_ON ("Is Fog On", Float) = 1
		[Toggle] _IS_FOG_ON ("Is Fog On", Float) = 1
        _FogIntensity ("Fog Intensity", Range(0, 1)) = 1
        [Toggle] _ClampBrightness ("Clamp Brightness", Int) = 0

		[Header(DrawState)]
		//[HideInInspector] _Mode ("__mode", Float) = 0.0
		[Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull Mode", Float) = 2
		[Enum(Off, 0, On, 1)] _ZWrite("ZWrite", Float) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Src Blend Mode", Float) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Dst Blend Mode", Float) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        Pass
        {
            Blend [_SrcBlend] [_DstBlend]
            ZWrite [_ZWrite]
            Cull [_Cull]
            CGPROGRAM
	        #pragma skip_variants FOG_EXP FOG_EXP2

            //#pragma multi_compile_fog
            //#define INSTANCING_ON
            //#define UNITY_INSTANCING_ENABLED
            #define FOG_LINEAR

            //#pragma shader_feature _ _IS_FOG_ON
            #pragma multi_compile _ _CURVE_WORLD_ON
            #pragma multi_compile_instancing
            
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"
            #include "UnityInstancing.cginc"
            #include "Assets/Art/Shaders/CurveWorldLib.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                //#ifdef _IS_FOG_ON
                    UNITY_FOG_COORDS(1)
                //#endif
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            sampler2D _MainTex;

            UNITY_INSTANCING_BUFFER_START(Props)
            
                UNITY_DEFINE_INSTANCED_PROP(int, _IS_FOG_ON)

                //UNITY_DEFINE_INSTANCED_PROP(float4, _MainTex_ST)
	            UNITY_DEFINE_INSTANCED_PROP(int, _FlipX)
	            UNITY_DEFINE_INSTANCED_PROP(int, _FlipY)
	            UNITY_DEFINE_INSTANCED_PROP(int, _FlipIDX)
                UNITY_DEFINE_INSTANCED_PROP(half4, _Color)
                UNITY_DEFINE_INSTANCED_PROP(half, _FogIntensity)
                UNITY_DEFINE_INSTANCED_PROP(half, _ClampBrightness)

            UNITY_INSTANCING_BUFFER_END(Props)

            v2f vert (appdata v)
            {
                v2f o = (v2f)0;

                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_TRANSFER_INSTANCE_ID(v, o);

                float4 posWorld = mul(UNITY_MATRIX_M, v.vertex);
                CURVE_WORLD_APPLY(posWorld.xyz, v.vertex.xyz)

                o.vertex = UnityObjectToClipPos(v.vertex);

                //o.uv = TRANSFORM_TEX(v.uv, UNITY_ACCESS_INSTANCED_PROP(Props, _MainTex));

                o.uv = v.uv;

                //#ifdef _IS_FOG_ON
                    UNITY_TRANSFER_FOG(o,o.vertex);
                //#endif
                return o;
            }
	        void Unity_Flipbook_float(float2 UV, float Width, float Height, float Tile, float2 Invert, out float2 Out)
	        {
		        Tile = fmod(Tile, Width * Height);
		        float2 tileCount = float2(1.0, 1.0) / float2(Width, Height);
		        float tileY = abs(Invert.y * Height - (floor(Tile * tileCount.x) + Invert.y * 1));
		        float tileX = abs(Invert.x * Width - ((Tile - Width * floor(Tile * tileCount.x)) + Invert.x * 1));
		        Out = (UV + float2(tileX, tileY)) * tileCount;
	        }
            // https://forum.unity.com/threads/flipbook.1324218/
            void Unity_Flipbook_float_FIXED(float2 UV, float Width, float Height, float Tile, float2 Invert, out float2 Out)
            {
                Tile = floor(fmod(Tile + float(0.00001), Width*Height));
                float2 tileScale = float2(1.0, 1.0) / float2(Width, Height);
                float x = floor((Tile + float(0.5)) * tileScale.x);
                float tileX = (Tile - Width * x);
                float tileY = (Invert.y * Height - (x + Invert.y * 1));
                Out = (UV + float2(tileX, tileY)) * tileScale;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                UNITY_SETUP_INSTANCE_ID(i);

				float2 flipbook_uv = 0;
				Unity_Flipbook_float_FIXED(i.uv.xy, 
                    UNITY_ACCESS_INSTANCED_PROP(Props, _FlipX), 
                    UNITY_ACCESS_INSTANCED_PROP(Props, _FlipY), 
                    UNITY_ACCESS_INSTANCED_PROP(Props, _FlipIDX) - 1,
                    float2(-1, 1), flipbook_uv);
                //return half4(flipbook_uv, 0, 1);
				i.uv.xy = flipbook_uv;
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv) * UNITY_ACCESS_INSTANCED_PROP(Props, _Color);
                //#ifdef _IS_FOG_ON
                //    // apply fog
                //    fixed4 src_col = col;
                //    UNITY_APPLY_FOG(i.fogCoord, col);
                //    col = lerp(src_col, col, _FogIntensity);
                //#endif

                // apply fog
                fixed4 src_col = col;
                UNITY_APPLY_FOG(i.fogCoord, col);
                col = lerp(src_col, col, 
                    UNITY_ACCESS_INSTANCED_PROP(Props, _IS_FOG_ON) * 
                    UNITY_ACCESS_INSTANCED_PROP(Props, _FogIntensity));

                return lerp(col, saturate(col), UNITY_ACCESS_INSTANCED_PROP(Props, _ClampBrightness));
            }
            ENDCG
        }
    }
}


References

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值