Shader效果踩坑备忘

发布于 2021-03-18  498 次阅读


在使用%运算来制作图集中的sprite无限滚动的UV动画效果的时候,记得用abs把符号去掉,否则%运算(对于小数或者整数都一样)会保留符号,这就导致实际取值范围会到达(-1,1) 负数uv的部分会造成依赖于贴图超出处理方式属性的错误结果(clamp就是什么都没有或者色块 repeat就是显示出同图集的相邻其他sprite图像)。

还有几种可以代替%的计算方法:

There are several solutions:

Note while fmod and modf directly returns the remainder, frac has to be used like this:

 num = frac(num/range) * range;

floor could be used like this:

 num /= range; num = (num - floor(num)) * range;

Though fmod would be the simplest implementation

 num = fmod(num, range);

另外unity的UV坐标原点在贴图左下角,和GDI的左上角不同。

参考shader:

        float2 RestrictRect(float2 uv,float4 rect){
            uv -= rect.xy;
            //uv = frac(uv/rect.zw) * rect.zw;
            uv = abs(uv%rect.zw);
            uv += rect.xy;
            return uv;
        }
        fixed4 SampleSpriteTexture(float2 uv)
        {
            float2 mainTexUV = RestrictRect(uv + _Offset,_UVRect);
            fixed4 color = tex2D(_MainTex, mainTexUV);
        #if ETC1_EXTERNAL_ALPHA
            fixed4 alpha = tex2D(_AlphaTex, mainTexUV);
            color.a = lerp(color.a, alpha.r, _EnableExternalAlpha);
        #endif
            return color;
        }

另外传入UVRect的时候记得从sprite的rect属性里得到rect再除以sprite的纹理宽高,生成0-1范围的UV坐标再传入shader,否则会看不到任何东西。



点击数:218


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。