97 lines
2.7 KiB
Plaintext
97 lines
2.7 KiB
Plaintext
#version 120
|
|
const int nLightCount = 2;
|
|
attribute vec4 in_vertex;
|
|
attribute vec3 in_normal;
|
|
attribute vec2 in_uv;
|
|
attribute vec4 in_color;
|
|
attribute vec4 in_uv2;
|
|
|
|
uniform float cycle;
|
|
uniform vec4 wsRot;
|
|
uniform vec4 wsPos;
|
|
uniform vec2 texSize;
|
|
|
|
varying vec4 pos;
|
|
varying vec3 normal, npos, origo;
|
|
varying vec2 uv, uv2, uvNoise, uvSplat, uvB[5];
|
|
varying float pulse, poleMask;
|
|
varying vec3 light[nLightCount];
|
|
varying vec3 splatRadial;
|
|
varying float atmoMask;
|
|
|
|
const float pi = 3.14159265358;
|
|
const float tau = 6.28318530717;
|
|
const vec2 fractions = vec2(0.984375, 0.0078125);
|
|
|
|
float square(float x){
|
|
return x*x;
|
|
}
|
|
|
|
vec3 square(vec3 x){
|
|
return x*x;
|
|
}
|
|
// regular atan() fails at 0,0
|
|
float atan2(float y, float x)
|
|
{
|
|
return x == 0.0 ? sign(y)*pi/2 : atan(y, x);
|
|
}
|
|
|
|
vec3 toLinear(vec3 x) {
|
|
return pow(x, vec3(2.2));
|
|
}
|
|
|
|
vec3 wsAllign(vec3 x){
|
|
return x + 2.0 * cross(wsRot.xyz, cross(wsRot.xyz, x) + wsRot.w * x);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
|
|
uv = in_uv;
|
|
uv2 = in_uv2.xy;
|
|
uvNoise = ((uv * vec2(128.0, 4.0)) * fractions.x + fractions.y) / 5.0;
|
|
float radial = fract(atan2(in_vertex.r, in_vertex.b) / tau);
|
|
uvSplat = vec2(uv2.y, abs(radial * 2.0 - 1.0));
|
|
|
|
radial = abs(fract(radial * 8.0) * 2.0 - 1.0);
|
|
radial *= 3.0;
|
|
splatRadial = clamp(vec3(radial, radial - 1.0, radial - 2.0), vec3(0.0), vec3(1.0));
|
|
splatRadial *= splatRadial * (3.0 - splatRadial * 2.0);
|
|
|
|
poleMask = square(abs(in_vertex.y * 16.0));
|
|
pulse = abs(cycle * 2.0 - 1.0);
|
|
pos = gl_ModelViewMatrix * in_vertex;
|
|
origo = in_vertex.xyz;
|
|
|
|
// convert view, normal and light vectors to world space and quaternion correct for model rotation
|
|
mat3 tcamrot = transpose(mat3x3(gl_ModelViewMatrix));
|
|
npos = (wsAllign(normalize(tcamrot * -pos.xyz)));
|
|
|
|
// special view vector to correct just for cubemap reflections
|
|
normal = (tcamrot * (gl_NormalMatrix * wsAllign(normalize(in_normal))));
|
|
for (int i = 0; i < nLightCount; i++) {
|
|
light[i] = wsAllign(normalize((tcamrot * (((gl_LightSource[i].position)).xyz - pos.xyz))));
|
|
}
|
|
|
|
atmoMask = in_color.r;
|
|
|
|
// make splatmap blurs
|
|
vec2 blur = vec2(1.0 / texSize.x, 1.0 / texSize.y);
|
|
uvB[0] = uv;
|
|
uvB[1] = uv + blur;
|
|
uvB[2] = uv + vec2(-blur.x, blur.y);
|
|
uvB[3] = uv + vec2(-blur.x, -blur.y);
|
|
uvB[4] = uv + vec2(blur.x, -blur.y);
|
|
|
|
// clamp so we don't get south poles blending into north poles an vice versa
|
|
blur.y = 1.0 - blur.x;
|
|
uvB[0].y = clamp(uvB[0].y, blur.x, blur.y);
|
|
uvB[1].y = clamp(uvB[1].y, blur.x, blur.y);
|
|
uvB[2].y = clamp(uvB[2].y, blur.x, blur.y);
|
|
uvB[3].y = clamp(uvB[3].y, blur.x, blur.y);
|
|
uvB[4].y = clamp(uvB[4].y, blur.x, blur.y);
|
|
|
|
|
|
gl_Position = gl_ProjectionMatrix * pos;
|
|
}
|