Battle Angel Alita писал(а):Можно попробовать premultiplied alpha
оно?
Используется glsl
Shader "Particles/Alpha Blended Premultiply" {
Properties {
_MainTex ("Particle Texture", 2D) = "white" {}
}
Category {
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
Blend One OneMinusSrcAlpha
ColorMask RGB
Cull Off Lighting Off ZWrite Off Fog {Mode Off}
BindChannels {
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
// ---- Dual texture cards
SubShader {
Pass {
SetTexture [_MainTex] {
combine primary * primary alpha
}
SetTexture [_MainTex] {
combine previous * texture
}
}
}
// ---- Single texture cards (not entirely correct)
SubShader {
Pass {
SetTexture [_MainTex] {
combine texture * primary
}
}
}
}
}
Что ему еще можно причесать для мобилки? Правильно ли я понял, что
текстура должна быть специальным образом подготовлена?
Не проблема, можно через текстуру передавать, она в памяти линейно лежит.
Тут такое дело, даже если и получится небезопасным кодом напрямую в память писать цвета текстуры (обойдя таким образом медленный SetPixel), чтобы заслать ее в видеокарту, надо Apply() вызывать. А это тоже как-то не быстро.
Наваял тут свой варант "анимирующего шейдера". Прошу пинать в нужном направлении. Но не сильно, это мой второй опыт общения с шейдырами (в первый раз это была замена Queue у UnlitAlpha
)
Использую нормаль как вектор направления движения
tangent.x - время начала движения
tangent.y - скорость анимации (время на кадр)
tangent.z - ширина кадра анимации
Используется glsl
Shader "Custom/AgentsAnimator" {
Properties {
_MainTex ("Texture", 2D) = "white" { }
_Speed ("Speed", Float) = 1
}
SubShader {
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _Speed;
sampler2D _MainTex;
struct appdata {
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float4 tangent : TANGENT;
};
struct v2f {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
float4 pos;
int maxFrames = 3;
float fps = v.tangent.y;
float spriteTime = _Time.y - v.tangent.x;
pos.xyz = v.vertex.xyz + v.normal * spriteTime * _Speed;
pos.w = 1.0f;
o.pos = mul(UNITY_MATRIX_MVP, pos);
int curFrame = (int)(abs(cos(spriteTime/fps))*maxFrames);
float2 tex = float2(v.texcoord.x + curFrame* v.tangent.z, v.texcoord.y);
o.uv = TRANSFORM_TEX (tex, _MainTex);
return o;
}
half4 frag (v2f i) : COLOR
{
return tex2D (_MainTex, i.uv);
}
ENDCG
}
}
Fallback "VertexLit"
}
теоретически выигрываем на перемещении спрайта, обращаемся к видеокарте (создаем vbo) только в момент начала движения. Но фактически, когда спрайтов много и все стартуют в разное время, периодически меняя направление, число обращений такое же как и без шейдера, когда все на CPU)) Экономия за счет того, что Lerp на CPU не делаем?
П.С. Опа. Только что заметил, что "предсказанное" на CPU время движения не совпадает с фактическим временем перемещения спрайта на GPU, в результате чего в конце происходит небольшой скачек