diff --git a/files/en-us/web/api/webgl_api/basic_2d_animation_example/index.md b/files/en-us/web/api/webgl_api/basic_2d_animation_example/index.md index 80aeb4f46ff5a05..e70113182fa562d 100644 --- a/files/en-us/web/api/webgl_api/basic_2d_animation_example/index.md +++ b/files/en-us/web/api/webgl_api/basic_2d_animation_example/index.md @@ -13,7 +13,7 @@ tags: - WebGL API --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} In this WebGL example, we create a canvas and within it render a rotating square using WebGL. The coordinate system we use to represent our scene is the same as the canvas's coordinate system. That is, (0, 0) is at the top-left corner and the bottom-right corner is at (600, 460). @@ -131,23 +131,22 @@ function startup() { const shaderSet = [ { type: gl.VERTEX_SHADER, - id: "vertex-shader" + id: "vertex-shader", }, { type: gl.FRAGMENT_SHADER, - id: "fragment-shader" - } + id: "fragment-shader", + }, ]; shaderProgram = buildShaderProgram(shaderSet); - aspectRatio = glCanvas.width/glCanvas.height; + aspectRatio = glCanvas.width / glCanvas.height; currentRotation = [0, 1]; currentScale = [1.0, aspectRatio]; vertexArray = new Float32Array([ - -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, - -0.5, 0.5, 0.5, -0.5, -0.5, -0.5 + -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, ]); vertexBuffer = gl.createBuffer(); @@ -155,7 +154,7 @@ function startup() { gl.bufferData(gl.ARRAY_BUFFER, vertexArray, gl.STATIC_DRAW); vertexNumComponents = 2; - vertexCount = vertexArray.length/vertexNumComponents; + vertexCount = vertexArray.length / vertexNumComponents; currentAngle = 0.0; @@ -197,7 +196,7 @@ function buildShaderProgram(shaderInfo) { } }); - gl.linkProgram(program) + gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { console.log("Error linking shader program:"); @@ -233,7 +232,11 @@ function compileShader(id, type) { gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - console.log(`Error compiling ${type === gl.VERTEX_SHADER ? "vertex" : "fragment"} shader:`); + console.log( + `Error compiling ${ + type === gl.VERTEX_SHADER ? "vertex" : "fragment" + } shader:` + ); console.log(gl.getShaderInfoLog(shader)); } return shader; @@ -258,18 +261,15 @@ function animateScene() { gl.clearColor(0.8, 0.9, 1.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT); - const radians = currentAngle * Math.PI / 180.0; + const radians = (currentAngle * Math.PI) / 180.0; currentRotation[0] = Math.sin(radians); currentRotation[1] = Math.cos(radians); gl.useProgram(shaderProgram); - uScalingFactor = - gl.getUniformLocation(shaderProgram, "uScalingFactor"); - uGlobalColor = - gl.getUniformLocation(shaderProgram, "uGlobalColor"); - uRotationVector = - gl.getUniformLocation(shaderProgram, "uRotationVector"); + uScalingFactor = gl.getUniformLocation(shaderProgram, "uScalingFactor"); + uGlobalColor = gl.getUniformLocation(shaderProgram, "uGlobalColor"); + uRotationVector = gl.getUniformLocation(shaderProgram, "uRotationVector"); gl.uniform2fv(uScalingFactor, currentScale); gl.uniform2fv(uRotationVector, currentRotation); @@ -277,17 +277,23 @@ function animateScene() { gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); - aVertexPosition = - gl.getAttribLocation(shaderProgram, "aVertexPosition"); + aVertexPosition = gl.getAttribLocation(shaderProgram, "aVertexPosition"); gl.enableVertexAttribArray(aVertexPosition); - gl.vertexAttribPointer(aVertexPosition, vertexNumComponents, - gl.FLOAT, false, 0, 0); + gl.vertexAttribPointer( + aVertexPosition, + vertexNumComponents, + gl.FLOAT, + false, + 0, + 0 + ); gl.drawArrays(gl.TRIANGLES, 0, vertexCount); requestAnimationFrame((currentTime) => { - const deltaAngle = ((currentTime - previousTime) / 1000.0) * degreesPerSecond; + const deltaAngle = + ((currentTime - previousTime) / 1000.0) * degreesPerSecond; currentAngle = (currentAngle + deltaAngle) % 360; diff --git a/files/en-us/web/api/webgl_api/compressed_texture_formats/index.md b/files/en-us/web/api/webgl_api/compressed_texture_formats/index.md index 1e7d7ea3e066f7c..43e6a93f9091803 100644 --- a/files/en-us/web/api/webgl_api/compressed_texture_formats/index.md +++ b/files/en-us/web/api/webgl_api/compressed_texture_formats/index.md @@ -4,6 +4,8 @@ slug: Web/API/WebGL_API/Compressed_texture_formats page-type: guide --- +{{DefaultAPISidebar("WebGL")}} + The WebGL API provides methods to use compressed texture formats. These are useful to increase texture detail while limiting the additional video memory necessary. By default, no compressed formats are available: a corresponding compressed texture format extension must first be enabled. ## Usage @@ -35,17 +37,21 @@ All formats support 2D textures. Which formats support `TEXTURE_2D_ARRAY` and `T async function getCompressedTextureIfAvailable(gl) { const texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, texture); // create texture object on GPU - const ext = gl.getExtension('WEBGL_compressed_texture_s3tc'); // will be null if not supported + const ext = gl.getExtension("WEBGL_compressed_texture_s3tc"); // will be null if not supported if (ext) { // the file is already in the correct compressed format - const dataArrayBuffer = await fetch('/textures/foobar512x512.RGBA_S3TC_DXT1') - .then((response) => response.arrayBuffer()); - gl.compressedTexImage2D(gl.TEXTURE_2D, + const dataArrayBuffer = await fetch( + "/textures/foobar512x512.RGBA_S3TC_DXT1" + ).then((response) => response.arrayBuffer()); + gl.compressedTexImage2D( + gl.TEXTURE_2D, 0, // set the base image level ext.COMPRESSED_RGBA_S3TC_DXT1_EXT, // the compressed format we are using - 512, 512, // width, height of the image + 512, + 512, // width, height of the image 0, // border, always 0 - new DataView(dataArrayBuffer)); + new DataView(dataArrayBuffer) + ); gl.generateMipMap(); // create mipmap levels, like we would for a standard image return texture; } diff --git a/files/en-us/web/api/webgl_api/constants/index.md b/files/en-us/web/api/webgl_api/constants/index.md index a94ce6ae16db922..3a0592c8a4aa0d7 100644 --- a/files/en-us/web/api/webgl_api/constants/index.md +++ b/files/en-us/web/api/webgl_api/constants/index.md @@ -12,15 +12,15 @@ spec-urls: - https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7 --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} The [WebGL API](/en-US/docs/Web/API/WebGL_API) provides several constants that are passed into or returned by functions. All constants are of type {{domxref("WebGL_API/Types", "GLenum")}}. Standard WebGL constants are installed on the {{domxref("WebGLRenderingContext")}} and {{domxref("WebGL2RenderingContext")}} objects, so that you use them as `gl.CONSTANT_NAME`: ```js -const canvas = document.getElementById('myCanvas'); -const gl = canvas.getContext('webgl'); +const canvas = document.getElementById("myCanvas"); +const gl = canvas.getContext("webgl"); gl.getParameter(gl.LINE_WIDTH); ``` @@ -28,7 +28,7 @@ gl.getParameter(gl.LINE_WIDTH); Some constants are also provided by [WebGL extensions](/en-US/docs/Web/API/WebGL_API/Using_Extensions). A [list](#constants_defined_in_webgl_extensions) is provided below. ```js -const debugInfo = gl.getExtension('WEBGL_debug_renderer_info'); +const debugInfo = gl.getExtension("WEBGL_debug_renderer_info"); const vendor = gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL); ``` diff --git a/files/en-us/web/api/webgl_api/data/index.md b/files/en-us/web/api/webgl_api/data/index.md index 4a8085d4ea1942b..c37989e71a48b3d 100644 --- a/files/en-us/web/api/webgl_api/data/index.md +++ b/files/en-us/web/api/webgl_api/data/index.md @@ -18,7 +18,7 @@ tags: - WebGL API --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} Shader programs have access to three kinds of data storage, each of which has a specific use case. Each kind of variable is accessible by one or both types of shader program (depending on the data store type) and possibly by the site's JavaScript code, depending on the specific type of variable. @@ -37,14 +37,14 @@ There are three kinds of "variable" or data storage available in GLSL, each of w ```js // init colors const vertexColors = [ - vec4(0.0, 0.0, 0.0, 1.0), // black - vec4(1.0, 0.0, 0.0, 1.0), // red - vec4(1.0, 1.0, 0.0, 1.0), // yellow - vec4(0.0, 1.0, 0.0, 1.0), // green - vec4(0.0, 0.0, 0.0, 1.0), // black - vec4(1.0, 0.0, 0.0, 1.0), // red - vec4(1.0, 1.0, 0.0, 1.0), // yellow - vec4(0.0, 1.0, 0.0, 1.0), // green + vec4(0.0, 0.0, 0.0, 1.0), // black + vec4(1.0, 0.0, 0.0, 1.0), // red + vec4(1.0, 1.0, 0.0, 1.0), // yellow + vec4(0.0, 1.0, 0.0, 1.0), // green + vec4(0.0, 0.0, 0.0, 1.0), // black + vec4(1.0, 0.0, 0.0, 1.0), // red + vec4(1.0, 1.0, 0.0, 1.0), // yellow + vec4(0.0, 1.0, 0.0, 1.0), // green ]; const cBuffer = gl.createBuffer(); ``` diff --git a/files/en-us/web/api/webgl_api/index.md b/files/en-us/web/api/webgl_api/index.md index c910bb9d8ef7ad8..8466e5d837e668e 100644 --- a/files/en-us/web/api/webgl_api/index.md +++ b/files/en-us/web/api/webgl_api/index.md @@ -1,5 +1,5 @@ --- -title: 'WebGL: 2D and 3D graphics for the web' +title: "WebGL: 2D and 3D graphics for the web" slug: Web/API/WebGL_API page-type: web-api-overview tags: @@ -19,7 +19,7 @@ browser-compat: - api.WebGL2RenderingContext --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} **WebGL** (Web Graphics Library) is a JavaScript API for rendering high-performance interactive 3D and 2D graphics within any compatible web browser without the use of plug-ins. WebGL does so by introducing an API that closely conforms to OpenGL ES 2.0 that can be used in HTML {{HTMLElement("canvas")}} elements. This conformance makes it possible for the API to take advantage of hardware graphics acceleration provided by the user's device. diff --git a/files/en-us/web/api/webgl_api/matrix_math_for_the_web/index.md b/files/en-us/web/api/webgl_api/matrix_math_for_the_web/index.md index ea0a7312526980a..b7085761b94570a 100644 --- a/files/en-us/web/api/webgl_api/matrix_math_for_the_web/index.md +++ b/files/en-us/web/api/webgl_api/matrix_math_for_the_web/index.md @@ -18,7 +18,7 @@ tags: - transform3d --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} Matrices can be used to represent transformations of objects in space, and are used for performing many key types of computation when constructing images and visualizing data on the Web. This article explores how to create matrices and how to use them with [CSS transforms](/en-US/docs/Web/CSS/CSS_Transforms/Using_CSS_transforms) and the `matrix3d` transform type. @@ -33,12 +33,7 @@ Let's begin by considering the **identity matrix**. This is a special transforma The identity matrix looks like this in JavaScript: ```js -let identityMatrix = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 -]; +let identityMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; ``` What does multiplying by the identity matrix look like? The easiest example is to multiply a single point by the identity matrix. Since a 3D point only needs three values (x, y, and z), and the transformation matrix is a 4x4 value matrix, we need to add a fourth dimension to the point. By convention, this dimension is called the **perspective**, and is represented by the letter w. For a typical position, setting w to 1 will make the math work out. @@ -46,12 +41,7 @@ What does multiplying by the identity matrix look like? The easiest example is t After adding the w component to the point, notice how neatly the matrix and the point line up: ```js -[1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1] - -[4, 3, 2, 1] // Point at [x, y, z, w] +[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1][(4, 3, 2, 1)]; // Point at [x, y, z, w] ``` The w component has some additional uses that are out of scope for this article. Check out the [WebGL model view projection](/en-US/docs/Web/API/WebGL_API/WebGL_model_view_projection) article for a look into how it comes in handy. @@ -64,10 +54,22 @@ In our example code we have defined a function to multiply a matrix and a point // point • matrix function multiplyMatrixAndPoint(matrix, point) { // Give a simple variable name to each part of the matrix, a column and row number - let c0r0 = matrix[ 0], c1r0 = matrix[ 1], c2r0 = matrix[ 2], c3r0 = matrix[ 3]; - let c0r1 = matrix[ 4], c1r1 = matrix[ 5], c2r1 = matrix[ 6], c3r1 = matrix[ 7]; - let c0r2 = matrix[ 8], c1r2 = matrix[ 9], c2r2 = matrix[10], c3r2 = matrix[11]; - let c0r3 = matrix[12], c1r3 = matrix[13], c2r3 = matrix[14], c3r3 = matrix[15]; + let c0r0 = matrix[0], + c1r0 = matrix[1], + c2r0 = matrix[2], + c3r0 = matrix[3]; + let c0r1 = matrix[4], + c1r1 = matrix[5], + c2r1 = matrix[6], + c3r1 = matrix[7]; + let c0r2 = matrix[8], + c1r2 = matrix[9], + c2r2 = matrix[10], + c3r2 = matrix[11]; + let c0r3 = matrix[12], + c1r3 = matrix[13], + c2r3 = matrix[14], + c3r3 = matrix[15]; // Now set some simple names for the point let x = point[0]; @@ -76,16 +78,16 @@ function multiplyMatrixAndPoint(matrix, point) { let w = point[3]; // Multiply the point against each part of the 1st column, then add together - let resultX = (x * c0r0) + (y * c0r1) + (z * c0r2) + (w * c0r3); + let resultX = x * c0r0 + y * c0r1 + z * c0r2 + w * c0r3; // Multiply the point against each part of the 2nd column, then add together - let resultY = (x * c1r0) + (y * c1r1) + (z * c1r2) + (w * c1r3); + let resultY = x * c1r0 + y * c1r1 + z * c1r2 + w * c1r3; // Multiply the point against each part of the 3rd column, then add together - let resultZ = (x * c2r0) + (y * c2r1) + (z * c2r2) + (w * c2r3); + let resultZ = x * c2r0 + y * c2r1 + z * c2r2 + w * c2r3; // Multiply the point against each part of the 4th column, then add together - let resultW = (x * c3r0) + (y * c3r1) + (z * c3r2) + (w * c3r3); + let resultW = x * c3r0 + y * c3r1 + z * c3r2 + w * c3r3; return [resultX, resultY, resultZ, resultW]; } @@ -108,9 +110,9 @@ In addition to multiplying a matrix and a point together, you can also multiply //matrixB • matrixA function multiplyMatrices(matrixA, matrixB) { // Slice the second matrix up into rows - let row0 = [matrixB[ 0], matrixB[ 1], matrixB[ 2], matrixB[ 3]]; - let row1 = [matrixB[ 4], matrixB[ 5], matrixB[ 6], matrixB[ 7]]; - let row2 = [matrixB[ 8], matrixB[ 9], matrixB[10], matrixB[11]]; + let row0 = [matrixB[0], matrixB[1], matrixB[2], matrixB[3]]; + let row1 = [matrixB[4], matrixB[5], matrixB[6], matrixB[7]]; + let row2 = [matrixB[8], matrixB[9], matrixB[10], matrixB[11]]; let row3 = [matrixB[12], matrixB[13], matrixB[14], matrixB[15]]; // Multiply each row by matrixA @@ -121,10 +123,22 @@ function multiplyMatrices(matrixA, matrixB) { // Turn the result rows back into a single matrix return [ - result0[0], result0[1], result0[2], result0[3], - result1[0], result1[1], result1[2], result1[3], - result2[0], result2[1], result2[2], result2[3], - result3[0], result3[1], result3[2], result3[3] + result0[0], + result0[1], + result0[2], + result0[3], + result1[0], + result1[1], + result1[2], + result1[3], + result2[0], + result2[1], + result2[2], + result2[3], + result3[0], + result3[1], + result3[2], + result3[3], ]; } ``` @@ -132,19 +146,9 @@ function multiplyMatrices(matrixA, matrixB) { Let's look at this function in action: ```js -let someMatrix = [ - 4, 0, 0, 0, - 0, 3, 0, 0, - 0, 0, 5, 0, - 4, 8, 4, 1 -] - -let identityMatrix = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 -]; +let someMatrix = [4, 0, 0, 0, 0, 3, 0, 0, 0, 0, 5, 0, 4, 8, 4, 1]; + +let identityMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; // Returns a new array equivalent to someMatrix let someMatrixResult = multiplyMatrices(identityMatrix, someMatrix); @@ -163,12 +167,7 @@ let x = 50; let y = 100; let z = 0; -let translationMatrix = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - x, y, z, 1 -]; +let translationMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1]; ``` Place the distances along the three axes in the corresponding positions in the translation matrix, then multiply it by the point or matrix you need to move through 3D space. @@ -189,11 +188,11 @@ Finally, for each of the examples we will generate a 4x4 matrix, then update the ```js // Create the matrix3d style property from a matrix array function matrixArrayToCssMatrix(array) { - return `matrix3d(${array.join(',')})`; + return `matrix3d(${array.join(",")})`; } // Grab the DOM element -let moveMe = document.getElementById('move-me'); +let moveMe = document.getElementById("move-me"); // Returns a result like: "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 50, 100, 0, 1);" let matrix3dRule = matrixArrayToCssMatrix(translationMatrix); @@ -215,14 +214,9 @@ The amount of change to apply to each of the width, height, and depth is placed ```js let w = 1.5; // width (x) let h = 0.7; // height (y) -let d = 1; // depth (z) +let d = 1; // depth (z) -let scaleMatrix = [ - w, 0, 0, 0, - 0, h, 0, 0, - 0, 0, d, 0, - 0, 0, 0, 1 -]; +let scaleMatrix = [w, 0, 0, 0, 0, h, 0, 0, 0, 0, d, 0, 0, 0, 0, 1]; ``` [View on JSFiddle](https://jsfiddle.net/tatumcreative/fndd6e1b/) @@ -247,7 +241,7 @@ let rotationInRadians = Math.PI / 3; let transformedPoint = [ Math.cos(rotationInRadians) * distance, - Math.sin(rotationInRadians) * distance + Math.sin(rotationInRadians) * distance, ]; ``` @@ -264,10 +258,22 @@ let a = Math.PI * 0.3; //Rotation amount in radians // Rotate around Z axis let rotateZMatrix = [ - cos(a), -sin(a), 0, 0, - sin(a), cos(a), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + cos(a), + -sin(a), + 0, + 0, + sin(a), + cos(a), + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, ]; ``` @@ -279,30 +285,15 @@ Here are a set of functions that return rotation matrices for rotating around ea ```js function rotateAroundXAxis(a) { - return [ - 1, 0, 0, 0, - 0, cos(a), -sin(a), 0, - 0, sin(a), cos(a), 0, - 0, 0, 0, 1 - ]; + return [1, 0, 0, 0, 0, cos(a), -sin(a), 0, 0, sin(a), cos(a), 0, 0, 0, 0, 1]; } function rotateAroundYAxis(a) { - return [ - cos(a), 0, sin(a), 0, - 0, 1, 0, 0, - -sin(a), 0, cos(a), 0, - 0, 0, 0, 1 - ]; + return [cos(a), 0, sin(a), 0, 0, 1, 0, 0, -sin(a), 0, cos(a), 0, 0, 0, 0, 1]; } function rotateAroundZAxis(a) { - return [ - cos(a), -sin(a), 0, 0, - sin(a), cos(a), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - ]; + return [cos(a), -sin(a), 0, 0, sin(a), cos(a), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; } ``` @@ -326,9 +317,9 @@ The function that we will be using to compose our matrices is `multiplyArrayOfMa ```js let transformMatrix = MDN.multiplyArrayOfMatrices([ - rotateAroundZAxis(Math.PI * 0.5), // Step 3: rotate around 90 degrees - translate(0, 200, 0), // Step 2: move down 200 pixels - scale(0.8, 0.8, 0.8), // Step 1: scale down + rotateAroundZAxis(Math.PI * 0.5), // Step 3: rotate around 90 degrees + translate(0, 200, 0), // Step 2: move down 200 pixels + scale(0.8, 0.8, 0.8), // Step 1: scale down ]); ``` @@ -340,12 +331,12 @@ Finally, a fun step to show how matrices work is to reverse the steps to bring t ```js let transformMatrix = MDN.multiplyArrayOfMatrices([ - scale(1.25, 1.25, 1.25), // Step 6: scale back up - translate(0, -200, 0), // Step 5: move back up - rotateAroundZAxis(-Math.PI * 0.5), // Step 4: rotate back - rotateAroundZAxis(Math.PI * 0.5), // Step 3: rotate around 90 degrees - translate(0, 200, 0), // Step 2: move down 200 pixels - scale(0.8, 0.8, 0.8), // Step 1: scale down + scale(1.25, 1.25, 1.25), // Step 6: scale back up + translate(0, -200, 0), // Step 5: move back up + rotateAroundZAxis(-Math.PI * 0.5), // Step 4: rotate back + rotateAroundZAxis(Math.PI * 0.5), // Step 3: rotate around 90 degrees + translate(0, 200, 0), // Step 2: move down 200 pixels + scale(0.8, 0.8, 0.8), // Step 1: scale down ]); ``` diff --git a/files/en-us/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.md b/files/en-us/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.md index accee3760bbb1c4..09f0ebe8cec248a 100644 --- a/files/en-us/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/adding_2d_content_to_a_webgl_context/index.md @@ -15,7 +15,7 @@ tags: - WebGL API --- -{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}} +{{DefaultAPISidebar("WebGL")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL")}} Once you've successfully [created a WebGL context](/en-US/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL), you can start rendering into it. A simple thing we can do is draw an untextured square plane, so let's start there. diff --git a/files/en-us/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.md b/files/en-us/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.md index 3e57d17539bfc33..a0460e8cd54079c 100644 --- a/files/en-us/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/animating_objects_with_webgl/index.md @@ -7,7 +7,7 @@ tags: - WebGL --- -{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL") }} +{{DefaultAPISidebar("WebGL")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", "Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL") }} ## Making the square rotate diff --git a/files/en-us/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.md b/files/en-us/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.md index 472ca02d2e78595..6dccc50b5b9eb01 100644 --- a/files/en-us/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/animating_textures_in_webgl/index.md @@ -9,7 +9,7 @@ tags: - WebGL --- -{{WebGLSidebar("Tutorial") }} {{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}} +{{DefaultAPISidebar("WebGL")}} {{Previous("Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}} In this demonstration, we build upon the previous example by replacing our static textures with the frames of an mp4 video file that's playing. This is actually pretty easy to do and fun to watch, so let's get started. You can use similar code to use any sort of data (such as a {{ HTMLElement("canvas") }}) as the source for your textures. diff --git a/files/en-us/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.md b/files/en-us/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.md index 230fc73525f3348..e66b5bc57596cd5 100644 --- a/files/en-us/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/creating_3d_objects_using_webgl/index.md @@ -12,7 +12,7 @@ tags: - rendering --- -{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}} +{{DefaultAPISidebar("WebGL")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", "Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL")}} Let's take our square plane into three dimensions by adding five more faces to create a cube. To do this efficiently, we're going to switch from drawing using the vertices directly by calling the {{domxref("WebGLRenderingContext.drawArrays()", "gl.drawArrays()")}} method to using the vertex array as a table, and referencing individual vertices in that table to define the positions of each face's vertices, by calling {{domxref("WebGLRenderingContext.drawElements()", "gl.drawElements()")}}. diff --git a/files/en-us/web/api/webgl_api/tutorial/getting_started_with_webgl/index.md b/files/en-us/web/api/webgl_api/tutorial/getting_started_with_webgl/index.md index 3ac6286ca56acaf..5e2e65eb74cd3a3 100644 --- a/files/en-us/web/api/webgl_api/tutorial/getting_started_with_webgl/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/getting_started_with_webgl/index.md @@ -7,7 +7,7 @@ tags: - WebGL --- -{{WebGLSidebar("Tutorial")}} {{Next("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context")}} +{{DefaultAPISidebar("WebGL")}} {{Next("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context")}} [WebGL](/en-US/docs/Web/API/WebGL_API) enables web content to use an API based on [OpenGL ES](https://www.khronos.org/opengles/) 2.0 to perform 2D and 3D rendering in an HTML [`canvas`](/en-US/docs/Web/API/Canvas_API) in browsers that support it without the use of plug-ins. diff --git a/files/en-us/web/api/webgl_api/tutorial/index.md b/files/en-us/web/api/webgl_api/tutorial/index.md index 19af202583b2a77..6fcda6b5cbceff0 100644 --- a/files/en-us/web/api/webgl_api/tutorial/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/index.md @@ -9,7 +9,7 @@ tags: - WebGL API --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} This tutorial describes how to use the {{HTMLElement("canvas")}} element to draw WebGL graphics, starting with the basics. The examples provided should give you some clear ideas of what you can do with WebGL and will provide code snippets that may get you started in building your own content. diff --git a/files/en-us/web/api/webgl_api/tutorial/lighting_in_webgl/index.md b/files/en-us/web/api/webgl_api/tutorial/lighting_in_webgl/index.md index a1735026a1fb989..768fd9a159e2a4b 100644 --- a/files/en-us/web/api/webgl_api/tutorial/lighting_in_webgl/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/lighting_in_webgl/index.md @@ -17,7 +17,7 @@ tags: - vertices --- -{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}} +{{DefaultAPISidebar("WebGL")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL", "Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL")}} As should be clear by now, WebGL doesn't have much built-in knowledge. It just runs two functions you supply — a vertex shader and a fragment shader — and expects you to write creative functions to get the results you want. In other words, if you want lighting you have to calculate it yourself. Fortunately, it's not all that hard to do, and this article will cover some of the basics. diff --git a/files/en-us/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.md b/files/en-us/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.md index 694708500893586..85232c0f8d0dc3a 100644 --- a/files/en-us/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/using_shaders_to_apply_color_in_webgl/index.md @@ -8,7 +8,7 @@ tags: - WebGL --- -{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL")}} +{{DefaultAPISidebar("WebGL")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", "Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL")}} Having created a square plane in the [previous demonstration](/en-US/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context), the next obvious step is to add a splash of color to it. We can do this by revising the shaders. diff --git a/files/en-us/web/api/webgl_api/tutorial/using_textures_in_webgl/index.md b/files/en-us/web/api/webgl_api/tutorial/using_textures_in_webgl/index.md index efbaf40f3d9af54..3849fc55f37b5b4 100644 --- a/files/en-us/web/api/webgl_api/tutorial/using_textures_in_webgl/index.md +++ b/files/en-us/web/api/webgl_api/tutorial/using_textures_in_webgl/index.md @@ -7,7 +7,7 @@ tags: - WebGL --- -{{WebGLSidebar("Tutorial")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}} +{{DefaultAPISidebar("WebGL")}} {{PreviousNext("Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", "Web/API/WebGL_API/Tutorial/Lighting_in_WebGL")}} Now that our sample program has a rotating 3D cube, let's map a texture onto it instead of having its faces be solid colors. diff --git a/files/en-us/web/api/webgl_api/types/index.md b/files/en-us/web/api/webgl_api/types/index.md index 846cfd5ad3101bc..70038aa39b32e5d 100644 --- a/files/en-us/web/api/webgl_api/types/index.md +++ b/files/en-us/web/api/webgl_api/types/index.md @@ -12,7 +12,7 @@ spec-urls: - https://www.khronos.org/registry/webgl/extensions/EXT_disjoint_timer_query/ --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} The following types are used in [WebGL](/en-US/docs/Web/API/WebGL_API) interfaces. diff --git a/files/en-us/web/api/webgl_api/using_extensions/index.md b/files/en-us/web/api/webgl_api/using_extensions/index.md index f966dd883bea0c1..b3f01cc5e810e50 100644 --- a/files/en-us/web/api/webgl_api/using_extensions/index.md +++ b/files/en-us/web/api/webgl_api/using_extensions/index.md @@ -7,7 +7,7 @@ tags: - WebGL --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} WebGL, like its sister APIs (OpenGL and OpenGL ES), supports extensions. A complete list of extensions is available in the [khronos webgl extension registry](https://www.khronos.org/registry/webgl/extensions/). @@ -20,11 +20,10 @@ Extensions may be supported by browser vendors before being officially ratified If you wish to work with the bleeding edge of extensions, and want to keep working on upon ratification (assuming, of course, that the extension doesn't change in incompatible ways), that you query the canonical extension name as well as the vendor extension name. For instance: ```js -const ext = ( - gl.getExtension('OES_vertex_array_object') || - gl.getExtension('MOZ_OES_vertex_array_object') || - gl.getExtension('WEBKIT_OES_vertex_array_object') -); +const ext = + gl.getExtension("OES_vertex_array_object") || + gl.getExtension("MOZ_OES_vertex_array_object") || + gl.getExtension("WEBKIT_OES_vertex_array_object"); ``` Note that, vendor prefix have been discouraged thus most browser implement experimental extensions behind a feature flag rather than vendor prefix. @@ -102,7 +101,7 @@ The current extensions are: Before an extension can be used it has to be enabled using {{domxref("WebGLRenderingContext.getExtension()")}}. For example: ```js -const float_texture_ext = gl.getExtension('OES_texture_float'); +const float_texture_ext = gl.getExtension("OES_texture_float"); ``` The return value is `null` if the extension is not supported, or an extension object otherwise. diff --git a/files/en-us/web/api/webgl_api/webgl_best_practices/index.md b/files/en-us/web/api/webgl_api/webgl_best_practices/index.md index 73b1fb3da636c6a..464adc091a98c4b 100644 --- a/files/en-us/web/api/webgl_api/webgl_best_practices/index.md +++ b/files/en-us/web/api/webgl_api/webgl_best_practices/index.md @@ -15,7 +15,7 @@ tags: - WebGL --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} WebGL is a complicated API, and it's often not obvious what the recommended ways to use it are. This page tackles recommendations across the spectrum of expertise, and not only highlights dos and don'ts, but also details _why_. You can rely on this document to guide your choice of approach, and ensure you're on the right track no matter what browser or hardware your users run. @@ -220,7 +220,7 @@ While we've described a pattern to allow browsers to compile and link in paralle Example usage: ```js -ext = gl.getExtension('KHR_parallel_shader_compile'); +ext = gl.getExtension("KHR_parallel_shader_compile"); gl.compileProgram(vs); gl.compileProgram(fs); gl.attachShader(prog, vs); @@ -553,8 +553,14 @@ function clientWaitAsync(gl, sync, flags, interval_ms) { } async function getBufferSubDataAsync( - gl, target, buffer, srcByteOffset, dstBuffer, - /* optional */ dstOffset, /* optional */ length) { + gl, + target, + buffer, + srcByteOffset, + dstBuffer, + /* optional */ dstOffset, + /* optional */ length +) { const sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0); gl.flush(); @@ -595,24 +601,26 @@ Demo: [Device pixel presnap](https://kdashg.github.io/misc/webgl/device-pixel-pr On supporting browsers (Chromium?), `ResizeObserver` can be used with `'device-pixel-content-box'` to request a callback that includes the true device pixel size of an element. This can be used to build an async-but-accurate function: ```js -window.getDevicePixelSize = window.getDevicePixelSize || (async (elem) => { - await new Promise((fn_resolve) => { +window.getDevicePixelSize = + window.getDevicePixelSize || + (async (elem) => { + await new Promise((fn_resolve) => { const observer = new ResizeObserver((entries) => { - for (const cur of entries) { - const dev_size = cur.devicePixelContentBoxSize; - const ret = { - width: dev_size[0].inlineSize, - height: dev_size[0].blockSize, - }; - fn_resolve(ret); - observer.disconnect(); - return; - } - throw `device-pixel-content-box not observed for elem ${elem}`; + for (const cur of entries) { + const dev_size = cur.devicePixelContentBoxSize; + const ret = { + width: dev_size[0].inlineSize, + height: dev_size[0].blockSize, + }; + fn_resolve(ret); + observer.disconnect(); + return; + } + throw `device-pixel-content-box not observed for elem ${elem}`; }); - observer.observe(elem, {box: 'device-pixel-content-box'}); - }); -}); + observer.observe(elem, { box: "device-pixel-content-box" }); + }); + }); ``` Please refer to [the specification](https://www.w3.org/TR/resize-observer/#resize-observer-interface) for more details. diff --git a/files/en-us/web/api/webgl_api/webgl_model_view_projection/index.md b/files/en-us/web/api/webgl_api/webgl_model_view_projection/index.md index 4bcd8f011eefdd0..c2fa757f958d39c 100644 --- a/files/en-us/web/api/webgl_api/webgl_model_view_projection/index.md +++ b/files/en-us/web/api/webgl_api/webgl_model_view_projection/index.md @@ -17,7 +17,7 @@ tags: - rotation --- -{{WebGLSidebar}} +{{DefaultAPISidebar("WebGL")}} This article explores how to take data within a [WebGL](/en-US/docs/Web/API/WebGL_API) project, and project it into the proper spaces to display it on the screen. It assumes a knowledge of basic matrix math using translation, scale, and rotation matrices. It explains the three core matrices that are typically used when composing a 3D scene: the model, view and projection matrices. @@ -54,7 +54,7 @@ The constructor looks like this: ```js function WebGLBox() { // Setup the canvas and WebGL context - this.canvas = document.getElementById('canvas'); + this.canvas = document.getElementById("canvas"); this.canvas.width = window.innerWidth; this.canvas.height = window.innerHeight; this.gl = MDN.createContext(canvas); @@ -62,17 +62,20 @@ function WebGLBox() { const gl = this.gl; // Setup a WebGL program, anything part of the MDN object is defined outside of this article - this.webglProgram = MDN.createWebGLProgramFromIds(gl, 'vertex-shader', 'fragment-shader'); + this.webglProgram = MDN.createWebGLProgramFromIds( + gl, + "vertex-shader", + "fragment-shader" + ); gl.useProgram(this.webglProgram); // Save the attribute and uniform locations - this.positionLocation = gl.getAttribLocation(this.webglProgram, 'position'); - this.colorLocation = gl.getUniformLocation(this.webglProgram, 'color'); + this.positionLocation = gl.getAttribLocation(this.webglProgram, "position"); + this.colorLocation = gl.getUniformLocation(this.webglProgram, "color"); // Tell WebGL to test the depth when drawing, so if a square is behind // another square it won't be drawn gl.enable(gl.DEPTH_TEST); - } ``` @@ -86,16 +89,27 @@ WebGLBox.prototype.draw = function (settings) { // drawn to the screen. There are two that form a square. const data = new Float32Array([ - //Triangle 1 - settings.left, settings.bottom, settings.depth, - settings.right, settings.bottom, settings.depth, - settings.left, settings.top, settings.depth, + settings.left, + settings.bottom, + settings.depth, + settings.right, + settings.bottom, + settings.depth, + settings.left, + settings.top, + settings.depth, //Triangle 2 - settings.left, settings.top, settings.depth, - settings.right, settings.bottom, settings.depth, - settings.right, settings.top, settings.depth + settings.left, + settings.top, + settings.depth, + settings.right, + settings.bottom, + settings.depth, + settings.right, + settings.top, + settings.depth, ]); // Use WebGL to draw this onto the screen. @@ -119,7 +133,7 @@ WebGLBox.prototype.draw = function (settings) { // Draw the triangles to the screen gl.drawArrays(gl.TRIANGLES, 0, 6); -} +}; ``` The shaders are the bits of code written in GLSL that take our data points and ultimately render them to the screen. For convenience, these shaders are stored in a {{htmlelement("script")}} element that is brought into the program through the custom function `MDN.createWebGLProgramFromIds()`. This function is part of a collection of [utility functions](https://github.com/gregtatum/mdn-webgl) written for these tutorials and is not explained in depth here. This function handles the basics of taking some GLSL source code and compiling it into a WebGL program. The function takes three parameters — the context to render the program in, the ID of the {{htmlelement("script")}} element containing the vertex shader, and the ID of the {{htmlelement("script")}} element containing the fragment shader. The vertex shader positions the vertices, and the fragment shader colors each pixel. @@ -157,13 +171,13 @@ First draw a red box in the middle. ```js box.draw({ - top : 0.5, // x - bottom : -0.5, // x - left : -0.5, // y - right : 0.5, // y + top: 0.5, // x + bottom: -0.5, // x + left: -0.5, // y + right: 0.5, // y - depth : 0, // z - color : [1, 0.4, 0.4, 1] // red + depth: 0, // z + color: [1, 0.4, 0.4, 1], // red }); ``` @@ -171,13 +185,13 @@ Next, draw a green box up top and behind the red box. ```js box.draw({ - top : 0.9, // x - bottom : 0, // x - left : -0.9, // y - right : 0.9, // y + top: 0.9, // x + bottom: 0, // x + left: -0.9, // y + right: 0.9, // y - depth : 0.5, // z - color : [0.4, 1, 0.4, 1] // green + depth: 0.5, // z + color: [0.4, 1, 0.4, 1], // green }); ``` @@ -185,13 +199,13 @@ Finally, for demonstration that clipping is actually going on, this box doesn't ```js box.draw({ - top : 1, // x - bottom : -1, // x - left : -1, // y - right : 1, // y + top: 1, // x + bottom: -1, // x + left: -1, // y + right: 1, // y - depth : -1.5, // z - color : [0.4, 0.4, 1, 1] // blue + depth: -1.5, // z + color: [0.4, 0.4, 1, 1], // blue }); ``` @@ -234,7 +248,7 @@ function homogeneousToCartesian(point) { let z = point[2]; let w = point[3]; - return [x/w, y/w, z/w]; + return [x / w, y / w, z / w]; } ``` @@ -260,14 +274,32 @@ To start playing with this idea the previous example can be modified to allow fo //Redefine the triangles to use the W component const data = new Float32Array([ //Triangle 1 - settings.left, settings.bottom, settings.depth, settings.w, - settings.right, settings.bottom, settings.depth, settings.w, - settings.left, settings.top, settings.depth, settings.w, + settings.left, + settings.bottom, + settings.depth, + settings.w, + settings.right, + settings.bottom, + settings.depth, + settings.w, + settings.left, + settings.top, + settings.depth, + settings.w, //Triangle 2 - settings.left, settings.top, settings.depth, settings.w, - settings.right, settings.bottom, settings.depth, settings.w, - settings.right, settings.top, settings.depth, settings.w + settings.left, + settings.top, + settings.depth, + settings.w, + settings.right, + settings.bottom, + settings.depth, + settings.w, + settings.right, + settings.top, + settings.depth, + settings.w, ]); ``` @@ -285,14 +317,14 @@ First, we draw a red box in the middle, but set W to 0.7. As the coordinates get ```js box.draw({ - top : 0.5, // y - bottom : -0.5, // y - left : -0.5, // x - right : 0.5, // x - w : 0.7, // w - enlarge this box - - depth : 0, // z - color : [1, 0.4, 0.4, 1] // red + top: 0.5, // y + bottom: -0.5, // y + left: -0.5, // x + right: 0.5, // x + w: 0.7, // w - enlarge this box + + depth: 0, // z + color: [1, 0.4, 0.4, 1], // red }); ``` @@ -300,14 +332,14 @@ Now, we draw a green box up top, but shrink it by setting the w component to 1.1 ```js box.draw({ - top : 0.9, // y - bottom : 0, // y - left : -0.9, // x - right : 0.9, // x - w : 1.1, // w - shrink this box - - depth : 0.5, // z - color : [0.4, 1, 0.4, 1] // green + top: 0.9, // y + bottom: 0, // y + left: -0.9, // x + right: 0.9, // x + w: 1.1, // w - shrink this box + + depth: 0.5, // z + color: [0.4, 1, 0.4, 1], // green }); ``` @@ -315,14 +347,14 @@ This last box doesn't get drawn because it's outside of clip space. The depth is ```js box.draw({ - top : 1, // y - bottom : -1, // y - left : -1, // x - right : 1, // x - w : 1.5, // w - Bring this box into range - - depth : -1.5, // z - color : [0.4, 0.4, 1, 1] // blue + top: 1, // y + bottom: -1, // y + left: -1, // x + right: 1, // x + w: 1.5, // w - Bring this box into range + + depth: -1.5, // z + color: [0.4, 0.4, 1, 1], // blue }); ``` @@ -362,9 +394,9 @@ CubeDemo.prototype.computeModelMatrix = function (now) { // Multiply together, make sure and read them in opposite order this.transforms.model = MDN.multiplyArrayOfMatrices([ position, // step 4 - rotateY, // step 3 - rotateX, // step 2 - scale // step 1 + rotateY, // step 3 + rotateX, // step 2 + scale, // step 1 ]); }; ``` @@ -372,13 +404,17 @@ CubeDemo.prototype.computeModelMatrix = function (now) { In order to use this in the shader it must be set to a uniform location. The locations for the uniforms are saved in the `locations` object shown below: ```js -this.locations.model = gl.getUniformLocation(webglProgram, 'model'); +this.locations.model = gl.getUniformLocation(webglProgram, "model"); ``` And finally the uniform is set to that location. This hands off the matrix to the GPU. ```js -gl.uniformMatrix4fv(this.locations.model, false, new Float32Array(this.transforms.model)); +gl.uniformMatrix4fv( + this.locations.model, + false, + new Float32Array(this.transforms.model) +); ``` In the shader, each position vertex is first transformed into a homogeneous coordinate (a `vec4` object), and then multiplied against the model matrix. @@ -444,12 +480,7 @@ In the next section we'll take this step of copying Z into the w slot and turn i The last step of filling in the w component can actually be accomplished with a simple matrix. Start with the identity matrix: ```js -const identity = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1, -]; +const identity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; MDN.multiplyPoint(identity, [2, 3, 4, 1]); //> [2, 3, 4, 1] @@ -458,12 +489,7 @@ MDN.multiplyPoint(identity, [2, 3, 4, 1]); Then move the last column's 1 up one space. ```js -const copyZ = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 1, - 0, 0, 0, 0, -]; +const copyZ = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0]; MDN.multiplyPoint(copyZ, [2, 3, 4, 1]); //> [2, 3, 4, 4] @@ -475,10 +501,22 @@ However in the last example we performed `(z + 1) * scaleFactor`: const scaleFactor = 0.5; const simpleProjection = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, scaleFactor, - 0, 0, 0, scaleFactor, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + scaleFactor, + 0, + 0, + 0, + scaleFactor, ]; MDN.multiplyPoint(simpleProjection, [2, 3, 4, 1]); @@ -488,22 +526,22 @@ MDN.multiplyPoint(simpleProjection, [2, 3, 4, 1]); Breaking it out a little further we can see how this works: ```js -let x = (2 * 1) + (3 * 0) + (4 * 0) + (1 * 0) -let y = (2 * 0) + (3 * 1) + (4 * 0) + (1 * 0) -let z = (2 * 0) + (3 * 0) + (4 * 1) + (1 * 0) -let w = (2 * 0) + (3 * 0) + (4 * scaleFactor) + (1 * scaleFactor) +let x = 2 * 1 + 3 * 0 + 4 * 0 + 1 * 0; +let y = 2 * 0 + 3 * 1 + 4 * 0 + 1 * 0; +let z = 2 * 0 + 3 * 0 + 4 * 1 + 1 * 0; +let w = 2 * 0 + 3 * 0 + 4 * scaleFactor + 1 * scaleFactor; ``` The last line could be simplified to: ```js -w = (4 * scaleFactor) + (1 * scaleFactor) +w = 4 * scaleFactor + 1 * scaleFactor; ``` Then factoring out the scaleFactor, we get this: ```js -w = (4 + 1) * scaleFactor +w = (4 + 1) * scaleFactor; ``` Which is exactly the same as the `(z + 1) * scaleFactor` that we used in the previous example. @@ -513,10 +551,22 @@ In the box demo, an additional `computeSimpleProjectionMatrix()` method is added ```js CubeDemo.prototype.computeSimpleProjectionMatrix = function (scaleFactor) { this.transforms.projection = [ - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, scaleFactor, - 0, 0, 0, scaleFactor + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + scaleFactor, + 0, + 0, + 0, + scaleFactor, ]; }; ``` @@ -573,17 +623,34 @@ The reason to flip the z axis is that the clip space coordinate system is a left Let's take a look at a `perspectiveMatrix()` function, which computes the perspective projection matrix. ```js -MDN.perspectiveMatrix = function (fieldOfViewInRadians, aspectRatio, near, far) { +MDN.perspectiveMatrix = function ( + fieldOfViewInRadians, + aspectRatio, + near, + far +) { const f = 1.0 / Math.tan(fieldOfViewInRadians / 2); const rangeInv = 1 / (near - far); return [ - f / aspectRatio, 0, 0, 0, - 0, f, 0, 0, - 0, 0, (near + far) * rangeInv, -1, - 0, 0, near * far * rangeInv * 2, 0 + f / aspectRatio, + 0, + 0, + 0, + 0, + f, + 0, + 0, + 0, + 0, + (near + far) * rangeInv, + -1, + 0, + 0, + near * far * rangeInv * 2, + 0, ]; -} +}; ``` The four parameters into this function are: @@ -662,12 +729,12 @@ CubeDemo.prototype.computeViewMatrix = function (now) { const moveLeftAndRight = 15 * Math.sin(now * 0.0017); // Move the camera around - const position = MDN.translateMatrix(moveLeftAndRight, 0, 50 + moveInAndOut ); + const position = MDN.translateMatrix(moveLeftAndRight, 0, 50 + moveInAndOut); // Multiply together, make sure and read them in opposite order const matrix = MDN.multiplyArrayOfMatrices([ // Exercise: rotate the camera view - position + position, ]); // Inverse the operation for camera movements, because we are actually diff --git a/files/jsondata/GroupData.json b/files/jsondata/GroupData.json index 2b338428a0da7a7..a7e13dafa48bd64 100644 --- a/files/jsondata/GroupData.json +++ b/files/jsondata/GroupData.json @@ -1728,7 +1728,6 @@ "WebGL": { "overview": ["WebGL API"], "guides": [ - "/docs/Web/API/WebGL_API/Tutorial", "/docs/Web/API/WebGL_API/Constants", "/docs/Web/API/WebGL_API/Types", "/docs/Web/API/WebGL_API/WebGL_model_view_projection", @@ -1740,6 +1739,17 @@ "/docs/Web/API/WebGL_API/Matrix_math_for_the_web", "/docs/Web/API/WebGL_API/Using_Extensions" ], + "tutorial": [ + "/docs/Web/API/WebGL_API/Tutorial", + "/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL", + "/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context", + "/docs/Web/API/WebGL_API/Tutorial/Using_shaders_to_apply_color_in_WebGL", + "/docs/Web/API/WebGL_API/Tutorial/Animating_objects_with_WebGL", + "/docs/Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL", + "/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL", + "/docs/Web/API/WebGL_API/Tutorial/Lighting_in_WebGL", + "/docs/Web/API/WebGL_API/Tutorial/Animating_textures_in_WebGL" + ], "interfaces": [ "WebGLRenderingContext", "WebGLBuffer",