forked from aya/aya
199 lines
5.5 KiB
Scala
199 lines
5.5 KiB
Scala
$input a_position, a_texcoord0, a_texcoord1, a_texcoord2, a_texcoord3
|
|
$output v_texcoord0, v_texcoord1, v_color0
|
|
|
|
#include "common.sh"
|
|
|
|
SAMPLER2D(s_tex, 0);
|
|
SAMPLER2D(s_cstrip, 1);
|
|
SAMPLER2D(s_astrip, 2);
|
|
|
|
uniform vec4 u_throttleFactor; // .x = alpha cutoff, .y = alpha boost (clamp), .w - additive/alpha ratio for Crazy shaders
|
|
uniform vec4 u_modulateColor;
|
|
uniform vec4 u_zOffset;
|
|
|
|
vec4 rotScale(vec4 scaleRotLife)
|
|
{
|
|
float cr = cos(scaleRotLife.z);
|
|
float sr = sin(scaleRotLife.z);
|
|
|
|
vec4 r;
|
|
r.x = cr * scaleRotLife.x;
|
|
r.y = -sr * scaleRotLife.x;
|
|
r.z = sr * scaleRotLife.y;
|
|
r.w = cr * scaleRotLife.y;
|
|
|
|
return r;
|
|
}
|
|
|
|
vec4 mulq(vec4 a, vec4 b)
|
|
{
|
|
vec3 i = cross(a.xyz, b.xyz) + a.w * b.xyz + b.w * a.xyz;
|
|
float r = a.w * b.w - dot(a.xyz, b.xyz);
|
|
return vec4(i, r);
|
|
}
|
|
|
|
vec4 conj(vec4 a)
|
|
{
|
|
return vec4(-a.xyz, a.w);
|
|
}
|
|
|
|
vec4 rotate(vec4 v, vec4 q)
|
|
{
|
|
return mulq(mulq(q, v), conj(q));
|
|
}
|
|
|
|
vec4 axis_angle(vec3 axis, float angle)
|
|
{
|
|
return vec4(sin(angle/2.0) * axis, cos(angle/2.0));
|
|
}
|
|
|
|
void vs()
|
|
{
|
|
vec4 pos = vec4(a_position, 1.0);
|
|
vec2 disp = a_texcoord1.xy * 2.0 - 1.0; // -1..1
|
|
|
|
vec4 scaleRotLifeFlt = a_texcoord0 * vec4(1.0/256.0, 1.0/256.0, 2.0 * 3.1415926 / 32767.0, 1.0 / 32767.0);
|
|
scaleRotLifeFlt.xy += 127.0;
|
|
|
|
vec4 rs = rotScale(scaleRotLifeFlt);
|
|
|
|
pos += u_viewRight * dot(disp, rs.xy);
|
|
pos += u_viewUp * dot(disp, rs.zw);
|
|
|
|
vec4 pos2 = pos + u_viewDir * u_zOffset.x; // Z-offset position in world space
|
|
|
|
gl_Position = mul(u_viewProjection, pos);
|
|
|
|
v_texcoord0.xy = a_texcoord1.xy;
|
|
v_texcoord0.y = 1.0 - v_texcoord0.y;
|
|
v_texcoord0.z = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
|
|
|
|
v_texcoord1.x = 1.0 - max(0.0, min(1.0, scaleRotLifeFlt.w));
|
|
v_texcoord1.y = a_texcoord2.x * (1.0 / 32767.0);
|
|
|
|
pos2 = mul(u_viewProjection, pos2); // Z-offset position in clip space
|
|
gl_Position.z = pos2.z * gl_Position.w / pos2.w; // Only need z
|
|
}
|
|
|
|
void psAdd()
|
|
{
|
|
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
|
|
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy);
|
|
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
|
|
|
|
vec4 result;
|
|
|
|
result.rgb = (texcolor.rgb + vcolor.rgb) * u_modulateColor.rgb;
|
|
result.a = texcolor.a * vcolor.a;
|
|
result.rgb *= result.a;
|
|
|
|
result.rgb = mix(vec3(0.0), result.rgb, saturate(v_texcoord0.zzz));
|
|
gl_FragColor = result;
|
|
}
|
|
|
|
void psModulate()
|
|
{
|
|
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
|
|
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy) * u_modulateColor;
|
|
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r * u_modulateColor.a;
|
|
|
|
vec4 result;
|
|
|
|
result.rgb = texcolor.rgb * vcolor.rgb;
|
|
result.a = texcolor.a * vcolor.a;
|
|
|
|
result.rgb = mix(u_fogColor.rgb, result.rgb, saturate(v_texcoord0.zzz));
|
|
gl_FragColor = result;
|
|
}
|
|
|
|
// - this shader is crazy
|
|
// - used instead of additive particles to help see bright particles (e.g. fire) on top of extremely bright backgrounds
|
|
// - requires ONE | INVSRCALPHA blend mode, useless otherwise
|
|
// - does not use color strip texture
|
|
// - outputs a blend between additive blend and alpha blend in fragment alpha
|
|
// - ratio multiplier is in throttleFactor.w
|
|
void psCrazy()
|
|
{
|
|
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
|
|
vec4 vcolor = vec4(1.0, 0.0, 0.0, 0.0);
|
|
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
|
|
float blendRatio = u_throttleFactor.w;
|
|
|
|
vec4 result;
|
|
|
|
result.rgb = (texcolor.rgb) * u_modulateColor.rgb * vcolor.a * texcolor.a;
|
|
result.a = blendRatio * texcolor.a * vcolor.a;
|
|
|
|
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
|
|
gl_FragColor = result;
|
|
}
|
|
|
|
void psCrazySparkles()
|
|
{
|
|
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
|
|
vec4 vcolor = texture2D(s_cstrip, v_texcoord1.xy);
|
|
vcolor.a = texture2D(s_astrip, v_texcoord1.xy).r;
|
|
float blendRatio = u_throttleFactor.w;
|
|
|
|
vec4 result;
|
|
|
|
if (texcolor.a < 0.5)
|
|
{
|
|
result.rgb = vcolor.rgb * u_modulateColor.rgb * (2.0 * texcolor.a);
|
|
}
|
|
else
|
|
{
|
|
result.rgb = mix(vcolor.rgb * u_modulateColor.rgb, texcolor.rgb, 2.0 * texcolor.a - 1.0);
|
|
}
|
|
|
|
result.rgb *= vcolor.a;
|
|
result.a = blendRatio * texcolor.a * vcolor.a;
|
|
|
|
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
|
|
gl_FragColor = result;
|
|
}
|
|
|
|
// Custom particle shader
|
|
void vsCustom()
|
|
{
|
|
vec4 pos = vec4(a_position, 1.0);
|
|
vec2 disp = a_texcoord1.xy * 2.0 - 1.0; // -1..1
|
|
|
|
vec4 scaleRotLifeFlt = a_texcoord0 * vec4(1.0/256.0, 1.0/256.0, 2.0 * 3.1415926 / 32767.0, 1.0 / 32767.0);
|
|
scaleRotLifeFlt.xy += 127.0;
|
|
|
|
vec4 rs = rotScale(scaleRotLifeFlt);
|
|
|
|
pos += u_viewRight * dot(disp, rs.xy);
|
|
pos += u_viewUp * dot(disp, rs.zw);
|
|
|
|
vec4 pos2 = pos + u_viewDir * u_zOffset.x; // Z-offset position in world space
|
|
|
|
gl_Position = mul(u_viewProjection, pos);
|
|
|
|
v_texcoord0.xy = a_texcoord1.xy;
|
|
v_texcoord0.y = 1.0 - v_texcoord0.y;
|
|
v_texcoord0.z = (u_fogParams.z - gl_Position.w) * u_fogParams.w;
|
|
|
|
v_color0 = a_texcoord3 * (1.0/255.0);
|
|
|
|
pos2 = mul(u_viewProjection, pos2); // Z-offset position in clip space
|
|
gl_Position.z = pos2.z * gl_Position.w / pos2.w; // Only need z
|
|
}
|
|
|
|
void psCustom()
|
|
{
|
|
vec4 texcolor = texture2D(s_tex, v_texcoord0.xy);
|
|
vec4 vcolor = v_color0;
|
|
|
|
float blendRatio = u_throttleFactor.w;
|
|
|
|
vec4 result;
|
|
|
|
result.rgb = texcolor.rgb * vcolor.rgb * vcolor.a * texcolor.a;
|
|
result.a = blendRatio * texcolor.a * vcolor.a;
|
|
|
|
result = mix(vec4(0.0), result, saturate(v_texcoord0.zzzz));
|
|
gl_FragColor = result;
|
|
}
|