vanta
Version:
3D animated backgrounds for your website
171 lines (144 loc) • 5.36 kB
JavaScript
import ShaderBase, {VANTA} from './_shaderBase.js'
class Effect extends ShaderBase {}
export default VANTA.register('CLOUDS', Effect)
Effect.prototype.defaultOptions = {
backgroundColor: 0xffffff,
skyColor: 0x68b8d7, // 0x99b5bf,
cloudColor: 0xadc1de,
cloudShadowColor: 0x183550,
sunColor: 0xff9919, // 0x1a9eaa
sunGlareColor: 0xff6633,
sunlightColor: 0xff9933, // 0x1a9eaa
scale: 3,
scaleMobile: 12,
speed: 1,
mouseEase: true,
}
Effect.prototype.fragmentShader = `\
uniform vec2 iResolution;
uniform vec2 iMouse;
uniform float iTime;
uniform sampler2D iTex;
uniform float speed;
uniform vec3 skyColor;
uniform vec3 cloudColor;
uniform vec3 cloudShadowColor;
uniform vec3 sunColor;
uniform vec3 sunlightColor;
uniform vec3 sunGlareColor;
uniform vec3 backgroundColor;
// uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click
// uniform samplerXX iChannel0..3; // input channel. XX = 2D/Cube
// Volumetric clouds. It performs level of detail (LOD) for faster rendering
float hash(float p) {
p = fract(p * 0.011);
p *= (p + 7.5);
p *= (p + p);
return fract(p);
}
float noise( vec3 x ){
// The noise function returns a value in the range -1.0f -> 1.0f
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
float n = p.x + p.y*57.0 + 113.0*p.z;
return mix(mix(mix( hash(n+0.0 ), hash(n+1.0 ),f.x),
mix( hash(n+57.0 ), hash(n+58.0 ),f.x),f.y),
mix(mix( hash(n+113.0), hash(n+114.0),f.x),
mix( hash(n+170.0), hash(n+171.0),f.x),f.y),f.z);
}
const float constantTime = 1000.;
float map5( in vec3 p ){
vec3 speed1 = vec3(0.5,0.01,1.0) * 0.5 * speed;
vec3 q = p - speed1*(iTime + constantTime);
float f;
f = 0.50000*noise( q ); q = q*2.02;
f += 0.25000*noise( q ); q = q*2.03;
f += 0.12500*noise( q ); q = q*2.01;
f += 0.06250*noise( q ); q = q*2.02;
f += 0.03125*noise( q );
return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
}
float map4( in vec3 p ){
vec3 speed1 = vec3(0.5,0.01,1.0) * 0.5 * speed;
vec3 q = p - speed1*(iTime + constantTime);
float f;
f = 0.50000*noise( q ); q = q*2.02;
f += 0.25000*noise( q ); q = q*2.03;
f += 0.12500*noise( q ); q = q*2.01;
f += 0.06250*noise( q );
return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
}
float map3( in vec3 p ){
vec3 speed1 = vec3(0.5,0.01,1.0) * 0.5 * speed;
vec3 q = p - speed1*(iTime + constantTime);
float f;
f = 0.50000*noise( q ); q = q*2.02;
f += 0.25000*noise( q ); q = q*2.03;
f += 0.12500*noise( q );
return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
}
float map2( in vec3 p ){
vec3 speed1 = vec3(0.5,0.01,1.0) * 0.5 * speed;
vec3 q = p - speed1*(iTime + constantTime);
float f;
f = 0.50000*noise( q ); q = q*2.02;
f += 0.25000*noise( q );
return clamp( 1.5 - p.y - 2.0 + 1.75*f, 0.0, 1.0 );
}
vec3 sundir = normalize( vec3(-1.0,0.0,-1.0) );
vec4 integrate( in vec4 sum, in float dif, in float den, in vec3 bgcol, in float t ){
// lighting
vec3 lin = cloudColor*1.4 + sunlightColor*dif;
vec4 col = vec4( mix( vec3(1.0,0.95,0.8), cloudShadowColor, den ), den );
col.xyz *= lin;
col.xyz = mix( col.xyz, bgcol, 1.0-exp(-0.003*t*t) );
// front to back blending
col.a *= 0.4;
col.rgb *= col.a;
return sum + col*(1.0-sum.a);
}
vec4 raymarch( in vec3 ro, in vec3 rd, in vec3 bgcol, in ivec2 px ){
vec4 sum = vec4(0.0);
float t = 0.0;
MARCH(20,map5);
MARCH(25,map4);
MARCH(30,map3);
MARCH(40,map2);
return clamp( sum, 0.0, 1.0 );
}
mat3 setCamera( in vec3 ro, in vec3 ta, float cr ){
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) );
vec3 cv = normalize( cross(cu,cw) );
return mat3( cu, cv, cw );
}
vec4 render( in vec3 ro, in vec3 rd, in ivec2 px ){
// background sky
float sun = clamp( dot(sundir,rd), 0.0, 1.0 );
vec3 col = skyColor - rd.y*0.2*vec3(1.0,0.5,1.0) + 0.15*0.5;
col += 0.2*sunColor*pow( sun, 8.0 );
// clouds
vec4 res = raymarch( ro, rd, col, px );
col = col*(1.0-res.w) + res.xyz;
// sun glare
col += 0.2*sunGlareColor*pow( sun, 3.0 );
return vec4( col, 1.0 );
}
void main(){
vec2 p = (-iResolution.xy + 2.0*gl_FragCoord.xy)/ iResolution.y;
vec2 m = iMouse.xy/iResolution.xy;
m.y = (1.0 - m.y) * 0.33 + 0.28; // camera height
m.x *= 0.25;
m.x += sin(iTime * 0.1 + 3.1415) * 0.25 + 0.25;
// camera
vec3 ro = 4.0*normalize(vec3(sin(3.0*m.x), 0.4*m.y, cos(3.0*m.x))); // origin
vec3 ta = vec3(0.0, -1.0, 0.0);
mat3 ca = setCamera( ro, ta, 0.0 );
// ray
vec3 rd = ca * normalize( vec3(p.xy,1.5));
gl_FragColor = render( ro, rd, ivec2(gl_FragCoord-0.5) );
}
`