Получение горизонтального градиента в неосвещенном спрайт-шейдере даже при вращении спрайта - PullRequest
0 голосов
/ 08 апреля 2020

Я пишу базовый c неосвещенный спрайт-шейдер, который создает градиент между 2 цветами. Я добился этого легко, перенеся значение с координатой y в UV. Но таким образом, когда я вращаю свой спрайт, градиент вращается со спрайтом, как и ожидалось. Липпинг значения с позицией y в пиксельном мировом пространстве решил проблему вращения, но только если спрайт находится в центре мира. Когда спрайт перемещается в другую позицию в мире, значение градиента меняется. Я хочу, чтобы градиент был все время горизонтальным и происходил только внутри границ спрайтов. Как можно написать это с использованием фрагмента шейдера?

Текущее состояние моего шейдера:

Shader "Custom/SpriteGradient"
{
     Properties
     {
         _MainTex ("Main Texture", 2D) = "white" {}
         _TopColor ("Top Color", Color) = (1, 1, 1, 1)
         _BottomColor ("Bottom Color", Color) = (1, 1, 1, 1)
         [Toggle(BLEND)] _Blend("Blend With Texture", Float) = 0
     }
     SubShader
     {
         Pass
         {
             Blend SrcAlpha OneMinusSrcAlpha
             CGPROGRAM
             #pragma vertex vert
             #pragma fragment frag
             #pragma shader_feature BLEND
             #include "UnityCG.cginc"

             struct vertexIn {
                 float4 pos : POSITION;
                 float2 uv : TEXCOORD0;
             };

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


             fixed4 _TopColor, _BottomColor;
             sampler2D _MainTex;
             fixed4 _MainTex_ST;
             float4x4 _TextureRotation;

             v2f vert(vertexIn input)
             {
                 v2f output;
                 output.pos = UnityObjectToClipPos(input.pos);
                 output.uv = input.uv;
                 output.worldPos = mul (unity_ObjectToWorld, input.pos);
                 output.screenPos = ComputeScreenPos(input.pos);
                 return output;
             }


             fixed4 frag(v2f input) : COLOR
             {
                float2 screenUV = input.screenPos.xy / input.screenPos.w;
                //float currentY = input.worldPos.y;
                //float4 centerY = mul(unity_ObjectToWorld, float4(0.5,0.5,0.0,1.0)).y;

                fixed4 textureColor = tex2D(_MainTex, input.uv);
                fixed4 gradientValue = lerp(_BottomColor, _TopColor, input.uv.y);
                textureColor.rgb *= textureColor.a;

                #ifdef BLEND
                    textureColor.rgb *= gradientValue;
                #else
                    textureColor.rgb = gradientValue.rgb;
                #endif

                return textureColor;
             }
             ENDCG
         }
     }
}

Это состояние, в котором я получаю градиентное значение с помощью UV.y. На самом деле, найти центральное положение легко. Если есть какая-то встроенная функция, которая может правильно определить мировое положение самого высокого и самого низкого положения пикселя на оси Y (даже спрайт поворачивается вверх ногами), я думаю, что я могу использовать эти значения.

Любая помощь будет принята с благодарностью. Я новичок в кодировании шейдеров.

Спасибо всем.

...