Published
Edited
Jun 12, 2020
1 fork
1 star
Insert cell
Insert cell
bnb({
w: 540, h: 540,
webgl: true,
fps: 20,
numFrames: 120,
record: true,
shutterAngle: .8,
samplesPerFrame: 8,
chromaticAberration: 1,
// video: true,
setup: (s, g) => {
s.myShader = s.createShader(vertexShader(), fragmentShader())
},

draw: (s, t, g) => {
s.noStroke()

s.background(0)
// shader() sets the active shader with our shader
s.shader(s.myShader)

// Send the frameCount to the shader
s.myShader.setUniform("uFrameCount", t * 50)

// Rotate our geometry on the X and Y axes
s.rotateY(s.PI/2)
s.rotateZ(s.TAU * t)

// Draw some geometry to the screen
// We're going to tessellate the sphere a bit so we have some more geometry to work with
s.sphere(s.width / 3, 200, 200)
},
})
Insert cell
vertexShader = () => `// Get the position attribute of the geometry
attribute vec3 aPosition;

// Get the texture coordinate attribute from the geometry
attribute vec2 aTexCoord;

// Get the vertex normal attribute from the geometry
attribute vec3 aNormal;

// When we use 3d geometry, we need to also use some builtin variables that p5 provides
// Most 3d engines will provide these variables for you. They are 4x4 matrices that define
// the camera position / rotation, and the geometry position / rotation / scale
// There are actually 3 matrices, but two of them have already been combined into a single one
// This pre combination is an optimization trick so that the vertex shader doesn't have to do as much work

// uProjectionMatrix is used to convert the 3d world coordinates into screen coordinates
uniform mat4 uProjectionMatrix;

// uModelViewMatrix is a combination of the model matrix and the view matrix
// The model matrix defines the object position / rotation / scale
// Multiplying uModelMatrix * vec4(aPosition, 1.0) would move the object into it's world position

// The view matrix defines attributes about the camera, such as focal length and camera position
// Multiplying uModelViewMatrix * vec4(aPosition, 1.0) would move the object into its world position in front of the camera
uniform mat4 uModelViewMatrix;

// Get the framecount uniform
uniform float uFrameCount;

varying vec2 vTexCoord;
varying vec3 vNormal;
varying vec3 vPos;

void main() {

// copy the position data into a vec4, using 1.0 as the w component
vec4 positionVec4 = vec4(aPosition, 1.0);

// Frequency and Amplitude will determine the look of the displacement
float frequency = 30.0;
float amplitude = 0.3;

// Displace the x position withe the sine of the x + time. Multiply by the normal to move it in the correct direction
// You could add more distortions to the other axes too.
float distortion = sin(positionVec4.x * frequency + uFrameCount);
positionVec4.x += distortion * aNormal.x * amplitude;

// Send the normal to the fragment shader
vNormal = aNormal;


// Move our vertex positions into screen space
// The order of multiplication is always projection * view * model * position
// In this case model and view have been combined so we just do projection * modelView * position
gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
// Send the texture coordinates to the fragment shader
vTexCoord = aTexCoord;
vPos = aPosition;
}`
Insert cell
fragmentShader = () => `precision mediump float;

varying vec2 vTexCoord;
varying vec3 vPos;

// Get the normal from the vertex shader
varying vec3 vNormal;

void main() {
// Normalize the normal
vec3 color = vNormal * 0.5 + 0.5;
// Lets just draw the texcoords to the screen
gl_FragColor = vec4(vec3(sin(vPos.x * 10.) * .6 + .5), 1.0);
}`
Insert cell
Insert cell
import {bnb} from '@makio135/bnb'
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more