Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documenting available attributes and uniforms (addresses issue 1017) #1033

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/data/examples/assets/shader_defaults.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* This is a modification of a shader by Adam Ferriss
https://github.com/aferriss/p5jsShaderExamples/blob/gh-pages/6_3d/6-2_vertexDisplacement
*/

/* WebGL requires that the first line of the fragment shader
specify the precision.
Precision is dependent on the the device.
Sometimes you'll see bugs if you use lowp so stick to mediump or highp.
*/
precision mediump float;

/* Get the normal from the vertex shader.
This is the same variable we declared in the vertex shader.
We need to declare it here too!
*/
varying vec3 vNormal;

void main() {

// Normalize the normal
vec3 color = vNormal * 0.5 + 0.5;

// Assign the color to be output to the screen
gl_FragColor = vec4(color, 1.0);
}
82 changes: 82 additions & 0 deletions src/data/examples/assets/shader_defaults.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* This is a modification of a shader by Adam Ferriss
https://github.com/aferriss/p5jsShaderExamples/blob/gh-pages/6_3d/6-2_vertexDisplacement
*/

// Get the vertex position attribute of the geometry
attribute vec3 aPosition;

// Get the vertex normal attribute of 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 (model, view, projection), but
two of them have already been combined into a single one (modelView).
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;

/* This is a variable that will be shared with the fragment shader.
We will assign the attribute aNormal to the varying vNormal to
move it from the vertex shader to the fragment shader.
It can be called whatever you want, but ofter people prefix it
with 'v' to indicate that it is a varying.
*/
varying vec3 vNormal;

void main() {

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

// Frequency and Amplitude will determine the look of the displacement
float frequency = 20.0;
float amplitude = 0.1;

/* 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(position.x * frequency + uFrameCount * 0.1);
position.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 * position;
}
87 changes: 87 additions & 0 deletions src/data/examples/en/20_3D/12_default_shader_inputs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* @name Default Shader Inputs
* @description
* <p>p5.js provides some default attributes and uniforms that can be used in your shader programs. Attributes provide per vertex information that can be used in a vertex shader. Uniforms provide information that can be used in both vertex and fragment shaders. (All vertices in a vertex shader, and all pixels in a fragment shader receive the same uniform value as input.)</p><br>
* <p><u>Attributes</u></p>
* <p>
* <span>• <b>aPosition</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>vec3</i> (x, y, z)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Position associated with a vertex</span><br>
* <span>• <b>aTexCoord</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>vec2</i> (x, y)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Texture coordinates associated with a vertex</span><br>
* <span>• <b>aNormal</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>vec3</i> (x, y, z)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Normal associated with vertex</span><br>
* <span>• <b>aMaterialColor</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>vec4</i> (r, g, b, a)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Color associated with a vertex</span><br>
* <span>• <b>The following attribute names are reserved:</b></span><br>
* <span>&nbsp;&nbsp;◦ aAmbientColor</span><br>
* </p><br>
* <p><u>Uniforms</u></p>
* <p>
* <span>• <b>uViewMatrix</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>mat4</i> (4x4 matrix)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Contains information about the current camera such as position and rotation. Used to ?</span><br>
* <span>• <b>uProjectionMatrix</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>mat4</i> (4x4 matrix)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Contains information about the current projection such as near and far clipping planes. Used to convert 3D world coordinates into 2D screen coordinates</span><br>
* <span>• <b>uModelViewMatrix</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>mat4</i> (4x4 matrix)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Combination of the model and view matrices. Used to ?</span><br>
* <span>• <b>uModelViewProjectionMatrix</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>mat4</i> (4x4 matrix)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Combination of the model, view, and projection matrices. Used to ?</span><br>
* <span>• <b>uNormalMatrix</b></span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Type: </span><i>mat3</i> (3x3 matrix)</span><br>
* <span>&nbsp;&nbsp;◦ <span class="small">Description: </span>Transpose inverse of the model matrix. Typically used in lighting calculations</span><br>
* <span>• <b>The following uniform names are reserved:</b></span><br>
* <span>&nbsp;&nbsp;◦ uStrokeWeight</span><br>
* </p><br>
* <p>To learn more about using shaders in p5.js see <a href="https://itp-xstory.github.io/p5js-shaders/">p5.js Shaders</a></p><br>
*/

// This variable will hold our shader object
let shaderProgram;

function preload() {
/* A shader is composed of two parts, a vertex shader, and a
fragment shader.
The vertex shader prepares the vertices and geometry to be drawn.
The fragment shader renders the actual pixel colors.

loadShader() is asynchronous so it needs to be in preload.
loadShader() first takes as input the filename of a vertex shader,
and a fragment shader.
These file types are usually .vert and .frag, but you can actually
use anything. .glsl is another common one
*/
shaderProgram = loadShader("assets/shader_defaults.vert", "assets/shader_defaults.frag");
}

function setup() {
// Shaders require WEBGL mode to work
createCanvas(710, 400, WEBGL);
noStroke();
}

function draw() {
background(0);

// shader() sets the active shader with our shader
shader(shaderProgram);

// Send the frameCount to the shader
shaderProgram.setUniform("uFrameCount", frameCount);

// Rotate our geometry on the X and Y axes
rotateX(frameCount * 0.01);
rotateY(frameCount * 0.005);

// Draw some geometry to the screen
/* We're going to tessellate the sphere a bit so we have some more
vertices to work with
*/
sphere(width / 5, 200, 200);
}