Related
Im having troubles rendering my object after implementing perspective projection. Ive tried adjusting my shaders relative to the JS file, but im still not sure whats wrong. Any help would be highly appreciated! Also, the console isnt showing any errors, its only the rendering of the object that doesnt work.
"use strict";
var canvas;
var gl;
var numVertices = 36;
var texSize = 64;
var program;
var pointsArray = [];
var colorsArray = [];
var texCoordsArray = [];
//Images
var texture;
var texture2;
//Dimensions of Home
//Needed to multiply the length and the width by 5 b/c the rectangle was too small before hand
var l = 1
var h = .5
var w = 1
//For Persepctive Distortion
var near = 0.3;
var far = 3.0;
var radius = 4.0;
var theta = 0.0;
var phi = 0.0;
var dr = 5.0 * Math.PI/180.0;
var fovy = 45.0; // Field-of-view in Y direction angle (in degrees)
var aspect; // Viewport aspect ratio
var mvMatrix, pMatrix;
var modelView, projection;
var eye;
const at = vec3(0.0, 0.0, 0.0);
const up = vec3(0.0, 1.0, 0.0);
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
var vertices = [
vec4( -l, -w, h, 1.0 ),
vec4( -l, w, h, 1.0 ),
vec4( l, w, h, 1.0 ),
vec4( l, -w, h, 1.0 ),
vec4( -l, -w, -h, 1.0 ),
vec4( -l, w, -h, 1.0 ),
vec4( l, w, -h, 1.0 ),
vec4( l, -w, -h, 1.0 )
];
var vertexColors = [
//Needed to set color to white inorder to for the images to be visable
vec4( 1.0, 1.0, 1.0, 1 ), // white
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
];
//For images
function configureTexture(image,image2) {
//this is for picture of the wall
texture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image );
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
gl.uniform1i(gl.getUniformLocation(program, "texture"), 0);
//this is for picture of deques
texture2 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image2 );
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
gl.uniform1i(gl.getUniformLocation(program, "texture2"), 0);
}
function quad(a, b, c, d) {
//Lighting direction
/*
var t1 = subtract(vertices[b], vertices[a]);
var t2 = subtract(vertices[c], vertices[b]);
var normal = cross(t1, t2);
var normal = vec3(normal);
*/
pointsArray.push(vertices[a]);
//normalsArray.push(normal);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[0]);
pointsArray.push(vertices[b]);
//normalsArray.push(normal);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[1]);
pointsArray.push(vertices[c]);
//normalsArray.push(normal);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[2]);
pointsArray.push(vertices[a]);
//normalsArray.push(normal);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[0]);
pointsArray.push(vertices[c]);
//normalsArray.push(normal);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[2]);
pointsArray.push(vertices[d]);
//normalsArray.push(normal);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[3]);
}
function colorCube()
{
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
aspect = canvas.width/canvas.height;
//Set canvas to black
gl.clearColor( 0, 0, 0, 1 );
gl.enable(gl.DEPTH_TEST);
//
// Load shaders and initialize attribute buffers
//
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
var cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var tBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );
var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
modelView = gl.getUniformLocation( program, "modelView" );
projection = gl.getUniformLocation( program, "projection" );
//Image of the wall (1) and deques (2)
var image = document.getElementById("texImage");
var image2 = document.getElementById("texImage2");
configureTexture(image,image2);
//Button to stop rotation
document.getElementById("ButtonT").onclick = function(){flag = !flag};
render();
}
var render = function(){
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
eye = vec3(radius*Math.sin(theta)*Math.cos(phi),
radius*Math.sin(theta)*Math.sin(phi), radius*Math.cos(theta));
mvMatrix = lookAt(eye, at , up);
pMatrix = perspective(fovy, aspect, near, far);
//Placing the image of deque on the larger face of the building
gl.bindTexture( gl.TEXTURE_2D, texture2);
gl.uniform1i(gl.getUniformLocation(program, "texture"), 0);
gl.drawArrays( gl.TRIANGLES, 0, 6);
//Wrapping the sides of the building with images of the wall
gl.bindTexture( gl.TEXTURE_2D, texture );
gl.uniform1i(gl.getUniformLocation(program, "texture"), 0);
gl.drawArrays(gl.TRIANGLES,6,numVertices-6);
gl.uniformMatrix4fv( modelView, false, flatten(mvMatrix) );
gl.uniformMatrix4fv( projection, false, flatten(pMatrix) );
requestAnimFrame(render);
}
<!DOCTYPE html>
<html>
<style type="text/css">
canvas { background: rgb(138, 40, 40); }
</style>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
attribute vec2 vTexCoord;
varying vec4 fColor;
varying vec2 fTexCoord;
uniform vec3 theta;
//lighting
uniform vec4 lightPosition;
uniform float shininess;
uniform vec4 diffuseProduct;
attribute vec3 vNormal;
//For Persepctive Projection
uniform mat4 modelView;
uniform mat4 projection;
void main()
{
fColor = vColor;
fTexCoord = vTexCoord;
gl_Position = projection * modelView * vPosition;
gl_Position.z = -gl_Position.z;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
varying vec2 fTexCoord;
uniform sampler2D texture;
void
main()
{
gl_FragColor = fColor * texture2D( texture, fTexCoord );
}
</script>
<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="FinalProject.js"></script>
<center> <button id = "ButtonT">Toggle Rotation</button> </center>
<body>
<p> </p>
<button id = "Button1">Increase Z</button>
<button id = "Button2">Decrease Z</button>
<button id = "Button3">Increase R</button>
<button id = "Button4">Decrease R</button>
<p> </p>
<button id = "Button5">Increase theta</button>
<button id = "Button6">Decrease theta</button>
<button id = "Button7">Increase phi</button>
<button id = "Button8">Decrease phi</button>
<p> </p>
<center> <canvas id="gl-canvas" width="600" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas> </center>
<center> Simplistic Model of the Dequés Building at GWU </center>
<center>---</center>
<center> Ideas covered in this project: </center>
<center> Double Texture Mapping, Lighting </center>
<img id = "texImage" src = "brick copy.jpeg" hidden></img>
<img id = "texImage2" src = "house copy.jpg" hidden></img>
</body>
</html>
OBJECTIVE: The objective to the below code is to make a moving robot arm that has three layer's(upper, lower and middle) all of them being attach to the base. Given are the 4 sliders that can move each part indipendently except the base that will move all the arms.
PROBLEM: The problem I am having is when I try to run this code I don't get any visuals on the screen and there is no error in the console, I can't find the issue whats causing it. I have also attached a pic of the output.
SOLUTION: Haven't found yet.
var NumVertices = 36;
var points = [];
var colors = [];
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 )
];
var 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, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var BASE_HEIGHT = 2.0;
var BASE_WIDTH = 5.0;
var LOWER_ARM_HEIGHT = 5.0;
var LOWER_ARM_WIDTH = 0.5;
var UPPER_ARM_HEIGHT = 5.0;
var UPPER_ARM_WIDTH = 0.5;
var MIDDLE_ARM_HEIGHT = 5.0;
var MIDDLE_ARM_WIDTH = 0.5;
var modelViewMatrix, projectionMatrix;
var Base = 0;
var LowerArm = 1;
var UpperArm = 2;
var MiddleArm = 3;
var theta= [ 0, 0, 0, 0];
var angle = 0;
var modelViewMatrixLoc;
var vBuffer, cBuffer;
function quad( a, b, c, d ) {
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[b]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[d]);
}
function colorCube() {
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
function scale4(a, b, c, d) {
var result = mat4();
result[0][0] = a;
result[1][1] = b;
result[2][2] = c;
result[3][3] = d;
return result;
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable( gl.DEPTH_TEST );
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
document.getElementById("slider1").onchange = function(event) {
theta[0] = event.target.value;
};
document.getElementById("slider2").onchange = function(event) {
theta[1] = event.target.value;
};
document.getElementById("slider3").onchange = function(event) {
theta[2] = event.target.value;
};
document.getElementById("slider4").onchange = function(event) {
theta[3] = event.target.value;
};
modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"), false, flatten(projectionMatrix) );
render();
}
function base() {
var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function upperArm() {
var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH);
var instanceMatrix = mult(translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function lowerArm()
{
var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function middleArm()
{
var s = scale4(MIDDLE_ARM_WIDTH, MIDDLE_ARM_HEIGHT, MIDDLE_ARM_WIDTH);
var instanceMatrix = mult( translate( 0.0, 0.5 * MIDDLE_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
modelViewMatrix = rotate(theta[Base], 0, 1, 0 );
base();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArm], 0, 0, 1 ));
lowerArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, LOWER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[UpperArm], 0, 0, 1) );
upperArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, UPPER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[MiddleArm], 0, 0, 1) );
middleArm();
requestAnimFrame(render);
}
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 fColor;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main()
{
fColor = vColor;
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
void main()
{
gl_FragColor = fColor;
}
</script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="robotArm.js"></script>
<div id="slider1">
body angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider2">
lower arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider4">
middle arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider3">
upper arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<body>
<canvas id="gl-canvas" width="512"" height="512"
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
The first thing I did was add webgl-lint
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
That immediately got the error
Uncaught Error: https://greggman.github.io/webgl-lint/webgl-lint.js:2843:
error in
uniformMatrix4fv(WebGLUniformLocation("modelViewMatrix"),
false,
[5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 5, 0, NaN, NaN, NaN, NaN]): element 12 of argument 2 is NaN
: trying to set uniform 'modelViewMatrix'
at reportError (webgl-lint.js:2163)
at reportFunctionError (webgl-lint.js:2924)
at checkArrayForUniformImpl (webgl-lint.js:2843)
at webgl-lint.js:2869
at checkArgs (webgl-lint.js:2972)
at WebGLRenderingContext.ctx.<computed> [as uniformMatrix4fv] (webgl-lint.js:3016)
at base (js:230)
at render (js:267)
at init (js:223)
Looking in your code the issue is rotate does not take 4 arguments, it takes 2 arguments, an angle and an axis
r = rotate(angle, x, y, z); // BAD!
r = rotate(angle, [x, y, z]); // Good
Fixing that webgl-lint printed a new error. The issue is scale4 takes 4 arguments.
s = scale4(x, y, z); // BAD!
s = scale4(x, y, z, w); // good
you want to pass 1 for w.
That fixed rendering. As for the sliders you probably want to call render in each onchange function. You also probably want to use oninput instead of onchange
var NumVertices = 36;
var points = [];
var colors = [];
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 )
];
var 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, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var BASE_HEIGHT = 2.0;
var BASE_WIDTH = 5.0;
var LOWER_ARM_HEIGHT = 5.0;
var LOWER_ARM_WIDTH = 0.5;
var UPPER_ARM_HEIGHT = 5.0;
var UPPER_ARM_WIDTH = 0.5;
var MIDDLE_ARM_HEIGHT = 5.0;
var MIDDLE_ARM_WIDTH = 0.5;
var modelViewMatrix, projectionMatrix;
var Base = 0;
var LowerArm = 1;
var UpperArm = 2;
var MiddleArm = 3;
var theta= [ 0, 0, 0, 0];
var angle = 0;
var modelViewMatrixLoc;
var vBuffer, cBuffer;
function quad( a, b, c, d ) {
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[b]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[a]);
colors.push(vertexColors[a]);
points.push(vertices[c]);
colors.push(vertexColors[a]);
points.push(vertices[d]);
}
function colorCube() {
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
function scale4(a, b, c, d) {
var result = mat4();
result[0][0] = a;
result[1][1] = b;
result[2][2] = c;
result[3][3] = d;
return result;
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable( gl.DEPTH_TEST );
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
document.getElementById("slider1").oninput = function(event) {
theta[0] = event.target.value;
render();
};
document.getElementById("slider2").oninput = function(event) {
theta[1] = event.target.value;
render();
};
document.getElementById("slider3").oninput = function(event) {
theta[2] = event.target.value;
render();
};
document.getElementById("slider4").oninput = function(event) {
theta[3] = event.target.value;
render();
};
modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
projectionMatrix = ortho(-10, 10, -10, 10, -10, 10);
gl.uniformMatrix4fv( gl.getUniformLocation(program, "projectionMatrix"), false, flatten(projectionMatrix) );
render();
}
function base() {
var s = scale4(BASE_WIDTH, BASE_HEIGHT, BASE_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * BASE_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function upperArm() {
var s = scale4(UPPER_ARM_WIDTH, UPPER_ARM_HEIGHT, UPPER_ARM_WIDTH, 1);
var instanceMatrix = mult(translate( 0.0, 0.5 * UPPER_ARM_HEIGHT, 0.0 ),s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function lowerArm()
{
var s = scale4(LOWER_ARM_WIDTH, LOWER_ARM_HEIGHT, LOWER_ARM_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * LOWER_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
function middleArm()
{
var s = scale4(MIDDLE_ARM_WIDTH, MIDDLE_ARM_HEIGHT, MIDDLE_ARM_WIDTH, 1);
var instanceMatrix = mult( translate( 0.0, 0.5 * MIDDLE_ARM_HEIGHT, 0.0 ), s);
var t = mult(modelViewMatrix, instanceMatrix);
gl.uniformMatrix4fv( modelViewMatrixLoc, false, flatten(t) );
gl.drawArrays( gl.TRIANGLES, 0, NumVertices );
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
modelViewMatrix = rotate(theta[Base], [0, 1, 0]);
base();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, BASE_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[LowerArm], [0, 0, 1] ));
lowerArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, LOWER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[UpperArm], [0, 0, 1]) );
upperArm();
modelViewMatrix = mult(modelViewMatrix, translate(0.0, UPPER_ARM_HEIGHT, 0.0));
modelViewMatrix = mult(modelViewMatrix, rotate(theta[MiddleArm], [0, 0, 1]) );
middleArm();
requestAnimFrame(render);
}
<html>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 fColor;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main()
{
fColor = vColor;
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
void main()
{
gl_FragColor = fColor;
}
</script>
<script src="https://greggman.github.io/webgl-lint/webgl-lint.js" crossorigin></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="robotArm.js"></script>
<div id="slider1">
body angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider2">
lower arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider4">
middle arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<div id="slider3">
upper arm angle -180 <input id="slide" type="range"
min="-180" max="180" step="10" value="0"
/>
180
</div><br/>
<body>
<canvas id="gl-canvas" width="512"" height="512"
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
I am trying to render a 3D rotating triangle, in which all the sides of the triangle has a different texture. I have made all the necessary changes but my triangle is a bit out of shape and I have tried to change the texture on each side of the triangle but I was able to do only one side of the triangle and no matter what I do it only changes one side. I am not looking to get a specific texture as it can be anything but different on all sides. Not sure what I am doing wrong.
var canvas;
var gl;
var numVertices = 36;
var texSize = 256;
var numChecks = 8;
var program;
var texture1, texture2;
var t1, t2;
var c;
var flag = true;
var image1 = new Uint8Array(4*texSize*texSize);
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
var patchx = Math.floor(i/(texSize/numChecks));
var patchy = Math.floor(j/(texSize/numChecks));
if(patchx%2 ^ patchy%2) c = 255;
else c = 0;
//c = 255*(((i & 0x8) == 0) ^ ((j & 0x8) == 0))
image1[8*i*texSize+8*j] = c;
image1[5*i*texSize+5*j+3] = c;
image1[6*i*texSize+6*j+4] = c;
image1[4*i*texSize+4*j+3] = 255;
}
}
var image2 = new Uint8Array(4*texSize*texSize);
// Create a checkerboard pattern
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
image2[4*i*texSize+4*j] = 127+127*Math.sin(0.1*i*j);
image2[6*i*texSize+6*j+1] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+2] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+3] = 255;
}
}
var pointsArray = [];
var colorsArray = [];
var texCoordsArray = [];
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
var vertices = [
vec4(0.5, -0.2722, 0.2886),
vec4(0.0, -0.2722, -0.5773),
vec4(-0.5, -0.2722, 0.2886),
vec4(0.5, -0.5443, 0.0)
];
var vertexColors = [
vec4( 0.0, 1.0, 0.0, 1.0 ), // black
vec4( 1.0, 0.0, 0.0, 1.0 ), // red
vec4( 1.0, 1.0, 1.0, 1.0 ), // yellow
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 0.0, 0.0, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 0.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = [45.0, 45.0, 45.0];
var thetaLoc;
function configureTexture() {
texture1 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image1);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
texture2 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image2);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
function quad(a, b, c) {
pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[0]);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[1]);
pointsArray.push(vertices[c]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[2]);
pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[0]);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[2]);
pointsArray.push(vertices[c]);
colorsArray.push(vertexColors[a]);
texCoordsArray.push(texCoord[3]);
}
function colorCube()
{
quad( 0, 1, 2 ); // bottom
quad( 1, 0, 3 ); // side0
quad( 1, 2, 3 ); // side1
quad( 2, 0, 3 ); // side3
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
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
//
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
var cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var tBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );
var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
configureTexture();
gl.activeTexture( gl.TEXTURE0 );
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.uniform1i(gl.getUniformLocation( program, "Tex0"), 0);
gl.activeTexture( gl.TEXTURE1 );
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.uniform1i(gl.getUniformLocation( program, "Tex1"), 1);
thetaLoc = gl.getUniformLocation(program, "theta");
document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};
document.getElementById("ButtonT").onclick = function(){flag = !flag;};
render();
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if(flag) theta[axis] += 2.0;
gl.uniform3fv(thetaLoc, theta);
gl.drawArrays( gl.TRIANGLES, 0, numVertices );
requestAnimFrame(render);
}
<!DOCTYPE html>
<html>
<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>
<button id = "ButtonT">Toggle Rotation</button>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
attribute vec2 vTexCoord;
varying vec4 fColor;
varying vec2 fTexCoord;
uniform vec3 theta;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
vec3 angles = radians( theta );
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 );
fColor = vColor;
fTexCoord = vTexCoord;
gl_Position = rz * ry * rx * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
varying vec2 fTexCoord;
uniform sampler2D Tex0;
uniform sampler2D Tex1;
void
main()
{
gl_FragColor = fColor*(texture2D(Tex0, fTexCoord)*texture2D(Tex1, fTexCoord));
}
</script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="texture.js"></script>
<body>
<canvas id="gl-canvas" width="1024" height="1024">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
I'm not sure what kind of help you are looking for.
The normal way to put a different image on each side of a pyramid is to use a texture atlas. Here's an article that covers it.
Effectively you put all the images in to one texture and then use texture coordinates on each face of the pyramid to select one of the images.
The reason I ask if that's what you want is because using a texture atlas is pretty much how 99% of all WebGL apps and 3D graphics apps in general would solve the issue of putting a different texture on each face of a pyramid.
Solving it by actually using multiple textures is possible but it's generally not considered a good solution since then you'd need a different shader to shade a cube (8 textures) from a 4 sides pyramid (4 textures) and again different shaders for every number of textures. Further, there's a limit to the number of textures a single shader can use in one draw call.
Otherwise, the code you posted seems to only make 2 textures and multiplies them together
gl_FragColor = fColor*(texture2D(Tex0, fTexCoord)*texture2D(Tex1, fTexCoord));
So there's nothing in your code to select one texture or the other. You need to add some data to select the texture.
One way would be to add another attribute to your shaders to select the texture. You'd set that attribute to 0 to select Tex0 and 1 to select Tex1
varying float mixAmount; // passed in from vertex shader via attributes
...
vec4 color0 = texture2D(Tex0, fTexCoord);
vec4 color1 = texture2D(Tex1, fTexCoord);
vec4 color = mix(color0, color1, mixAmount);
gl_FragColor = fColor * color;
Where it selects texture 0 when mixAmount = 0 and texture 1 when mixAmount = 1
var canvas;
var gl;
var numVertices = 24;
var texSize = 256;
var numChecks = 8;
var program;
var texture1, texture2;
var t1, t2;
var c;
var flag = true;
var image1 = new Uint8Array(4*texSize*texSize);
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
var patchx = Math.floor(i/(texSize/numChecks));
var patchy = Math.floor(j/(texSize/numChecks));
if(patchx%2 ^ patchy%2) c = 255;
else c = 0;
//c = 255*(((i & 0x8) == 0) ^ ((j & 0x8) == 0))
image1[8*i*texSize+8*j] = c;
image1[5*i*texSize+5*j+3] = c;
image1[6*i*texSize+6*j+4] = c;
image1[4*i*texSize+4*j+3] = 255;
}
}
var image2 = new Uint8Array(4*texSize*texSize);
// Create a checkerboard pattern
for ( var i = 0; i < texSize; i++ ) {
for ( var j = 0; j <texSize; j++ ) {
image2[4*i*texSize+4*j] = 127+127*Math.sin(0.1*i*j);
image2[6*i*texSize+6*j+1] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+2] = 127+127*Math.sin(0.1*i*j);
image2[4*i*texSize+4*j+3] = 255;
}
}
var pointsArray = [];
var colorsArray = [];
var texCoordsArray = [];
var mixAmountsArray = [];
var texCoord = [
vec2(0, 0),
vec2(0, 1),
vec2(1, 1),
vec2(1, 0)
];
var vertices = [
vec4(0.5, -0.2722, 0.2886),
vec4(0.0, -0.2722, -0.5773),
vec4(-0.5, -0.2722, 0.2886),
vec4(0.5, -0.5443, 0.0)
];
var vertexColors = [
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 1.0, 0.0, 0.0, 1.0 ), // red
vec4( 1.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 0.0, 1.0 ), // green
vec4( 0.0, 0.0, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 0.0, 1.0, 1.0, 1.0 ), // cyan
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = [45.0, 45.0, 45.0];
var thetaLoc;
function configureTexture() {
texture1 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image1);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
texture2 = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, image2);
gl.generateMipmap( gl.TEXTURE_2D );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
gl.NEAREST_MIPMAP_LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
function quad(a, b, c, mixAmount) {
pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[0]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[1]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[c]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[2]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[a]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[0]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[b]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[2]);
mixAmountsArray.push(mixAmount);
pointsArray.push(vertices[c]);
colorsArray.push(vertexColors[2]);
texCoordsArray.push(texCoord[3]);
mixAmountsArray.push(mixAmount);
}
function colorCube()
{
quad( 0, 1, 2, 0 ); // bottom
quad( 1, 0, 3, 1 ); // side0
quad( 1, 2, 3, 0 ); // side1
quad( 2, 0, 3, 1 ); // side3
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
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
//
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
var cBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );
var vColor = gl.getAttribLocation( program, "vColor" );
gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vColor );
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
var tBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, tBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(texCoordsArray), gl.STATIC_DRAW );
var vTexCoord = gl.getAttribLocation( program, "vTexCoord" );
gl.vertexAttribPointer( vTexCoord, 2, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vTexCoord );
var mBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, mBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(mixAmountsArray), gl.STATIC_DRAW );
var vMixAmount = gl.getAttribLocation( program, "vMixAmount" );
gl.vertexAttribPointer( vMixAmount, 1, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vMixAmount );
configureTexture();
gl.activeTexture( gl.TEXTURE0 );
gl.bindTexture( gl.TEXTURE_2D, texture1 );
gl.uniform1i(gl.getUniformLocation( program, "Tex0"), 0);
gl.activeTexture( gl.TEXTURE1 );
gl.bindTexture( gl.TEXTURE_2D, texture2 );
gl.uniform1i(gl.getUniformLocation( program, "Tex1"), 1);
thetaLoc = gl.getUniformLocation(program, "theta");
document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};
document.getElementById("ButtonT").onclick = function(){flag = !flag;};
render();
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if(flag) theta[axis] += 2.0;
gl.uniform3fv(thetaLoc, theta);
gl.drawArrays( gl.TRIANGLES, 0, numVertices );
requestAnimFrame(render);
}
canvas { border: 1px solid black; }
<!DOCTYPE html>
<html>
<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>
<button id = "ButtonT">Toggle Rotation</button>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
attribute vec2 vTexCoord;
attribute float vMixAmount;
varying vec4 fColor;
varying vec2 fTexCoord;
varying float mixAmount;
uniform vec3 theta;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
vec3 angles = radians( theta );
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 );
mixAmount = vMixAmount;
fColor = vColor;
fTexCoord = vTexCoord;
gl_Position = rz * ry * rx * vPosition;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
varying vec2 fTexCoord;
varying float mixAmount;
uniform sampler2D Tex0;
uniform sampler2D Tex1;
void
main()
{
vec4 color0 = texture2D(Tex0, fTexCoord);
vec4 color1 = texture2D(Tex1, fTexCoord);
gl_FragColor = fColor * mix(color0, color1, mixAmount);
}
</script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/webgl-utils.js"></script>
<script type="text/javascript" src="https://esangel.github.io/WebGL/Common/initShaders.js"></script>
<script type="text/javascript"src="https://esangel.github.io/WebGL/Common/MV.js"></script>
<script type="text/javascript" src="texture.js"></script>
<body>
<canvas id="gl-canvas" width="200" height="200">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
That's only 2 textures. To do 4 textures you'd have to do more math and maybe have your mixAmount be 0 to 3
vec4 color0 = texture2D(Tex0, fTexCoord);
vec4 color1 = texture2D(Tex1, fTexCoord);
vec4 color2 = texture2D(Tex2, fTexCoord);
vec4 color3 = texture2D(Tex3, fTexCoord);
vec4 color = color0 * clamp(mixAmount, 0, 1) +
color1 * clamp(abs(1 - mixAmount, 0, 1) +
color2 * clamp(abs(2 - mixAmount, 0, 1) +
color3 * clamp(abs(3 - mixAmount, 0, 1);
gl_FragColor = fColor * color;
I am pretty new to webgl. I am given an assignment to do a loop animation for rotation then scaling, means it will always rotate then scale. However, the first loop is okay but the second loop the rotation( ) cannot escape the loop and enter the scale function like in the first loop. It will just keep rotating there with strange behaviour. I have set value step as the control variable for which function to run.
I show my code to my professor and he has no clue, and I spend more than 2 days on this single problem. Hope someone else can enlighten me, any help is very appreciated. My js code is long but i comment out the section to make it more readable.
The COMMON file is provided by lecturer
PROBLEM SOLVED
the problem lies in the else if (scaleFactor<=1) of function scaletion //1 , if I put any value smaller than 1 it works, any value >= 1 it works strange, and I have no idea ~
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>3D Sierpinski Gasket</title>
</head>
<body>
<div class="container">
Animation Speed..........
<input type="range" min="1" max="5" value="3" steps = "1" class="slider" id="animSpeed" onmouseup="updateAnimSpeed()">
<label class = "label" id= "aSpeedLabel">3</label><br>
Rotation Axis...............
<input type="range" min="1" max="2" steps="1" value="1" class="slider" id="rotationAxis" onmouseup="updateAxis()">
<p class = "label" id= "rAxisLabel">Axis Z</p><br>
Number of Subdivision
<input type="range" min="1" max="6" steps="1" value="4" class="slider" id="subDivision" onmouseup="updateDivision()">
<p class = "label" id= "subLabel">4</p><br>
<button type= "button" class= "animButton" id= "animButton" onclick="stopAnimate()">StopAnimate</button>
<button type= "button" class= "animButton" id= "animButton" onclick="animation()">Animate</button>
</div>
<div class= "gasket">
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 color;
varying vec2 v_texcoord;
attribute vec2 a_texcoord;
uniform mat4 initScale;
uniform mat4 translation;
uniform mat4 rotationX;
uniform mat4 rotationY;
uniform mat4 rotationZ;
uniform mat4 scaling;
void main()
{
gl_Position = vPosition * initScale * rotationX * rotationY * rotationZ * translation * scaling;
color = vColor;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 color;
void main()
{
gl_FragColor = color;
}
</script>
<script id="fragment-shader2" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D u_texture;
varying vec2 v_texcoord;
void main()
{
gl_FragColor = texture2D(u_texture, v_texcoord);
}
</script>
<script type="text/javascript" src="Common/webgl-utils.js"></script>
<script type="text/javascript" src="Common/initShaders.js"></script>
<script type="text/javascript" src="Common/MV.js"></script>
<script type="text/javascript" src="gasket4.js"></script>
<canvas id="gl-canvas" width="680" height="680" class="canvas">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</div>
</body>
</html>
var canvas;
var gl;
var program;
var points = []; //all points goes here
var colors = []; //all color data goes here
var vertices = [ //positions of the 4 inital corner vertices, will be subdivided
vec3( 0.0000, 0.0000, -1.0000 ),
vec3( 0.0000, 0.9428, 0.3333 ),
vec3( -0.8165, -0.4714, 0.3333 ),
vec3( 0.8165, -0.4714, 0.3333 )
];
var subDivisionCount = 6; //subdivision count
var aspectRatio = 1.5; //canvas aspect ratio
//determines if animation is being played, for cancellation purposes
var id;
var step = 0; //animation sequence
var nextSeq = false; //determine whether to go for next sequence
var radians = 0.0; //rotation angle
var scaleFactor = 1.0; //scale size
var posX = 0.0, posY = 0.0, posZ = 0.0; //position, -1.0 -> 1.0 clipped space
var rotationSpeed = 0.02, translationSpeed = 0.01, scaleSpeed = 0.01; //default animation speed
var animSpeedValue, axisToRotate;
var color1Value, color2Value, color3Value, color4Value, fracStyle;
var rotate2=false, rotate=true;
var animSpeed, aSpeedLabel, rotationAxis, rAxisLabel, subDivision, subLabel; //html controllers
var color1, color2, color3, color4, useTexture, animButton, fractalStyle, fractalLabel;
//////////////////////////////////////////////////////////variable//////////////////////////////////////////////////////////////////////////////////////////
window.onload = function init() //Main function
{
setUpWegGL(); //set up web gl
getAllController(); //reference to html controllers
divideTetra( vertices[0], vertices[1], vertices[2], vertices[3], subDivisionCount); //forms the gasket
configGL(); //configure wel gl settings
setUpVertexShader();
setUpFragmentShader(); //create buffer and link to shader program
initScale(0.7/aspectRatio,0.7,0.7); //scale down to a smaller size
scaling(1,1,1); //transformation
rotationX(0.0);
rotationY(0.0);
rotationZ(0.0);
translation(0.0,0.0,0.0);
animation();
//draw out the object
};
//////////////////////////////////////////////////////////animation start here//////////////////////////////////////////////////////////////////////////////////////////
function animation()
{
if (step==0)
rotation();
else if(step==1)
scaletion();
id=window.requestAnimFrame( animation );
render();
}
//////////////////////////////////////////////////////////animation function here//////////////////////////////////////////////////////////////////////////////////////////
function rotation(){
radians-=rotationSpeed*animSpeedValue;
if(radians<-3.142)
{ rotationSpeed=-rotationSpeed
}
else if (radians>=0)
{
step++; // step ++ to go to scale function , the problem is here in second loop, it cannot escape
rotationSpeed=-rotationSpeed
radians=0.0;
}
rotationZ(radians);
}
function translate(){
posX+=translationSpeed*animSpeedValue;
if(posX>0.5)
translationSpeed=-translationSpeed;
else if(posX<-0.5)
translationSpeed=-translationSpeed;
translation(posX,posX,posX);
}
function scaletion(){
scaleFactor+=scaleSpeed*animSpeedValue;
if(scaleFactor>2)
scaleSpeed=-scaleSpeed;
else if (scaleFactor<1)
{
scaleFactor=1.0;
step--; // step -- to go back to rotation
}
scaling(scaleFactor,scaleFactor,scaleFactor);
}
var requestAnimFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ;
function stopAnimate()
{cancelAnimationFrame( id );
}
//////////////////////////////////////////////////////////animation fucntion here/////////////////////////////////////////////////////////////////////////////
function getAllController()
{
animSpeed = document.getElementById("animSpeed");
aSpeedLabel = document.getElementById("aSpeedLabel");
rotationAxis= document.getElementById("rotationAxis");
rAxisLabel = document.getElementById("rAxisLabel");
subDivision = document.getElementById("subDivision");
subLabel = document.getElementById("subLabel");
animButton = document.getElementById("animButton");
color1 = document.getElementById("color1");
color2 = document.getElementById("color2");
color3 = document.getElementById("color3");
color4 = document.getElementById("color4");
animSpeedValue = animSpeed.value;
subDivisionCount = subDivision.value;
axisToRotate = rotationAxis.value;
color1Value = vec3(1.0, 0.0, 0.0);
color2Value = vec3(0.0, 1.0, 0.0);
color3Value = vec3(0.0, 0.0, 1.0);
color4Value = vec3(0.0, 0.2, 0.2);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function render()
{
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays( gl.TRIANGLES, 0, points.length);
}
function setUpWegGL()
{
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl )
alert( "WebGL isn't available" );
else
aspectRatio = canvas.width/canvas.height;
}
function configGL()
{
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.clearColor( 1.0, 1.0, 1.0, 1.0 );
gl.enable(gl.DEPTH_TEST); //hidden surface removal
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram(program);
}
function setUpVertexShader()
{
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(points), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" ); //get vertex shader from html file
gl.vertexAttribPointer( vPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray( vPosition );
}
function setUpFragmentShader()
{
var cBuffer = gl.createBuffer(); //allocate empty memory sapce
gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer ); //connect the memory space to gl
gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW ); //add data to the connected memory space
var vColor = gl.getAttribLocation( program, "vColor" ); //get frag shader from html file
gl.vertexAttribPointer( vColor, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray( vColor );
}
/////////////////////////// triangle ////////////////////////////////////////////////////////////////////////
function triangle( a, b, c, color )
{
var baseColors = //Change color here
[
color1Value,
color2Value,
color3Value,
color4Value
];
colors.push( baseColors[color] );
points.push( a );
colors.push( baseColors[color] );
points.push( b );
colors.push( baseColors[color] );
points.push( c );
}
function tetra( a, b, c, d )
{
triangle( a, c, b, 0 ); // tetrahedron with each side using a different color
triangle( a, c, d, 1 );
triangle( a, b, d, 2 );
triangle( b, c, d, 3 );
}
function divideTetra( a, b, c, d, count )
{
if ( count === 0 ) { //default state for recursion
tetra( a, b, c, d );
}
else
{ // find midpoints of sides
var ab = mix( a, b, 0.5 ); // divide four smaller tetrahedra , data type = array
var ac = mix( a, c, 0.5 );
var ad = mix( a, d, 0.5 );
var bc = mix( b, c, 0.5 );
var bd = mix( b, d, 0.5 );
var cd = mix( c, d, 0.5 );
--count;
divideTetra( a, ab, ac, ad, count ); //for all 4 faces of the tetrahedron
divideTetra( ab, b, bc, bd, count );
divideTetra( ac, bc, c, cd, count );
divideTetra( ad, bd, cd, d, count );
}
}
/////////////////////////// triangle ////////////////////////////////////////////////////////////////////////
// update //////////////////////////////////////////////////////////////////////////////////////////
function updateAxis()
{
if(rotationAxis.value == 1)
{
rAxisLabel.innerHTML = "Axis Z"
axisToRotate = 1;
}
else if(rotationAxis.value == 2)
{
rAxisLabel.innerHTML = "Axis Y";
axisToRotate = 2;
}
}
function updateAnimSpeed()
{
aSpeedLabel.innerHTML = animSpeed.value;
animSpeedValue = animSpeed.value;
}
function updateDivision()
{
subLabel.innerHTML = subDivision.value;
subDivisionCount = subDivision.value;
colors = [];
points = [];
}
// update //////////////////////////////////////////////////////////////////////////////////////////
////transformation///////////////////////////////////////////////////////////////////////////////
function translation(Tx, Ty, Tz)
{
var translationValue = mat4();
translationValue = [
1.0, 0.0, 0.0, Tx,
0.0, 1.0, 0.0, Ty,
0.0, 0.0, 1.0, Tz,
0.0, 0.0, 0.0, 1.0
];
var translation = gl.getUniformLocation(program, 'translation');
gl.uniformMatrix4fv(translation, false , translationValue );
}
function initScale(Sx, Sy, Sz)
{
var scaleMat = mat4();
scaleMat = [
Sx, 0.0, 0.0, 0.0,
0.0, Sy, 0.0, 0.0,
0.0, 0.0, Sz, 0.0,
0.0, 0.0, 0.0, 1.0
];
var initScale = gl.getUniformLocation(program, 'initScale');
gl.uniformMatrix4fv(initScale, false, scaleMat);
}
function scaling(Sx, Sy, Sz)
{
var scaleMat = mat4();
scaleMat = [
Sx, 0.0, 0.0, 0.0,
0.0, Sy, 0.0, 0.0,
0.0, 0.0, Sz, 0.0,
0.0, 0.0, 0.0, 1.0
];
var scaling = gl.getUniformLocation(program, 'scaling');
gl.uniformMatrix4fv(scaling, false, scaleMat);
}
function rotationX(theta)
{
var rotationMat = mat4();
rotationMat = [
1, 0.0, 0.0, 0.0,
0.0, Math.cos(theta), -Math.sin(theta) , 0.0,
0.0, Math.sin(theta) , Math.cos(theta) , 0.0,
0.0, 0.0, 0.0, 1.0
];
var rotateX = gl.getUniformLocation(program, 'rotationX')
gl.uniformMatrix4fv(rotateX, false, rotationMat);
}
function rotationY(theta)
{
var rotationMat = mat4();
rotationMat = [
Math.cos(theta), 0.0, Math.sin(theta), 0.0,
0.0, 1.0, 0.0 , 0.0,
-Math.sin(theta), 0.0 , Math.cos(theta) , 0.0,
0.0, 0.0, 0.0, 1.0
];
var rotateY = gl.getUniformLocation(program, 'rotationY')
gl.uniformMatrix4fv(rotateY, false, rotationMat);
}
function rotationZ(theta)
{
var rotationMat = mat4();
rotationMat = [
Math.cos(theta), -Math.sin(theta), 0.0, 0.0,
Math.sin(theta), Math.cos(theta), 0.0 , 0.0,
0.0, 0.0 , 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
];
var rotateZ = gl.getUniformLocation(program, 'rotationZ')
gl.uniformMatrix4fv(rotateZ, false, rotationMat);
}
////transformation///////////////////////////////////////////////////////////////////////////////
I need to solve a task on a webGl problem where I have to apply shading on a rotating an animated cube.
When I try to do this the problem is that the shade is applied but it is fixed while. While the cube is rotating I see the same faces darker and the others with more light , when I need to see them changing in a dynamic way.
Here is my code :
HTML
<!DOCTYPE html>
<html>
<button id = "ButtonX">Rotate X</button>
<button id = "ButtonY">Rotate Y</button>
<button id = "ButtonZ">Rotate Z</button>
<button id = "ButtonT">Toggle Rotation</button>
<button id="Direction">Change Direction</button>
<button id="OrthoPersp">Change Ortho/Persp</button>
<div>Traslation on X <input id="slideX" type="range"
min="-1" max="1" step="0.1" value="0" />
</div>
<div>Traslation on Y <input id="slideY" type="range"
min="-1" max="1" step="0.1" value="0" />
</div>
<div>Traslation on Z <input id="slideZ" type="range"
min="-1" max="1" step="0.1" value="0" />
</div>
<div>Scaling on X <input id="ScalingX" type="range"
min="0" max="1" step="0.1" value="0" />
</div>
<div>Scaling on Y <input id="ScalingY" type="range"
min="0" max="1" step="0.1" value="0" />
</div>
<div>Scaling on Z <input id="ScalingZ" type="range"
min="0" max="1" step="0.1" value="0" />
</div>
<div>
zNear Min<input id="zNearSlider" type="range" min="0.00" max="2.8" step="0.1" value="0.3">
Max
</div>
<div>
zFar Min<input id="zFarSlider" type="range" min="3" max="10" step="3.0" value="3">
Max
</div>
<script id="vertex-shader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec4 vColor;
varying vec4 fColor;
//uniform vec3 theta;
// Point 2 -> Move the matrices
// Per spostare le matrici le abbiamo dovuto dichiarare nel file GLSL come uniform
// le matrici rx ry e rz sono rispettivamente le matrici di rotazione sugli assi
uniform mat4 rx;
uniform mat4 ry;
uniform mat4 rz;
// Points 3 -> Traslation Matrix
uniform mat4 traslation;
// Points 3 -> Scaling Matrix
uniform mat4 scaling;
//Point 4 -> MV and P matrices
uniform mat4 modelView;
uniform mat4 projection;
//Poinit 6 -> Light Source
attribute vec3 vNormal;
uniform vec4 ambientProduct, diffuseProduct, specularProduct;
uniform vec4 lightPosition;
uniform float shininess;
void main()
{
// Compute the sines and cosines of theta for each of
// the three axes in one computation.
//vec3 angles = radians( theta );
//vec3 c = cos( angles );
//vec3 s = sin( angles );
// Remember: the 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 );
*/
//fColor = vColor;
// ORDINE : scaling -> rotazione -> traslation
//gl_Position = projection*modelView*scaling *rz * ry * rx * traslation *vPosition ;
//gl_Position.z = -gl_Position.z;
//Point 6
vec3 pos = -(modelView * vPosition).xyz;
vec3 light = lightPosition.xyz;
vec3 L = normalize( light - pos );
vec3 E = normalize( -pos );
vec3 H = normalize( L + E );
vec4 NN = vec4(vNormal,0);
vec3 N = normalize( (modelView*NN).xyz);
vec4 ambient = ambientProduct;
float Kd = max( dot(L, N), 0.0 );
vec4 diffuse = Kd*diffuseProduct;
float Ks = pow( max(dot(N, H), 0.0), shininess );
vec4 specular = Ks * specularProduct;
if( dot(L, N) < 0.0 ) {
specular = vec4(0.0, 0.0, 0.0, 1.0);
}
gl_Position = projection*modelView*scaling *rz * ry * rx * traslation *vPosition ;
//fColor = vColor;
//fColor = ambient + diffuse + specular;
fColor = (ambient + diffuse + specular);
fColor.a = 1.0;
// *******************
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 fColor;
void
main()
{
gl_FragColor = fColor;
}
</script>
<script type="text/javascript" src="../Common/webgl-utils.js"></script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MV.js"></script>
<script type="text/javascript" src="Homework1.js"></script>
<body>
<canvas id="gl-canvas" width="1024" height="1024">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
JavaScript
"use strict";
var canvas;
var gl;
var numVertices = 36;
var numChecks = 8;
var program;
var c;
var flag = true;
var direction = true;
var rx;
var ry;
var rz;
var traslation_loc;
var tx = 0 ;
var ty = 0;
var tz = 0;
var scaling_loc;
var sx = 1.0;
var sy = 1.0;
var sz = 1.0;
var pointsArray = [];
var colorsArray = [];
//Point 4
var near = 0.3;
var far = 3.0;
//var radius = 1.0;
var theta = 0.0;
//var phi = 0.0;
//var dr = 5.0 * Math.PI/180.0;
var left = -1.0;
var right = 1.0;
var ytop = 1.0;
var bottom = -1.0;
var mvMatrix, pMatrix;
var modelView, projection;
var eye;
const at = vec3(0.0, 0.0, 0.0);
const up = vec3(0.0, 1.0, 0.0);
var eye = vec3(1, 1, 1);
//var eye = vec3(0.02, 0.02, 0.02);
//
//Point 5
var fovy = 45.0;
var aspect;
var orthoBool = true;
var aspect = 1.0;
//
//Poinit 6
var lightAmbient = vec4(0.2, 0.2, 0.2, 1.0);
var lightDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
var lightSpecular = vec4(1.0, 1.0, 1.0, 1.0);
var lightPosition = vec4(1.0, 2.0, 3.0,1.0);
var materialAmbient = vec4(1.0, 0.0, 1.0, 1.0);
var materialDiffuse = vec4(1.0, 0.8, 0.0, 1.0);
var materialSpecular = vec4(1.0, 0.8, 0.0, 1.0);
var materialShininess = 100.0;
var ambientColor, diffuseColor, specularColor;
var normalsArray = [];
//
var vertices = [
vec4( -0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, 0.5, 0.5, 1.0 ),
vec4( 0.5, -0.5, 0.5, 1.0 ),
vec4( -0.5, -0.5, -0.5, 1.0 ),
vec4( -0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, 0.5, -0.5, 1.0 ),
vec4( 0.5, -0.5, -0.5, 1.0 )
];
/*
var 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, 1.0, 1.0 ), // blue
vec4( 1.0, 0.0, 1.0, 1.0 ), // magenta
vec4( 0.0, 1.0, 1.0, 1.0 ), // white
vec4( 0.0, 1.0, 1.0, 1.0 ) // cyan
];
*/
var xAxis = 0;
var yAxis = 1;
var zAxis = 2;
var axis = xAxis;
var theta = [45.0, 45.0, 45.0];
//var thetaLoc;
function quad(a, b, c, d) {
// Point 6
var t1 = subtract(vertices[b], vertices[a]);
var t2 = subtract(vertices[c], vertices[b]);
var normal = cross(t1, t2);
var normal = vec3(normal);
// *****
//*** Abbiamo rimpizzato i colori on queli del materiale per svolgere il punto 6
pointsArray.push(vertices[a]);
//colorsArray.push(vertexColors[a]);
normalsArray.push(normal);
pointsArray.push(vertices[b]);
//colorsArray.push(vertexColors[a]);
normalsArray.push(normal);
pointsArray.push(vertices[c]);
//colorsArray.push(vertexColors[a]);
normalsArray.push(normal);
pointsArray.push(vertices[a]);
//colorsArray.push(vertexColors[a]);
normalsArray.push(normal);
pointsArray.push(vertices[c]);
//colorsArray.push(vertexColors[a]);
normalsArray.push(normal);
pointsArray.push(vertices[d]);
//colorsArray.push(vertexColors[a]);
normalsArray.push(normal);
}
function colorCube()
{
quad( 1, 0, 3, 2 );
quad( 2, 3, 7, 6 );
quad( 3, 0, 4, 7 );
quad( 6, 5, 1, 2 );
quad( 4, 5, 6, 7 );
quad( 5, 4, 0, 1 );
}
window.onload = function init() {
canvas = document.getElementById( "gl-canvas" );
gl = WebGLUtils.setupWebGL( canvas );
if ( !gl ) { alert( "WebGL isn't available" ); }
gl.viewport( 0, 0, canvas.width, canvas.height );
// Point 5 -> define aspect
aspect = 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
//
program = initShaders( gl, "vertex-shader", "fragment-shader" );
gl.useProgram( program );
colorCube();
//Point 6
var nBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, nBuffer );
gl.bufferData( gl.ARRAY_BUFFER, flatten(normalsArray), gl.STATIC_DRAW );
var vNormal = gl.getAttribLocation( program, "vNormal" );
gl.vertexAttribPointer( vNormal, 3, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vNormal );
//*************
// RIMPIAZZATI I COLORI PER IL PUNTO 6
//var cBuffer = gl.createBuffer();
//gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
//gl.bufferData( gl.ARRAY_BUFFER, flatten(colorsArray), gl.STATIC_DRAW );
//var vColor = gl.getAttribLocation( program, "vColor" );
//gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
//gl.enableVertexAttribArray( vColor );
var vBuffer = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, vBuffer);
gl.bufferData( gl.ARRAY_BUFFER, flatten(pointsArray), gl.STATIC_DRAW );
var vPosition = gl.getAttribLocation( program, "vPosition" );
gl.vertexAttribPointer( vPosition, 4, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( vPosition );
// Possiamo commentare quello che riguarda il theta per il punto 2
//thetaLoc = gl.getUniformLocation(program, "theta");
// Point 2 - Rotation
//X AXIS
rx = gl.getUniformLocation(program, "rx");
//Y AXIS
ry = gl.getUniformLocation(program, "ry");
//Z AXIS
rz = gl.getUniformLocation(program, "rz");
// Traslation Matrix
traslation_loc = gl.getUniformLocation(program , "traslation");
// Scaling Matrix
scaling_loc = gl.getUniformLocation(program , "scaling");
// Projection and Model matrix
modelView = gl.getUniformLocation( program, "modelView" );
projection = gl.getUniformLocation( program, "projection" );
//**************
document.getElementById("ButtonX").onclick = function(){axis = xAxis;};
document.getElementById("ButtonY").onclick = function(){axis = yAxis;};
document.getElementById("ButtonZ").onclick = function(){axis = zAxis;};
document.getElementById("ButtonT").onclick = function(){flag = !flag;};
document.getElementById("Direction").onclick = function() { direction = !direction;};
document.getElementById( "slideX" ).oninput = function(){ tx = parseFloat(event.target.value,10); };
document.getElementById( "slideY" ).oninput = function(){ ty = parseFloat(event.target.value,10); };
document.getElementById( "slideZ" ).oninput = function(){ tz = parseFloat(event.target.value,10); };
document.getElementById( "ScalingX" ).oninput = function(){ sx = parseFloat(event.target.value,10); };
document.getElementById( "ScalingY" ).oninput = function(){ sy = parseFloat(event.target.value,10); };
document.getElementById( "ScalingZ" ).oninput = function(){ sz = parseFloat(event.target.value,10); };
// Point 5
document.getElementById("OrthoPersp").onclick = function(){orthoBool = !orthoBool;};
// Point 4
// per documentazine leggi la parte sotto il codice a pag 244 con spiegazione sul clip out
// cambiato inserito due sliders // perspective -> ortho -> + lontano
document.getElementById("zFarSlider").onchange = function() {
far = event.srcElement.value;
};
document.getElementById("zNearSlider").onchange = function() {
near = event.srcElement.value;
};
//Point 6
var ambientProduct = mult(lightAmbient, materialAmbient);
var diffuseProduct = mult(lightDiffuse, materialDiffuse);
var specularProduct = mult(lightSpecular, materialSpecular);
gl.uniform4fv(gl.getUniformLocation(program, "ambientProduct"),
flatten(ambientProduct));
gl.uniform4fv(gl.getUniformLocation(program, "diffuseProduct"),
flatten(diffuseProduct) );
gl.uniform4fv(gl.getUniformLocation(program, "specularProduct"),
flatten(specularProduct) );
gl.uniform4fv(gl.getUniformLocation(program, "lightPosition"),
flatten(lightPosition) );
gl.uniform1f(gl.getUniformLocation(program, "shininess"),materialShininess);
//*************************************
render();
}
var render = function() {
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// Point 4
//*************************************
//eye = vec3(radius*Math.sin(phi), radius*Math.sin(theta),
// radius*Math.cos(phi)); RIMANE COMMENTATO
//mvMatrix = lookAt(eye, at , up);
//pMatrix = ortho(left, right, bottom, ytop, near, far);
//gl.uniformMatrix4fv( modelView, false, flatten(mvMatrix) );
//gl.uniformMatrix4fv( projection, false, flatten(pMatrix) );
//*************************************
//Point 5
//*************************************
mvMatrix = lookAt(eye, at , up);
if (orthoBool) {
pMatrix = ortho(left, right, bottom, ytop, near, far); }
else {
pMatrix=perspective(fovy , aspect , near , far); }
gl.uniformMatrix4fv( modelView, false, flatten(mvMatrix) );
gl.uniformMatrix4fv( projection, false, flatten(pMatrix) );
//*************************************
// Point 3 -> Scaling
var scaling = [sx , 0.0 , 0.0 , 0.0,
0.0 , sy, 0.0 , 0.0,
0.0 , 0.0 , sz , 0.0,
0.0 , 0.0 , 0.0 , 1];
gl.uniformMatrix4fv(scaling_loc,false,scaling);
// ****************************************
//X AXIS - Point 2
var theta_x_degree = theta[0];
var theta_x_radians = theta_x_degree * Math.PI / 180;
var s_x = Math.sin(theta_x_radians);
var c_x = Math.cos(theta_x_radians);
var rx_loc = [ 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 ];
gl.uniformMatrix4fv(rx, false, rx_loc);
//Y AXIS - Point 2
var theta_y_degree = theta[1];
var theta_y_radians = theta_y_degree * Math.PI / 180;
var s_y = Math.sin(theta_y_radians);
var c_y = Math.cos(theta_y_radians);
var ry_loc = [ 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 ];
gl.uniformMatrix4fv(ry, false, ry_loc);
//Z AXIS - Point 2
var theta_z_degree = theta[2];
var theta_z_radians = theta_z_degree * Math.PI / 180;
var s_z = Math.sin(theta_z_radians);
var c_z = Math.cos(theta_z_radians);
var rz_loc = [ 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 ];
gl.uniformMatrix4fv(rz, false, rz_loc);
// ****************************************
// Point 3 -> Traslation
var traslation = [1.0 , 0.0 , 0.0 , 0.0,
0.0 , 1.0 , 0.0 , 0.0,
0.0 , 0.0 , 1.0 , 0.0,
tx , ty , tz , 1.0];
gl.uniformMatrix4fv(traslation_loc,false,traslation);
// ****************************************
// ****************************************
// Point 1 --> Change and Toggle Rotation
if((direction)&&(!flag)) theta[axis] += -2.0;
if((!direction)&&(!flag)) theta[axis] += +2.0;
if(!direction) {theta[axis] += -2.0; }
if(direction) {theta[axis] += 2.0 ; }
// ****************************************
//gl.uniform3fv(thetaLoc, theta);
gl.drawArrays( gl.TRIANGLES, 0, numVertices );
requestAnimFrame(render);
}
Your problem seem to be stemming from the fact you're calculating your final colour in the vertex shader then passing that to the fragment shader, this approach is called gourad shading. What you want to do instead is pass along the directional vectors you use for your lighting calculations and perform them in the fragment shader, that is per pixel lighting/phong shading.