<!-- The vertex shader operates on individual vertices in our model data by setting gl_Position -->
<script id="vertex-shader" type="x-shader/x-vertex">
// Each point has a position and color
attribute vec3 position;
attribute vec4 color;
// The transformation matrix
uniform mat4 model;
// Pass the color attribute down to the fragment shader
varying vec4 vColor;
void main() {
//Pass the color down to the fragment shader
vColor = color;
// Multiply the
gl_Position = model * vec4(position, 1.0);
}
</script>
<!-- The fragment shader determines the color of the final pixel by setting gl_FragColor -->
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main() {
gl_FragColor = vColor;
// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>
<canvas id="canvas"></canvas>
<h1 class='lesson-title'>
Model Transform
</h1>
<script>
//Shared code for the examples
// Define the MDN global
var MDN = {};
// Define the data that is needed to make a 3d cube
MDN.createCubeData = function() {
var positions = [
// Front face
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Back face
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Top face
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Bottom face
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Right face
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Left face
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
];
var colorsOfFaces = [
[0.3, 1.0, 1.0, 1.0], // Front face: cyan
[1.0, 0.3, 0.3, 1.0], // Back...
/*
Placing points directly into clip space is of limited use. What's better is to take model data and transform it into clip space. The cube is an easy example of how to do this. The cube data below consists of vertex positions, the colors of the faces of the cube, and the order of the vertex positions that make up the individual polygons (in groups of 3). The positions and colors are stored in buffers and sent to the shader as attributes, and then operated upon individually.
Finally a single model matrix is set that represents the transformations that will be performed on each position that makes up the model to move it into the correct space. In this case, for every frame of the animation, a series of scale, rotation, and translation matrices move the data into the desired spot in clip space. The cube is the size of clip space (-1,-1,-1) to (1,1,1) so it will need to be shrunk down to fit. This matrix is sent to the shader having been multiplied in JavaScript beforehand.
In the shader each position vertex is first transformed into a homogeneous coordinate (vec4), and then multiplied against the model matrix. In
gl_Position = model * vec4(position, 1.0);
It may be noted that in JavaScript matrix multiplication requires a function, while in the shader it is built into the language with the simple * operator.
At this point the W value of the transformed point is still 1.0. The cube still doesn't have any perspective. The next example will take this setup, and fiddle with the W values to provide some perspective.
Exercise:
1) Shrink down the box using the scale matrix and position it in different places within clip space. Try moving it outside of clip space. Resize the window and watch as the box skews out of shape. Add a rotateZ matrix.
2) Modify the MDN.createCubeData() function in /shared/cube.js to change the underlying data for the cube and note how the model transform perserves it. (Make sure and restore it once you are done for the other...
Please Whitelist JSFiddle in your content blocker.
Help keep JSFiddle free for always by one of two ways:
Whitelist JSFiddle in your content blocker (two clicks)
Go PRO and get access to additional PRO features →
Join the 4+ million users, and keep the JSFiddle dream alive.
Ad-free
All ads in the editor and listing pages are turned completely off.
Use pre-released features
You get to try and use features (like the Palette Color Generator) months before everyone else.
Fiddle collections
Sort and categorize your Fiddles into multiple collections.
Private collections and fiddles
You can make as many Private Fiddles, and Private Collections as you wish!
Console
Debug your Fiddle with a minimal built-in JavaScript console.