Particle Waves made with native WebGL shader
A Pen by Boris Šehovac on CodePen.
| <div class="waves"></div> |
Particle Waves made with native WebGL shader
A Pen by Boris Šehovac on CodePen.
| // https://github.com/bsehovac/shader-program | |
| const pointSize = 2.5 | |
| const waves = new ShaderProgram( document.querySelector( '.waves' ), { | |
| texture: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAb1BMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8v0wLRAAAAJHRSTlMAC/goGvDhmwcExrVjWzrm29TRqqSKenRXVklANSIUE8mRkGpv+HOfAAABCElEQVQ4y4VT13LDMAwLrUHteO+R9f/fWMfO6dLaPeKVEECRxOULWsEGpS9nULDwia2Y+ALqUNbAWeg775zv+sA4/FFRMxt8U2FZFCVWjR/YrH4/H9sarclSKdPMWKzb8VsEeHB3m0shkhVCyNzeXeAQ9Xl4opEieX2QCGnwGbj6GMyjw9t1K0fK9YZunPXeAGsfJtYjwzxaBnozGGorYz0ypK2HzQSYx1y8DgSRo2ewOiyh2QWOEk1Y9OrQV0a8TiBM1a8eMHWYnRMy7CZ4t1CmyRkhSUvP3gRXyHOCLBxNoC3IJv//ZrJ/kxxUHPUB+6jJZZHrpg6GOjnqaOmzp4NDR48OLxn/H27SRQ08S0ZJAAAAAElFTkSuQmCC', | |
| uniforms: { | |
| size: { type: 'float', value: pointSize }, | |
| field: { type: 'vec3', value: [ 0, 0, 0 ] }, | |
| speed: { type: 'float', value: 5 }, | |
| }, | |
| vertex: ` | |
| #define M_PI 3.1415926535897932384626433832795 | |
| precision highp float; | |
| attribute vec4 a_position; | |
| attribute vec4 a_color; | |
| uniform float u_time; | |
| uniform float u_size; | |
| uniform float u_speed; | |
| uniform vec3 u_field; | |
| uniform mat4 u_projection; | |
| varying vec4 v_color; | |
| void main() { | |
| vec3 pos = a_position.xyz; | |
| pos.y += ( | |
| cos(pos.x / u_field.x * M_PI * 8.0 + u_time * u_speed) + | |
| sin(pos.z / u_field.z * M_PI * 8.0 + u_time * u_speed) | |
| ) * u_field.y; | |
| gl_Position = u_projection * vec4( pos.xyz, a_position.w ); | |
| gl_PointSize = ( u_size / gl_Position.w ) * 100.0; | |
| v_color = a_color; | |
| }`, | |
| fragment: ` | |
| precision highp float; | |
| uniform sampler2D u_texture; | |
| varying vec4 v_color; | |
| void main() { | |
| gl_FragColor = v_color * texture2D(u_texture, gl_PointCoord); | |
| }`, | |
| onResize( w, h, dpi ) { | |
| const position = [], color = [] | |
| const width = 400 * ( w / h ) | |
| const depth = 400 | |
| const height = 3 | |
| const distance = 5 | |
| for ( let x = 0; x < width; x += distance ) { | |
| for ( let z = 0; z < depth; z+= distance ) { | |
| position.push( - width / 2 + x, -30, -depth / 2 + z ) | |
| color.push( 0, 1 - ( x / width ) * 1, 0.5 + x / width * 0.5, z / depth ) | |
| } | |
| } | |
| this.uniforms.field = [ width, height, depth ] | |
| this.buffers.position = position | |
| this.buffers.color = color | |
| this.uniforms.size = ( h / 400) * pointSize * dpi | |
| }, | |
| } ) |
| <script src="https://codepen.io/bsehovac/pen/mddZWPw.js"></script> |
| html, body { height: 100%; } | |
| body { margin: 0; background: #000; } | |
| canvas { display: block; } | |
| .waves { position: absolute; left: 0; top: 0; right: 0; bottom: 0; } |