Die Nachkommastellen von "mode" beinhaltet Information über den angewendeten exklusiven Effekt, ursprünglich gab es davon 10.
0.0 - 0.1 : Sinus basiertes Blinken, wird für die Hexas verwendet
0.1 - 0.2 : -
0.2 - 0.3 : -
0.3 - 0.4 : Aufflackern einer Einheit wenn sie Schaden nimmt, bei vollen HP Weiss, fast tot Magenta
0.4 - 0.5 : Helligkeit
0.5 - 0.6 : -
0.6 - 0.7 : Rot Einfärben, 0.6999 ist komplett Rot
0.7 - 0.8 : Sterbendes Objekt, zerstäuben/zerfallender Effekt
0.8 - 0.9 : -
0.9 - 1.0 : Blending Mode, 0.9 Normal 0.9999 Additive
smode ist der Wert ab der zweiten Nachkommastelle, also von 0.9532 ist es 0.0532. Um besser damit arbeiten zu können wird der Wert mit 10 multipliziert -> 0.532. smode wird überwiegend benutzt um die Stärke eines Effekts festzulegen.
Typische Code für ein Effekt sieht bei mir so aus:
Code: Alles auswählen
//0.6<mode<=0.7 make red
c.rgb = (mode>0.6 && mode<=0.7) ? c.rgb*nmode+vec3(smode*c.a, 0.0, 0.0) : c.rgb;
Am meisten Sinn würde ein Switch statement machen, wäre es normaler Code, da jeder Effekt exklusiv ist. Dazu kommt dass jeder Effekt pro Polygon garantiert immer gleich ist, also wäre zumindest ein Teil in den Vertex-Shader verlagerbar. Da ich mit Alpha-Blending alles sequentiell zeichnen muss, wird vermutlich die GPU die Polygone einzeln abarbeiten. Aber ich habe eigentlich keine Ahnung.
Dazu kommt, Ich weiss überhaupt nicht wie ich Shader testen soll. Trial and Error scheint das einzige zu sein, aber ich habe auch nicht ausreichend Testgeräte für sowas.
Was denkt ihr?
Code: Alles auswählen
float smode = fract(mode*10.0);
float nmode = 1.0-smode;
//0.7<mode<=0.8 dying
bool dying = mode>0.7 && mode<=0.8;
float x = v_tex.x;
float y = (dying && nmode<1.0 && nmode!=0.0) ? fallApart(pos, nmode, smode) : 1000.0;
vec2 texpos = y==1000.0 ? pos : v_coord + vec2(x, y)*v_size;
//if dying and coordinates for look up outside of texture bounds -> can be discarded or alpha = 0, what is better???
if(dying && (y<0.0 || y>1.0 || x<0.0 || x>1.0)){
//gl_FragColor = vec4(0.0,0.0,0.0,0.0);
//return;
discard;
}
//squared randomized value, only used if the object is dying
float r2 = dying ? sqr(rand(pos+v_pos*vec2(smode,smode))) : 0;
vec4 c = texture2D(u_image, texpos)*(dying && nmode<0.5 ? (r2>nmode*2.0 ? 0.0 : min(nmode*6.0,1.0)) : 1.0);
//alpha value of received texture from atlas is 0 -> discard it
if(c.a==0.0) discard;
//0.6<mode<=0.7 make red
c.rgb = (mode>0.6 && mode<=0.7) ? c.rgb*nmode+vec3(smode*c.a, 0.0, 0.0) : c.rgb;
//0.9<mode additive blending
bool additive = mode>0.9;
c.a *= additive ? nmode : 1.0;
//mode with bright elements being additive, dark elements normal composition
bool shot = mode>0.5 && mode<=0.6;
c.a *= (shot && c.a>0.0) ? (1.0-c.r)*(1.0+c.r*(0.3/c.a-nmode)) : 1.0;
c.rgb = (shot) ? (c.rgb+c.r*0.2*max(smode,0.0))*(1.0+c.a*2.5)*max(smode-0.1,0.0) : c.rgb;
//0.4<mode<=0.5 brightness
c.rgb = (mode>0.4 && mode<=0.5) ? (c.rgb+c.r*0.2*max(smode,0.0))*(1.0+c.a*9.0)*max(smode-0.1,0.0) : c.rgb;
//0.3<mode<=0.4 unit damage highlight
bool hurt = (mode>0.3 && mode<=0.4);
dec = hurt ? 0.0 : dec;
float ca2 = 2.0*max(0.0,c.a-0.5);
float mx = max(max(c.r,c.g),c.b);
//smode = 0.0; dec = 0.0;
float asmode = ca2*smode;
c.rgba = hurt ? vec4(ca2*mx, min(1.0,(asmode-0.25)*1.75)*mx, 3.0*max(0.0,max(asmode-0.333,(0.125-smode)*ca2))*mx, ca2)*2.0 : c.rgba;
//0.0<mode<=0.1 sinus blink
c.rgb*= (mode<=0.1) ? (1.0+smode*abs(sin(smode*1000.0+u_time*fract(smode*10.0)))) : 1.0;