51 lines
1.7 KiB
GLSL
51 lines
1.7 KiB
GLSL
#version 450 core
|
|
#include "common.glsl"
|
|
|
|
layout(location = 0) in vec4 iPosSize;
|
|
layout(location = 1) in vec4 iColor; // rgb, alpha
|
|
// x = kind (0 firefly, 1 mote, 2 spark, 3 flame, 4 ember, 5 smoke, 6 glow),
|
|
// y = age / life, z = per-particle random seed
|
|
layout(location = 2) in vec4 iParams;
|
|
|
|
out vec2 vUV;
|
|
out vec4 vColor;
|
|
flat out int vKind;
|
|
out vec2 vLifeSeed;
|
|
|
|
void main() {
|
|
vec2 corner = vec2(float(gl_VertexID & 1), float(gl_VertexID >> 1)) - 0.5;
|
|
vec3 camRight = vec3(uView[0][0], uView[1][0], uView[2][0]);
|
|
vec3 camUp = vec3(uView[0][1], uView[1][1], uView[2][1]);
|
|
int kind = int(iParams.x + 0.5);
|
|
float seed = iParams.z;
|
|
|
|
vec2 offset = corner;
|
|
float extent = 5.0; // fireflies / motes need room for their halo
|
|
if (kind == 2 || kind == 4 || kind == 6) extent = 1.0;
|
|
if (kind == 3) { // flame tongues are taller than wide
|
|
extent = 1.0;
|
|
offset *= vec2(1.0, 1.7);
|
|
}
|
|
if (kind == 5) { // smoke puffs rotate slowly
|
|
extent = 1.0;
|
|
float a = seed * 6.2832 + iParams.y * 1.5;
|
|
offset = mat2(cos(a), sin(a), -sin(a), cos(a)) * offset;
|
|
}
|
|
vec3 c = iPosSize.xyz;
|
|
vec3 wp = c + (camRight * offset.x + camUp * offset.y) * iPosSize.w * extent;
|
|
|
|
vec4 col = iColor;
|
|
if (kind == 1) { // dust motes only sparkle inside sun shafts
|
|
float vis = sunShadowFast(c) * shaftCookie(c);
|
|
col.rgb *= uSunColor.rgb * uSunDir.w * 0.8;
|
|
col.a *= vis;
|
|
}
|
|
if (kind == 5) // smoke is lit by the sky and warmed by nearby fire light
|
|
col.rgb *= hemiAmbient(vec3(0, 1, 0)) * 2.5 + pointLights(c, vec3(0, -1, 0)) * 0.4;
|
|
vUV = corner + 0.5;
|
|
vColor = col;
|
|
vKind = kind;
|
|
vLifeSeed = iParams.yz;
|
|
gl_Position = uViewProj * vec4(wp, 1.0);
|
|
}
|