WebGL example won't work with supplied uniforms matrices - javascript

I'm finding few difficulties as i'm moving from opengl to webgl
The triangle example worked fine until I added uniform matrices, which is why I'll just include the relevant code
hopefully you could spot the error(s)
var gl;
function webGLStart()
{
var canvas = document.getElementById("glcanvas");
gl = canvas.getContext("experimental-webgl");
gl.viewport(0, 0, 500, 500);
if(!gl)
{ alert("Could Not Initialize WebGL"); }
//initialize shaders
var Program = getShader("triangle_vert", "triangle_frag", false);
//initialize buffers
var triangleVBO = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVBO);
var vertices = [ //position //color
-1.0, -1.0, -5.0, 1.0, 0.0, 0.0,
+0.0, +1.0, -5.0, 0.0, 1.0, 0.0,
+1.0, -1.0, -5.0, 0.0, 0.0, 1.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var step = Float32Array.BYTES_PER_ELEMENT;
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, step * 6, 0);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, step * 6, step * 3);
gl.enableVertexAttribArray(1);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//setting matrices and uniforms
var Model = mat4.create();
var View = mat4.create();
var Projection = mat4.create();
mat4.identity(Model);
mat4.identity(View);
mat4.perspective(45, 500.0/500.0, 0.1, 100.0, Projection);
gl.useProgram(Program);
gl.uniformMatrix4fv(gl.getUniformLocation(Program, "Model"), false, Model);
gl.uniformMatrix4fv(gl.getUniformLocation(Program, "View"), false, View);
gl.uniformMatrix4fv(gl.getUniformLocation(Program, "Projection"), false, Projection);
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
Vertex / fragment shaders:
<head>
<script id="triangle_frag" type="frag">
precision mediump float;
varying vec3 Col;
void main(void) {
gl_FragColor = vec4(Col, 1.0);
}
</script>
<script id="triangle_vert" type="vert">
attribute vec3 aVertexPosition;
attribute vec3 color;
varying vec3 Col;
uniform mat4 Model;
uniform mat4 View;
uniform mat4 Projection;
void main(void) {
gl_Position = Projection * View * Model * vec4(aVertexPosition, 1.0);
Col = color;
}
</script>
//...
I'm using gl-matrix-min.js and trying to run the example with firefox on windows 7

Related

How to properly specify indices for a four-sided pyramid in WebGL?"

I am trying to create a 4-sided pyramid in WebGL where each face is a different color and I believe I'm running into issues with the indices. From my understanding, if I specify an indexed array, WebGL should be drawing a line between the corresponding vertices. I believe my code has all the necessary lines covered but I just can't get the pyramid to form correctly.
If someone could take a look at my code and help me figure out where I'm going wrong, that would be greatly appreciated!
Javascript code:
"use strict";
var canvas;
var gl;
var numPositions = 12;
var positions = [];
var colors = [];
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = 0;
var theta = [0, 0, 0];
var thetaLoc;
window.onload = function init()
{
canvas = document.getElementById("gl-canvas");
gl = canvas.getContext('webgl2');
if (!gl) alert("WebGL 2.0 isn't available");
colorPyramid();
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.enable(gl.DEPTH_TEST);
//
// Load shaders and initialize attribute buffers
//
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
var cBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW);
var colorLoc = gl.getAttribLocation( program, "aColor" );
gl.vertexAttribPointer( colorLoc, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( colorLoc );
var vBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(positions), gl.STATIC_DRAW);
var positionLoc = gl.getAttribLocation(program, "aPosition");
gl.vertexAttribPointer(positionLoc, 4, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLoc);
thetaLoc = gl.getUniformLocation(program, "uTheta");
//event listeners for buttons
document.getElementById( "xButton" ).onclick = function () {
axis = xAxis;
};
document.getElementById( "yButton" ).onclick = function () {
axis = yAxis;
};
document.getElementById( "zButton" ).onclick = function () {
axis = zAxis;
};
render();
}
function colorPyramid()
{
triple(0, 3, 2); //base
triple(2, 0, 1);
triple(3, 1, 2);
triple(0, 1, 3);
}
function triple(a, b, c)
{
var vertices = [
vec3(0.5, -0.2722, 0.2886),
vec3(0.0, -0.2772, -0.5773),
vec3(-0.5, -0.2722, 0.2886),
vec3(0.0, 0.5443, 0.0)
];
var vertexColors = [
vec4(0.0, 0.0, 0.0, 1.0), // black
vec4(1.0, 0.0, 0.0, 1.0), // red
vec4(0.0, 1.0, 0.0, 1.0), // green
vec4(0.0, 0.0, 1.0, 1.0) // blue
];
// We need to parition the quad into two triangles in order for
// WebGL to be able to render it. In this case, we create two
// triangles from the quad indices
//vertex color assigned by the index of the vertex
var indices = [a, b, c];
for ( var i = 0; i < indices.length; ++i ) {
positions.push( vertices[indices[i]] );
//colors.push( vertexColors[indices[i]] );
// for solid colored faces use
colors.push(vertexColors[a]);
}
}
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
theta[axis] += 2.0;
gl.uniform3fv(thetaLoc, theta);
gl.drawArrays(gl.TRIANGLES, 0, numPositions);
requestAnimationFrame(render);
}
I don't think the issue is my HTML code, but it never hurts to include it!
HTML:
<!DOCTYPE html>
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
#version 300 es
in vec4 aPosition;
in vec4 aColor;
out vec4 vColor;
uniform vec3 uTheta;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
vec3 angles = radians(uTheta);
vec3 c = cos(angles);
vec3 s = sin(angles);
// Remeber: thse matrices are column-major
mat4 rx = mat4(1.0, 0.0, 0.0, 0.0,
0.0, c.x, s.x, 0.0,
0.0, -s.x, c.x, 0.0,
0.0, 0.0, 0.0, 1.0);
mat4 ry = mat4(c.y, 0.0, -s.y, 0.0,
0.0, 1.0, 0.0, 0.0,
s.y, 0.0, c.y, 0.0,
0.0, 0.0, 0.0, 1.0);
mat4 rz = mat4(c.z, s.z, 0.0, 0.0,
-s.z, c.z, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0);
vColor = aColor;
gl_Position = rz * ry * rx * aPosition;
gl_Position.z = -gl_Position.z;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
#version 300 es
precision mediump float;
in vec4 vColor;
out vec4 fColor;
void
main()
{
fColor = vColor;
}
</script>
<script type="text/javascript" src="http://interactivecomputergraphics.com/Code/Common/utility.js"></script>
<script type="text/javascript" src="http://interactivecomputergraphics.com/Code/Common/initShaders.js"></script>
<script type="text/javascript" src="http://interactivecomputergraphics.com/Code/Common/MV.js"></script>
<script type="text/javascript" src="ASPyramid.js"></script>
<body>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
<br/>
<button id= "xButton">Rotate X</button>
<button id= "yButton">Rotate Y</button>
<button id= "zButton">Rotate Z</button>
</body>
</html>
Ended up figuring out the issue with the help of a nice Redditor. I forgot to update the vertexAttribPointer for positionLoc to 3 instead of 4. The pyramid renders properly now.

Webgl vertex position Built in VertexShader

I only use the matrix to draw a square! Only the matrix is updated in each rendering. How to remove Vertex Position from my codes
lock like this
https://webgl2fundamentals.org/webgl/lessons/webgl-drawing-without-data.html
#version 300 es
in vec4 a_position;
in vec2 a_texcoord;
uniform mat4 u_matrix;
out vec2 v_texcoord;
void main()
ngl_Position = u_matrix * a_position;
v_texcoord = a_texcoord;
}
and remove this
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0, 0,
0, 1, 0,
1, 0, 0,
0, 1, 0,
1, 1, 0,
1, 0, 0]), gl.STATIC_DRAW);
Sorry for using Google Translator
Here is your square vertex shader. You don't need to use a matrix.
#version 300 es
void main() {
float xs[6] = float[](0.0, 0.0, 1.0, 0.0, 1.0, 1.0);
float ys[6] = float[](0.0, 1.0, 0.0, 1.0, 1.0, 0.0);
float x = xs[gl_VertexID];
float y = ys[gl_VertexID];
gl_Position = vec4(x, y, 0, 1);
}
And to render you just do this. You don't need to do any bufferData or any uniforms.
gl.drawArrays(gl.TRIANGLES, 0, 6);

Texturing a pyramid in WebGL

I am working on a textured pyramid, but I got some warnings. I did it by step by step from the book "Beginning WebGL for HTML5" and it does not work.
Here is my code:
<!doctype html>
<html>
<head>
<title>Project 2</title>
<script type="text/javascript" src="gl-matrix-min.js"></script>
<style>
body{ background-color: grey; }
canvas{ background-color: white; }
</style>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 aVertexPosition;
attribute vec4 aVertexColor;
attribute vec2 aVertexTextureCoord;
varying highp vec2 vTextureCoord;
varying vec4 vColor;
/*
Couting On GPU
// Model matrix
uniform mat4 uMVMatrix;
// Projection matrix
uniform mat4 uPMatrix;
// View matrix
uniform mat4 uVMatrix;
*/
uniform mat4 uPVMatrix;
void main(void) {
vColor = aVertexColor;
gl_Position = uPVMatrix * aVertexPosition;
vTextureCoord = aVertexTextureCoord;
// gl_Position = uPMatrix * uVMatrix * uMVMatrix * aVertexPosition;
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vTextureCoord);
}
</script>
<script>
var gl = null,
canvas = null,
glProgram = null,
fragmentShader = null,
vertexShader = null;
var coordinateArray = [],
triangleVerticeColors = [],
verticesArray = [],
verticesIndexArray = [],
triangleTexCoords = [];
var vertexPositionAttribute = null,
trianglesVerticeBuffer = null,
vertexColorAttribute = null,
trianglesColorBuffer = null,
triangleVerticesIndexBuffer = null,
vertexTexCoordAttribute = null,
trianglesTexCoordBuffer = null;
var P = mat4.create(),
V = mat4.create(),
M = mat4.create(),
VM = mat4.create(),
PVM = mat4.create();
var uPVMMatrix;
var texture;
var textureImage = null;
function initWebGL() {
canvas = document.getElementById("my-canvas");
try {
gl = canvas.getContext("webgl") ||
canvas.getContext("experimental-webgl");
}catch(e){ }
if(gl) {
setupWebGL();
initShaders();
setupTexture();
setupBuffers();
//getMatrixUniforms();
//setMatrixUniforms();
//animationLoop();
drawScene();
}else{
alert( "Error: Your browser does not appear to" + "support WebGL.");
}
}
function animationLoop() {
var R = mat4.create();
var angle = 0;
var i =0;
var loop = function() {
angle = performance.now() / 1000 / 6 * 2 * Math.PI;
i++;
mat4.rotate(PVM, R, angle, [0, 1, 0]);
gl.uniformMatrix4fv(uPVMMatrix, false, PVM);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);
drawScene();
requestAnimationFrame(loop);
};
requestAnimationFrame(loop);
}
function setupWebGL() {
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
gl.frontFace(gl.CW);
gl.cullFace(gl.BACK);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
console.log(P);
console.log(V);
console.log(M);
// mat4.identity(M);
mat4.lookAt(V, [5, 0, -5], [0, 0, 0], [0, 1, 0]);
mat4.perspective(P, glMatrix.toRadian(45), canvas.width / canvas.height, 0.1, 1000.0);
mat4.multiply(VM,V,M);
mat4.multiply(PVM,P,VM);
}
function initShaders() {
var fs_source = document.getElementById('shader-fs').innerHTML,
vs_source = document.getElementById('shader-vs').innerHTML;
vertexShader = makeShader(vs_source, gl.VERTEX_SHADER);
fragmentShader = makeShader(fs_source, gl.FRAGMENT_SHADER);
glProgram = gl.createProgram();
gl.attachShader(glProgram, vertexShader);
gl.attachShader(glProgram, fragmentShader);
gl.linkProgram(glProgram);
if (!gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
alert("Unable to initialize the shader program.");
}
gl.useProgram(glProgram);
uPVMMatrix = gl.getUniformLocation(glProgram, "uPVMatrix");
gl.uniformMatrix4fv(uPVMMatrix, false, PVM);
}
function loadTexture() {
textureImage = $("#troll").get(0);
setupTexture();
}
function setupTexture() {
texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNISGNED_BYTE, textureImage);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
glProgram.sampleUniform = gl.getUniformLocation(glProgram, "uSampler");
gl.uniform1i(glProgram.sampleUniform, 0);
if(!gl.isTexture(texture)) {
console.log("Error : Texture is invalid");
}
}
function makeShader(src, type) {
var shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert("Error compiling shader: " + gl.getShaderInfoLog(shader));
}
return shader;
}
function setupBuffers() {
// n-sides polygon
var n = 6;
var radius = 1;
var angle = (Math.PI * 2) / n;
var xCoordinate = 0;
var yCoordinate = 0;
for(var i = 0 ; i < n ; i++) {
var a = angle * i;
var xNewCoordinate = xCoordinate + radius * Math.cos(a);
var yNewCoordinate = yCoordinate + radius * Math.sin(a);
var zNewCoordinate = 0;
coordinateArray.push(xNewCoordinate);
coordinateArray.push(yNewCoordinate);
coordinateArray.push(zNewCoordinate);
}
verticesArray = [
//Bottom Face
0.0, 0.0, 0.0,
0.0, 0.0, -1.0,
1.0, 0.0, -1.0,
0.0, 0.0, 0.0,
1.0, 0.0, -1.0,
1.0, 0.0, 0.0,
//Front Face
0.0, 0.0, 0.0,
1.0, 0.0, 0.0,
0.5, 1.0, -0.5,
//Right Face
1.0, 0.0, 0.0,
1.0, 0.0, -1.0,
0.5, 1.0, -0.5,
//Back Face
1.0, 0.0, -1.0,
0.0, 0.0, -1.0,
0.5, 1.0, -0.5,
//Left Face
0.0, 0.0, -1.0,
0.0, 0.0, 0.0,
0.5, 1.0, -0.5,
];
trianglesVerticeBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesArray), gl.STATIC_DRAW);
verticesIndexArray = [
0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10, 11,
12, 13, 14,
15, 16, 17,
];
triangleVerticesIndexBuffer = gl.createBuffer();
triangleVerticesIndexBuffer.number_vertext_points = verticesIndexArray.length;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, triangleVerticesIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(verticesIndexArray), gl.STATIC_DRAW);
triangleTexCoords = [
0.5000, 0.1910,
0.1910, 0.5000,
0.5000, 0.8090,
0.5000, 0.1910,
0.5000, 0.8090,
0.8090, 0.5000,
0.5000, 0.1910,
0.8090, 0.5000,
1.0000, 0.0000,
0.8090, 0.5000,
0.5000, 0.8090,
1.0000, 1.0000,
0.5000, 0.8090,
0.1910, 0.5000,
0.0000, 1.0000,
0.1910, 0.5000,
0.5000, 0.1910,
0.0000, 0.0000,
];
trianglesTexCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesTexCoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleTexCoords), gl.STATIC_DRAW);
triangleVerticeColors = [
// Bottom quad
0.470, 0.796, 0.886,
0.470, 0.796, 0.886,
0.470, 0.796, 0.886,
0.470, 0.796, 0.886,
0.470, 0.796, 0.886,
0.470, 0.796, 0.886,
// Back triangle
0.772, 0.470, 0.886,
0.772, 0.470, 0.886,
0.772, 0.470, 0.886,
// Left triangle
0.886, 0.552, 0.470,
0.886, 0.552, 0.470,
0.886, 0.552, 0.470,
// Front triangle
0.886, 0.882, 0.470,
0.886, 0.882, 0.470,
0.886, 0.882, 0.470,
// Right triangle
0.470, 0.886, 0.505,
0.470, 0.886, 0.505,
0.470, 0.886, 0.505,
];
trianglesColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVerticeColors), gl.STATIC_DRAW);
}
// GPU
function getMatrixUniforms() {
glProgram.mvMatrixUniform = gl.getUniformLocation(glProgram, "uMVMatrix");
glProgram.pMatrixUniform = gl.getUniformLocation(glProgram, "uPMatrix");
glProgram.vMatrixUniform = gl.getUniformLocation(glProgram, "uVMatrix");
}
// GPU
function setMatrixUniforms() {
gl.uniformMatrix4fv(glProgram.mvMatrixUniform, false, M);
gl.uniformMatrix4fv(glProgram.pMatrixUniform, false, P);
gl.uniformMatrix4fv(glProgram.vMatrixUniform, false, V);
}
function drawScene() {
vertexPositionAttribute = gl.getAttribLocation(glProgram, "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesVerticeBuffer);
gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0);
vertexTexCoordAttribute = gl.getAttribLocation(glProgram, "aVertexTexCoord");
gl.enableVertexAttribArray(vertexTexCoordAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesTexCoordBuffer);
gl.vertexAttribPointer(vertexTexCoordAttribute, 2, gl.FLOAT, false, 0, 0);
/*vertexColorAttribute = gl.getAttribLocation(glProgram, "aVertexColor");
gl.enableVertexAttribArray(vertexColorAttribute);
gl.bindBuffer(gl.ARRAY_BUFFER, trianglesColorBuffer);
gl.vertexAttribPointer(vertexColorAttribute, 3, gl.FLOAT, false, 0, 0);
*/
gl.drawElements(gl.TRIANGLE_STRIP, triangleVerticesIndexBuffer.number_vertext_points, gl.UNSIGNED_SHORT, 0);
}
</script>
</head>
<body onload="initWebGL()">
<canvas id="my-canvas" width="800" height="600">
Your browser does not support the HTML5 canvas element.
</canvas>
<img src="./trollface.png" id="troll" />
</body>
</html>
The texture coordinates I used looks like this:
Here is the texture:
The warnings are about out of range arrays and about the image not loading.
You have multiple errors in your code.
Your function loadTexture() is never called and so the texture is actually never loaded.
Replace setupTexture() with loadTexture() inside initWebGL().
You are also seem to be using jQuery to retrieve the image from DOM, but you didn't load the library.
Replace $("#troll").get(0) with document.getElementById("troll") inside loadTexture().
The dimensions of the texture needs to be a power of 2 (128x32, 256x256, 512x1024, ...)
You should resize your image to 256x256.
You made a typo with one of the parameters for texImage2D().
Replace gl.UNISGNED_BYTE with gl.UNSIGNED_BYTE inside your gl.texImage2D() call.
Your names for he texture coordinates attribute don't match between your gl.getAttribLocation() call and your vertex shader code.
Replace aVertexTexCoord with aVertexTextureCoord inside your gl.getAttribLocation() call.
If you are rendering individual triangles replace gl.TRIANGLE_STRIP with gl.TRIANGLES inside your gl.drawElements() call.
If you fix all those mistakes your code will run without errors.

Perspective projection showing nothing

I'm trying to follow WebGLFundamentals.org and LearningWebGL tutorials and I reached the projection part.
I create my scene something like LearningWebGL Tutorial 01 (with only the square):
var canvas;
var gl;
var shaderProgram;
// Vertex Shader
var positionLocation;
var uvMatrixLocation;
var pMatrixLocation;
var uvMatrix = mat4.create();
var pMatrix = mat4.create();
// Fragment Shader
var colorLocation;
var buffer = [];
function initGL() {
canvas = document.getElementById("webgl-canvas");
gl = WebGLUtils.setupWebGL(canvas);
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
}
function createShader(gl, id, type) {
var shader;
var shaderSrc = document.getElementById(id);
if (type == "fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (type == "vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, shaderSrc.text);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
function initShaders() {
var fragmentShader = createShader(gl, "fshader", "fragment");
var vertexShader = createShader(gl, "vshader", "vertex");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
// Linka os parametros do shader
positionLocation = gl.getAttribLocation(shaderProgram, "a_position");
uvMatrixLocation = gl.getUniformLocation(shaderProgram, "uvMatrix");
pMatrixLocation = gl.getUniformLocation(shaderProgram, "pMatrix");
gl.enableVertexAttribArray(positionLocation);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Não foi possível inicializar os shaders"); }
}
function initBuffers() {
createPoly([
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0
]);
}
function draw() {
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(shaderProgram);
mat4.perspective(pMatrix, Math.PI/3, 1, -10, 10);
gl.uniformMatrix4fv(pMatrixLocation, false, pMatrix);
gl.uniformMatrix4fv(uvMatrixLocation, false, uvMatrix);
buffer.forEach(function(e) {
gl.bindBuffer(gl.ARRAY_BUFFER, e.buffer);
gl.vertexAttribPointer(positionLocation, e.vertSize, gl.FLOAT, false, 0, 0);
gl.drawArrays(e.primtype, 0, e.nVerts());
});
}
window.onload = function() {
initGL();
initShaders();
initBuffers();
draw();
}
// ---------------------------------------------------------------
// --------------------------- Utils -----------------------------
// ---------------------------------------------------------------
function createPoly(vertices) {
var vertexBuffer;
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var poly = {
buffer: vertexBuffer,
vertSize: 3,
nVerts: function() { return vertices.length/this.vertSize; },
primtype: gl.TRIANGLE_STRIP
};
buffer.push(poly);
}
<script src="https://www.khronos.org/registry/webgl/sdk/demos/common/webgl-utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>
<script id="vshader" type="x-shader/x-vertex">
attribute vec3 a_position;
uniform mat4 uvMatrix;
uniform mat4 pMatrix;
varying vec4 v_color;
void main() {
gl_Position = pMatrix * uvMatrix * vec4(a_position, 1);
v_color = gl_Position;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_color;
void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }
</script>
<canvas id="webgl-canvas" width="800" height="600"></canvas>
Then I set the projection on line 85:
Using orthogonal projection mat4.ortho(pMatrix, -5, 5, -5, 5, -5, 5); the square appears on my canvas
when I use perspective mat4.perspective(pMatrix, Math.PI/3, 1, -10, 10); it won't work
I've already tried several parameters
First off normally you'd make zNear and zFar positive numbers. They represent how the area in front of the camera that will be visible. Second is because your uvMatrix is the identity matrix your object as at the origin. The view is also at the origin (see cameras and perspective)
That means in order to view the object you either need to move the object away from the camera or add in a view matrix (which also effectively moves the object away from the origin)
I changed the code to this and it worked
// set zNear to 0.1
mat4.perspective(pMatrix, Math.PI/3, 1, 0.1, 10);
// move the object out from the camera
mat4.translate(uvMatrix, uvMatrix, [0, 0, -5]);
var canvas;
var gl;
var shaderProgram;
// Vertex Shader
var positionLocation;
var uvMatrixLocation;
var pMatrixLocation;
var uvMatrix = mat4.create();
var pMatrix = mat4.create();
// Fragment Shader
var colorLocation;
var buffer = [];
function initGL() {
canvas = document.getElementById("webgl-canvas");
gl = WebGLUtils.setupWebGL(canvas);
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
}
function createShader(gl, id, type) {
var shader;
var shaderSrc = document.getElementById(id);
if (type == "fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (type == "vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, shaderSrc.text);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
function initShaders() {
var fragmentShader = createShader(gl, "fshader", "fragment");
var vertexShader = createShader(gl, "vshader", "vertex");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
// Linka os parametros do shader
positionLocation = gl.getAttribLocation(shaderProgram, "a_position");
uvMatrixLocation = gl.getUniformLocation(shaderProgram, "uvMatrix");
pMatrixLocation = gl.getUniformLocation(shaderProgram, "pMatrix");
gl.enableVertexAttribArray(positionLocation);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { alert("Não foi possível inicializar os shaders"); }
}
function initBuffers() {
createPoly([
1.0, 1.0, 0.0,
-1.0, 1.0, 0.0,
1.0, -1.0, 0.0,
-1.0, -1.0, 0.0
]);
}
function draw() {
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(shaderProgram);
mat4.perspective(pMatrix, Math.PI/3, 1, 0.1, 10);
mat4.translate(uvMatrix, uvMatrix, [0, 0, -5]);
gl.uniformMatrix4fv(pMatrixLocation, false, pMatrix);
gl.uniformMatrix4fv(uvMatrixLocation, false, uvMatrix);
buffer.forEach(function(e) {
gl.bindBuffer(gl.ARRAY_BUFFER, e.buffer);
gl.vertexAttribPointer(positionLocation, e.vertSize, gl.FLOAT, false, 0, 0);
gl.drawArrays(e.primtype, 0, e.nVerts());
});
}
window.onload = function() {
initGL();
initShaders();
initBuffers();
draw();
}
// ---------------------------------------------------------------
// --------------------------- Utils -----------------------------
// ---------------------------------------------------------------
function createPoly(vertices) {
var vertexBuffer;
vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
var poly = {
buffer: vertexBuffer,
vertSize: 3,
nVerts: function() { return vertices.length/this.vertSize; },
primtype: gl.TRIANGLE_STRIP
};
buffer.push(poly);
}
<script src="https://www.khronos.org/registry/webgl/sdk/demos/common/webgl-utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.3.2/gl-matrix-min.js"></script>
<script id="vshader" type="x-shader/x-vertex">
attribute vec3 a_position;
uniform mat4 uvMatrix;
uniform mat4 pMatrix;
varying vec4 v_color;
void main() {
gl_Position = pMatrix * uvMatrix * vec4(a_position, 1);
v_color = gl_Position;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 v_color;
void main(void) { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); }
</script>
<canvas id="webgl-canvas" width="800" height="600"></canvas>
Change zNear to a small, positive number.

Blending and Culling in Webgl

Hi I dont actually get the culling part here? Can someone explain why my object is not blending? I need to apply blending on the object together with lighting
Below is the code of my script
Vertex shader:
<script type="x-shader/x-vertex" id="vshader">
attribute vec3 aPosition;
attribute vec4 aColor;
uniform mat4 uModel;
uniform mat4 uView;
uniform mat4 uProjection;
varying vec4 vColor;
attribute vec3 aNormal;
uniform mat4 uNormal;
uniform vec3 uLightDiffuse;
uniform vec3 uLightDirection;
void main() {
gl_Position = uProjection * uView * uModel * vec4(aPosition,1.0);
float lambertCoefficient = max(dot(-normalize(uLightDirection),normalize(vec3(uNormal * vec4(aNormal,1.0)))),0.0);
vec3 diffuseColor = uLightDiffuse * aColor.rgb * lambertCoefficient;
vColor = vec4(diffuseColor,1.0);
}
</script>
fragment shader
<script type="x-shader/x-fragment" id="fshader">
precision mediump float;
varying vec4 vColor;
void main() {
gl_FragColor = vColor;
}
</script>
<script type="text/javascript" src="initUtils.js"></script>
<script type="text/javascript" src="gl-matrix-min.js"></script>
main code:
<script>
function main() {
var canvas = document.getElementById("c");
var gl = initializeWebGL(canvas);
var vertexShader = initializeShader(gl,"vshader");
var fragmentShader = initializeShader(gl, "fshader");
var program = initializeProgram(gl,vertexShader,fragmentShader);
gl.useProgram(program);
var cube_vertices = [ // Coordinates
1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, //front
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
1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, //up
-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
-1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, //down
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
];
//buffer creation
var cubeVerticesBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cube_vertices), gl.STATIC_DRAW);
//attribute variable mapping to buffer
var aPosition = gl.getAttribLocation(program,"aPosition");
gl.vertexAttribPointer(aPosition,3,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(aPosition);
//unbind buffer to ARRAY_BUFFER POINTER
gl.bindBuffer(gl.ARRAY_BUFFER, null);
var cube_color = [ // Coordinates
1.0,0.0,0.0,0.5, 1.0,0.0,0.0,0.5, 1.0,0.0,0.0,0.5, 1.0,0.0,0.0,0.5, //front red
0.0,1.0,0.0,0.5, 0.0,1.0,0.0,0.5, 0.0,1.0,0.0,0.5, 0.0,1.0,0.0,0.5, //right green
0.0,0.0,1.0,0.5, 0.0,0.0,1.0,0.5, 0.0,0.0,1.0,0.5, 0.0,0.0,1.0,0.5, //up blue
1.0,1.0,0.0,0.5, 1.0,1.0,0.0,0.5, 1.0,1.0,0.0,0.5, 1.0,1.0,0.0,0.5, //left yellow
0.0,1.0,1.0,0.5, 0.0,1.0,1.0,0.5, 0.0,1.0,1.0,0.5, 0.0,1.0,1.0,0.5, //down cyan
1.0,0.0,1.0,0.5, 1.0,0.0,1.0,0.5, 1.0,0.0,1.0,0.5, 1.0,0.0,1.0,0.5 //back magenta
];
//buffer creation
var cubeColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cubeColorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(cube_color), gl.STATIC_DRAW);
//attribute variable mapping to buffer
var aColor = gl.getAttribLocation(program,"aColor");
gl.vertexAttribPointer(aColor,4,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(aColor);
//unbind buffer to ARRAY_BUFFER POINTER
gl.bindBuffer(gl.ARRAY_BUFFER, null);
var normals = [ // Normal of each vertex
0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, // front
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // right
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // up
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, // left
0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, // down
0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0, 0.0, 0.0,-1.0 // back
];
//buffer creation
var normalBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, normalBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
//attribute variable mapping to buffer
var aNormal = gl.getAttribLocation(program,"aNormal");
gl.vertexAttribPointer(aNormal,3,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(aNormal);
//unbind buffer to ARRAY_BUFFER POINTER
gl.bindBuffer(gl.ARRAY_BUFFER, null);
// Indices of the vertices
var indices = [
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // right
8, 9,10, 8,10,11, // up
12,13,14, 12,14,15, // left
16,17,18, 16,18,19, // down
20,21,22, 20,22,23 // back
];
//buffer creation
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array(indices), gl.STATIC_DRAW);
//unbind buffer to gl.ELEMENT_ARRAY_BUFFER POINTER
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
var modelMatrix = mat4.create();
var uModel = gl.getUniformLocation(program,"uModel");
gl.uniformMatrix4fv(uModel,false,modelMatrix);
//add normal matrix
var normalMatrix = mat4.create();
var uNormal = gl.getUniformLocation(program,"uNormal");
mat4.invert(normalMatrix,modelMatrix);
mat4.transpose(normalMatrix,normalMatrix);
gl.uniformMatrix4fv(uNormal,false,normalMatrix);
var viewMatrix = mat4.create();
var uView = gl.getUniformLocation(program,"uView");
mat4.lookAt(viewMatrix,[3,3,7],[0,0,0],[0,1,0]);
gl.uniformMatrix4fv(uView,false,viewMatrix);
var projectionMatrix = mat4.create();
var uProjection = gl.getUniformLocation(program,"uProjection");
mat4.perspective(projectionMatrix,glMatrix.toRadian(30),canvas.width/canvas.height,1,100);
gl.uniformMatrix4fv(uProjection,false,projectionMatrix);
var uLightDiffuse = gl.getUniformLocation(program,"uLightDiffuse");
gl.uniform3f(uLightDiffuse,1.0,1.0,1.0);
var uLightDirection= gl.getUniformLocation(program,"uLightDirection");
gl.uniform3f(uLightDirection,-1.0,-2.5,-5.0);
//draw scene
gl.clearColor(0, 0, 0, 1);
gl.enable(gl.DEPTH_TEST);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.disable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.FRONT);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_BYTE, 0);
}
The below shader statement indicates that you are writing pixels with Alpha=1.0, and it is opaque.
vColor = vec4(diffuseColor,1.0);
To make it transparent, you would need to make it a non-1.0 value, maybe calculated or passed in from texture itself ?
Culling has no relation to blending. It indicates the capability of GL HW to discard certain primitives depending on whether they are front-facing or back-facing.

Categories

Resources