WebGL - Perspective Correct Textured Cube (modified)
Shows the impact of rectangular vs. non-rectangular geometry on texture mapping fidelity.
by Chrisssie
HTML
<canvas id="canvas"></canvas>
<!-- vertex shader -->
<script id="vertex-shader-3d" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute vec2 a_texcoord;
uniform mat4 u_matrix;
varying vec2 v_texcoord;
void main() {
// Multiply the position by the matrix.
gl_Position = u_matrix * a_position;
// Pass the texcoord to the fragment shader.
v_texcoord = a_texcoord;
}
</script>
<!-- fragment shader -->
<script id="fragment-shader-3d" type="x-shader/x-fragment">
precision mediump float;
// Passed in from the vertex shader.
varying vec2 v_texcoord;
// The texture.
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, v_texcoord);
}
</script><!--
for most samples webgl-utils only provides shader compiling/linking and
canvas resizing because why clutter the examples with code that's the same in every sample.
See https://webglfundamentals.org/webgl/lessons/webgl-boilerplate.html
and https://webglfundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
for webgl-utils, m3, m4, and webgl-lessons-ui.
-->
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://webglfundamentals.org/webgl/resources/m4.js"></script>
CSS
@import url("https://webglfundamentals.org/webgl/resources/webgl-tutorials.css");
canvas {
background: #888;
}
JavaScript
// WebGL - Perspective Correct Textured Cube (the default)
// from https://webglfundamentals.org/webgl/webgl-perspective-correct-cube.html
"use strict";
function main() {
// Get A WebGL context
/** @type {HTMLCanvasElement} */
var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl");
if (!gl) {
return;
}
// setup GLSL program
var program = webglUtils.createProgramFromScripts(gl, ["vertex-shader-3d", "fragment-shader-3d"]);
// look up where the vertex data needs to go.
var positionLocation = gl.getAttribLocation(program, "a_position");
var texcoordLocation = gl.getAttribLocation(program, "a_texcoord");
// lookup uniforms
var matrixLocation = gl.getUniformLocation(program, "u_matrix");
var textureLocation = gl.getUniformLocation(program, "u_texture");
// Create a buffer for positions
var positionBuffer = gl.createBuffer();
// Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// Put the positions in the buffer
setGeometry(gl);
// provide texture coordinates for the rectangle.
var texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
// Set Texcoords.
setTexcoords(gl);
// Create a texture.
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Fill the texture with a 4x4 LUMINANCE pixel.
const level = 0;
const format = gl.LUMINANCE;
const type = gl.UNSIGNED_BYTE;
const border = 0;
const width = 8;
const height = 8;
const pixels = new Uint8Array([
255, 64, 255, 64, 255, 64, 255, 64,
64, 255, 64, 255, 64, 255, 64, 255,
255, 64, 255, 64, 255, 64, 255, 64,
64, 255, 64, 255, 64, 255, 64, 255,
255, 64, 255, 64, 255, 64, 255, 64,
64, 255, 64, 255, 64, 255, 64, 255,
255, 64, 255, 64, 255, 64, 255, 64,
64, 255, 64, 255, 64, 255, 64, 255,
]);
gl.texImage2D(gl.TEXTURE_2D, level,...