WebGL shapes disappearing - webgl

image3 Image1 When im rendering using requestAnimationFrame , Sometimes it generates only 1 circle or a big circle and small circles where both these circles need to have same radius.As you can see i am increasing the radius of circles during the requireanimationframe.if i have a r value of greater than 1 it renders the background circle and other small circles.if the r value is much smaller it doesnt render the background and renders an animated circle
var vertexShaderText =
[
'uniform vec2 u_resolution;',
'',
'attribute vec2 a_position;',
'',
'void main()',
'{',
'',
'vec2 clipspace = a_position / u_resolution * 2.0 -1.0 ;',
'',
'gl_Position = vec4(clipspace *vec2(2.5,-1.3) , 0, 1);',
'}'
].join("\n");
var fragmentShaderText =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.75, 0.85, 0.8, 0.85);',
'',
'}'
].join("\n");
var fragmentShaderText0 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(1.0,0.0,0.0,0.85);',
'',
'}'
].join("\n");
var fragmentShaderText1 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.0,1.0,0.0,1.0);',
'',
'}'
].join("\n");
var fragmentShaderText2 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.0,0.0,1.0,1.0);',
'',
'}'
].join("\n");
var fragmentShaderText3 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.5,0.0,0.0,1.0);',
'',
'}'
].join("\n");
var fragmentShaderText4 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.0,0.5,0.0,1.0);',
'',
'}'
].join("\n");
var fragmentShaderText5 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.0,0.0,0.5,1.0);',
'',
'}'
].join("\n");
var fragmentShaderText6 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.2,0.0,0.0,1.0);',
'',
'}'
].join("\n");
var fragmentShaderText7 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.0,0.2,0.0,1.0);',
'',
'}'
].join("\n");
var fragmentShaderText8 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.0,0.0,0.2,1.0);',
'',
'}'
].join("\n");
var fragmentShaderText9 =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0.2,0.2,0.0,1.0);',
'',
'}'
].join("\n");
var uni = function(){
var canvas = document.getElementById("game-surface");
var gl = canvas.getContext("webgl");
console.log("This is working");
var vertextShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertextShader,vertexShaderText);
gl.shaderSource(fragmentShader,fragmentShaderText);
gl.compileShader(vertextShader);
gl.compileShader(fragmentShader);
if(!gl.getShaderParameter(vertextShader,gl.COMPILE_STATUS)){
console.error("Error with vertexshader",gl.getShaderInfoLog(vertextShader));
return;
}
if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){
console.error("Error with fragmentShader",gl.getShaderInfoLog(fragmentShader));
return;
}
var program =gl.createProgram();
gl.attachShader(program,vertextShader);
gl.attachShader(program,fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
if(!gl.getProgramParameter(program,gl.LINK_STATUS)){
console.error("Error linking program",gl.getProgramInfoLog(program));
return;
}
gl.validateProgram(program);
if(!gl.getProgramParameter(program,gl.VALIDATE_STATUS)){
console.error("Error validating",gl.getProgramInfoLog(program));
}
var circle = {x: 150, y:75, r: 45};
var ATTRIBUTES = 2;
var numFans =32;
var degreePerFan = (2* Math.PI) / numFans;
var vertexData = [circle.x, circle.y];
for(var i = 0; i <=numFans; i++) {
var index = ATTRIBUTES * i + 2; // there is already 2 items in array
var angle = degreePerFan * (i+1000);
vertexData[index] = circle.x + Math.cos(angle) * circle.r;
vertexData[index + 1] = circle.y + Math.sin(angle) * circle.r;
}
var randomNumber = Math.floor(Math.random()*64);
var vertexDataTyped = new Float32Array(vertexData);
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexDataTyped, gl.STATIC_DRAW);
var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
gl.enableVertexAttribArray(positionLocation);
var positionLocation = gl.getAttribLocation(program, "a_position");
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0);
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertexData.length/ATTRIBUTES);
/////
var randomBacteria = Math.floor(Math.random()*10)+1;
console.log(randomBacteria);
for(var k = 0;k <randomBacteria;k++){
var b_colors = this["fragmentShaderText"+k];
gl.shaderSource(fragmentShader,b_colors);
gl.compileShader(fragmentShader);
var program1 =gl.createProgram();
gl.attachShader(program1,vertextShader);
gl.attachShader(program1,fragmentShader);
gl.linkProgram(program1);
gl.useProgram(program1);
var randomEven = Math.floor(Math.random()*67/2)*2;
var check = vertexData[randomEven];
if(check == 150){
var randomEven = null;
}
var bacteria = {x: vertexData[randomEven], y:vertexData[randomEven+1], r:1};
var ATTRIBUTES = 2;
var numFans =64;
var degreePerFan = (2*Math.PI) / numFans;
var bacteria_vertexData = [bacteria.x, bacteria.y];
function growth(){
if(bacteria.r<10){
requestAnimationFrame(growth);
for(var a=0;a<randomBacteria;a++){
bacteria.r += 1;
for(var i = 0; i <= numFans; i++) {
var index = ATTRIBUTES * i +2; // there is already 2 items in array
var angle = degreePerFan * (i);
bacteria_vertexData[index] = bacteria.x - Math.cos(angle) * bacteria.r;
bacteria_vertexData[index + 1] = bacteria.y - Math.sin(angle) * bacteria.r;
}
var bacteria_vertexDataTyped1 = new Float32Array(bacteria_vertexData);
console.log(bacteria_vertexData);
var bacteria_buffer1 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bacteria_buffer1);
gl.bufferData(gl.ARRAY_BUFFER, bacteria_vertexDataTyped1, gl.DYNAMIC_DRAW);
var program1 =gl.createProgram();
gl.attachShader(program1,vertextShader);
gl.attachShader(program1,fragmentShader);
gl.linkProgram(program1);
gl.useProgram(program1);
var bacteria_resolutionLocation = gl.getUniformLocation(program1, "u_resolution");
gl.uniform2f(bacteria_resolutionLocation, canvas.width, canvas.height);
var bacteria_positionLocation = gl.getAttribLocation(program1, "a_position");
gl.enableVertexAttribArray(bacteria_positionLocation);
gl.vertexAttribPointer(bacteria_positionLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0);
gl.drawArrays(gl.TRIANGLE_FAN, 0, bacteria_vertexData.length/ATTRIBUTES);
}
}
}
growth();
}
};

Related

Issue with webgl coloring

I'll start off by saying that I'm new to webgl, only picked it up a few days ago for a computer graphics class and I'm having a problem with an application using dat.gui. What it's supposed to do is draw a rectangle with 2 clicks and color it with the color selected with the dat.gui controller, but the color that I get is a sort of a mix going from green, yellow, red and left bottom corner is black. If I comment the gl.enableVertexAttribArray(_color); line the rectangles are all black, so all I can think of is I'm not storing the color information correctly. I would very much appreciate it if someone could point me towards a solution or at least towards the problem. `
<html>
<body>
<canvas width="570" height="570" id="my_Canvas"></canvas>
<script src="../lib/dat.gui.js"></script>
<script>
var canvas = document.getElementById('my_Canvas');
gl = canvas.getContext('experimental-webgl');
var vertCode =
'attribute vec3 coordinates;' +
'varying vec3 vColor;' +
'attribute vec3 color;' +
'void main(void){' +
' gl_Position=vec4(coordinates, 1.0);' +
'vColor=color;' +
'}';
var vertShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
var fragCode =
'precision highp float;' +
'varying vec3 vColor;' +
'void main(void){' +
' gl_FragColor=vec4(vColor, 1.0);' +
'}';
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
console.log(gl.getShaderInfoLog(vertShader));
console.log(gl.getProgramInfoLog(shaderProgram));
var gui = new dat.GUI();
var colore = {
colorv: [200, 200, 0]
};
gui.addColor(colore, 'colorv');
gl.clearColor(0.5, 0.5, 0.5, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
var g_indices = [0, 1, 2, 0, 1, 3];
var colors = [];
var p_counter = 0; //this counter is used to detect if the point clicked is the 2nd point
var g_counter = 0; //this is a global counter, used as a multiplier for g_points
var quad_g_counter;
var dodeca_g_counter;
var g_points = []; // the array for mousepress
var indices = [];
var vertex_buffer = gl.createBuffer();
var Index_Buffer = gl.createBuffer();
var color_Buffer = gl.createBuffer();
function click(ev, gl, canvas) {
var x = ev.clientX;
var y = ev.clientY;
var rect = ev.target.getBoundingClientRect();
x = ((x - rect.left) - canvas.height / 2) / (canvas.height / 2);
y = (canvas.width / 2 - (y - rect.top)) / (canvas.width / 2);
//store the coords in g_points array
g_points.push(x);
g_points.push(y);
g_points.push(0);
// clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
p_counter += 1;
if (p_counter == 2) {
//g_points
dodeca_g_counter = g_counter * 12;
g_points.push(g_points[dodeca_g_counter + 3]);
g_points.push(g_points[dodeca_g_counter + 1]);
g_points.push(0);
g_points.push(g_points[dodeca_g_counter]);
g_points.push(g_points[dodeca_g_counter + 4]);
g_points.push(0);
//indices
quad_g_counter = g_counter * 4;
indices.push(g_indices[0] + quad_g_counter);
indices.push(g_indices[1] + quad_g_counter);
indices.push(g_indices[2] + quad_g_counter);
indices.push(g_indices[3] + quad_g_counter);
indices.push(g_indices[4] + quad_g_counter);
indices.push(g_indices[5] + quad_g_counter);
//colors
for (var i = 0; i < 4; i += 1) {
colors.push(colore.colorv[0] / 255);
colors.push(colore.colorv[1] / 255);
colors.push(colore.colorv[2] / 255);
}
p_counter = 0;
g_counter += 1;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(g_points), gl.STATIC_DRAW);
//gl.bindBuffer(gl.ARRAY_BUFFER, null);
//gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
//gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
draw();
}
canvas.onmousedown = function(ev) {
click(ev, gl, canvas);
}
function draw() {
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);
var _color = gl.getAttribLocation(shaderProgram, "color");
gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(_color);
gl.useProgram(shaderProgram);
gl.enable(gl.DEPTH_TEST);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
}
</script>
</body>
</html>
You have to bind the proper vertex buffer before you call gl.vertexAttribPointer:
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
var _color = gl.getAttribLocation(shaderProgram, "color");
.....
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);
gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(_color);
Note, gl.vertexAttribPointer define an array of generic vertex attribute data refering to the currently bound ARRAY_BUFFER. See gl.bindBuffer.
Before you specify the vertex attributes for "coordinates" you bind vertex_buffer. But you don't bind color_Buffer befor you specify the vertex attributes for "color".
Because of that the vertex coordinate buffer is used for the color attributes too. his causes colorful lines and areas, because the colors are interpolated from point to point.
See the snippet:
var canvas = document.getElementById('my_Canvas');
gl = canvas.getContext('experimental-webgl');
var vertCode=
'attribute vec3 coordinates;' +
'varying vec3 vColor;' +
'attribute vec3 color;' +
'void main(void){' +
' gl_Position=vec4(coordinates, 1.0);' +
'vColor=color;' +
'}';
var vertShader=gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
var fragCode=
'precision highp float;' +
'varying vec3 vColor;' +
'void main(void){' +
' gl_FragColor=vec4(vColor, 1.0);' +
'}';
var fragShader=gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
var shaderProgram=gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
console.log(gl.getShaderInfoLog(vertShader));
console.log(gl.getProgramInfoLog(shaderProgram));
//var gui = new dat.GUI();
var colore={
colorv: [200,200,0]
};
//gui.addColor(colore, 'colorv');
gl.clearColor(0.5, 0.5, 0.5, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
var g_indices=[0,1,2,0,1,3];
var colors=[];
var p_counter=0; //this counter is used to detect if the point clicked is the 2nd point
var g_counter=0; //this is a global counter, used as a multiplier for g_points
var quad_g_counter;
var dodeca_g_counter;
var g_points = []; // the array for mousepress
var indices=[];
var vertex_buffer=gl.createBuffer();
var Index_Buffer=gl.createBuffer();
var color_Buffer=gl.createBuffer();
function click(ev,gl,canvas){
var x = ev.clientX;
var y = ev.clientY;
var rect = ev.target.getBoundingClientRect();
x = ((x - rect.left) - canvas.height/2)/(canvas.height/2);
y = (canvas.width/2 - (y - rect.top))/(canvas.width/2);
//store the coords in g_points array
g_points.push(x);g_points.push(y); g_points.push(0);
// clear <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
p_counter+=1;
if(p_counter==2){
//g_points
dodeca_g_counter=g_counter*12;
g_points.push(g_points[dodeca_g_counter+3]);g_points.push(g_points[dodeca_g_counter+1]);g_points.push(0);
g_points.push(g_points[dodeca_g_counter]);g_points.push(g_points[dodeca_g_counter+4]);g_points.push(0);
//indices
quad_g_counter=g_counter*4;
indices.push(g_indices[0]+quad_g_counter);indices.push(g_indices[1]+quad_g_counter);
indices.push(g_indices[2]+quad_g_counter);indices.push(g_indices[3]+quad_g_counter);
indices.push(g_indices[4]+quad_g_counter);indices.push(g_indices[5]+quad_g_counter);
//colors
for(var i=0; i<4; i+=1){
colors.push(colore.colorv[0]/255);colors.push(colore.colorv[1]/255);
colors.push(colore.colorv[2]/255);
}
p_counter=0;
g_counter+=1;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(g_points), gl.STATIC_DRAW);
//gl.bindBuffer(gl.ARRAY_BUFFER, null);
//gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
//gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
draw();
}
canvas.onmousedown = function(ev) {click(ev,gl,canvas);}
function draw(){
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
var coord=gl.getAttribLocation(shaderProgram, "coordinates");
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(coord);
gl.bindBuffer(gl.ARRAY_BUFFER, color_Buffer);
var _color=gl.getAttribLocation(shaderProgram, "color");
gl.vertexAttribPointer(_color, 3, gl.FLOAT, false, 0,0);
gl.enableVertexAttribArray(_color);
gl.useProgram(shaderProgram);
gl.enable(gl.DEPTH_TEST);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.viewport(0, 0, canvas.width, canvas.height);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
}
<canvas width="570" height="570" id="my_Canvas"></canvas>

Webgl Circle without using extrernal library

I am new to webgl and at this point I am able to create a triangle and square.
I am finding it difficult to understand how to create a circle with out any external scripts or libraries.
var vertexShaderText =
[
'uniform vec2 u_resolution;',
'',
'attribute vec2 a_position;',
'',
'void main()',
'{',
'',
'vec2 clipspace = a_position / u_resolution * 1.0 ;',
'',
'gl_Position = vec4(clipspace * vec2(2.5, 2.0), 0, 1);',
'}'
].join("\n");
var fragmentShaderText =
[
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0, 0, 0, 1.0);',
'',
'}'
].join("\n");
var uni = function(){
var canvas = document.getElementById("game-surface");
var gl = canvas.getContext("webgl");
console.log("This is working");
gl.clearColor(0.412,0.412,0.412,1);
gl.clear(gl.COLOR_BUFFER_BIT);
var vertextShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertextShader,vertexShaderText);
gl.shaderSource(fragmentShader,fragmentShaderText);
gl.compileShader(vertextShader);
gl.compileShader(fragmentShader);
if(!gl.getShaderParameter(vertextShader,gl.COMPILE_STATUS)){
console.error("Error with vertexshader",gl.getShaderInfoLog(vertextShader));
return;
}
if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){
console.error("Error with fragmentShader",gl.getShaderInfoLog(fragmentShader));
return;
}
var program =gl.createProgram();
gl.attachShader(program,vertextShader);
gl.attachShader(program,fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
if(!gl.getProgramParameter(program,gl.LINK_STATUS)){
console.error("Error linking program",gl.getProgramInfoLog(program));
return;
}
gl.validateProgram(program);
if(!gl.getProgramParameter(program,gl.VALIDATE_STATUS)){
console.error("Error validating",gl.getProgramInfoLog(program));
}
var circle = {x: 0, y:0, r: 75};
var ATTRIBUTES = 2;
var numFans = 64;
var degreePerFan = (2* Math.PI) / numFans;
var vertexData = [circle.x, circle.y];
for(var i = 0; i <= numFans; i++) {
var index = ATTRIBUTES * i + 2; // there is already 2 items in array
var angle = degreePerFan * (i+0.1);
vertexData[index] = circle.x + Math.cos(angle) * circle.r;
vertexData[index + 1] = circle.y + Math.sin(angle) * circle.r;
}
var vertexDataTyped = new Float32Array(vertexData);
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexDataTyped, gl.STATIC_DRAW);
var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
gl.enableVertexAttribArray(positionLocation);
var positionLocation = gl.getAttribLocation(program, "a_position");
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0);
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertexData.length/ATTRIBUTES);
};

Generate random shape along a point on circumference of circle

I am new to webgl ,i created a circle from vertices generated in a loop and i want a random shape(small circle) to be generated on some point along the circumference of the big circle.Can anyone provide me some info on how i can acheive this
Here is my code for the circle:
var vertexShaderText = [
'uniform vec2 u_resolution;',
'',
'attribute vec2 a_position;',
'',
'void main()',
'{',
'',
'vec2 clipspace = a_position / u_resolution * 1.0 ;',
'',
'gl_Position = vec4(clipspace * vec2(1, -1), 0, 1);',
'}'
].join("\n");
var fragmentShaderText = [
'precision mediump float;',
'',
'void main(void)',
'{',
'',
'gl_FragColor = vec4(0, 0, 0, 1.0);',
'',
'}'
].join("\n");
var uni = function(){
var canvas = document.getElementById("game-surface");
var gl = canvas.getContext("webgl",{antialias: true});
console.log("This is working");
gl.clearColor(0.412,0.412,0.412,1);
gl.clear(gl.COLOR_BUFFER_BIT);
var vertextShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertextShader,vertexShaderText);
gl.shaderSource(fragmentShader,fragmentShaderText);
gl.compileShader(vertextShader);
gl.compileShader(fragmentShader);
if(!gl.getShaderParameter(vertextShader,gl.COMPILE_STATUS)){
console.error("Error with vertexshader",gl.getShaderInfoLog(vertextShader));
return;
}
if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){
console.error("Error with fragmentShader",gl.getShaderInfoLog(fragmentShader));
return;
}
var program =gl.createProgram();
gl.attachShader(program,vertextShader);
gl.attachShader(program,fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);
if(!gl.getProgramParameter(program,gl.LINK_STATUS)){
console.error("Error linking program",gl.getProgramInfoLog(program));
return;
}
gl.validateProgram(program);
if(!gl.getProgramParameter(program,gl.VALIDATE_STATUS)){
console.error("Error validating",gl.getProgramInfoLog(program));
}
var circle = {x: 0, y:0, r: 55};
var ATTRIBUTES = 2;
var numFans = 32;
var degreePerFan = (2* Math.PI) / numFans;
var vertexData = [circle.x, circle.y];
for(var i = 0; i <= numFans; i++) {
var index = ATTRIBUTES * i + 2; // there is already 2 items in array
var angle = degreePerFan * (i+0.1);
vertexData[index] = circle.x + Math.cos(angle) * circle.r;
vertexData[index + 1] = circle.y + Math.sin(angle) * circle.r;
}
console.log(vertexData);
var vertexDataTyped = new Float32Array(vertexData);
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertexDataTyped, gl.STATIC_DRAW);
var resolutionLocation = gl.getUniformLocation(program, "u_resolution");
gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
gl.enableVertexAttribArray(positionLocation);
var positionLocation = gl.getAttribLocation(program, "a_position");
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT, 0);
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertexData.length/ATTRIBUTES);
};
uni();
<canvas id="game-surface"></canvas>
It's hard to answer your question because WebGL is just a rasterization library so there's literally 1000s of ways to draw something somewhere.
So, you can
add more points
You generated the circle points. Generate some more for whatever else you want to draw.
draw the same circle multiple times in different places and sizes
Let's say you wanted to draw a small circle on the big circle. Compute a matrix to scale and reorient the big circle where you want it to be, update the matrix, draw the circle again.
draw more things
Just like you drew the circle, draw something else like a square and position it at the edge of the circle.
1000 more ways...

shaders are not compiling

i have some problem maybe syntax maybe logic dont know but my shaders are not compiling when it passes through the console maybe someone knows whats happening, i followed the tutorial on youtube:WebGl Tutorial
var vertexShaderText =
[
'precision mediump float;',
'',
'attribute vec2 vertPosition;',
'',
'void main()',
'{',
'gl_position = vec4(vertPosition,0.0,1.0);',
'}'
].join('\n');
var fragmentShaderText =
[
'precision mediump float;',
'',
'void main()',
'{',
'gl_FragColor = vec4(1.0,0.0,0.0,1.0);',
'}'
].join('\n');
var initDemo = function()
{
console.log("this is working");
var canvas = document.getElementById("myCanvas");
var gl = canvas.getContext("webgl");
if(!gl)
{
console.log("your browser doesnt support webgl, trying expermiental");
gl = canvas.getContext("experimental-webgl");
}
if(!gl)
{
alert("your bwoser doesnt support webgl");
}
gl.clearColor(0,1,0,1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// create shadders
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vertexShader,vertexShaderText);
gl.shaderSource(fragmentShader,fragmentShaderText);
console.log(fragmentShader);
if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS))
{
console.error("Error compiling",gl.getShaderInfoLog(vertexShader));
}
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
gl.linkProgram(program);
if(!gl.getProgramParameter(program,gl.LINK_STATUS))
{
console.error("Error linking program",gl.getProgramInfoLog(program));
return;
}
gl.validateProgram(program);
if(!gl.getProgramParameter(program,gl.LINK_STATUS))
{
console.error("Error linking program",gl.getProgramInfoLog(program));
return;
}
var triangleVertices =
[
0.0,0.5,
0.5,0.5,
0.5,-0.5
]
var triangleVertexBufferObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexBufferObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices),gl.STATIC_DRAW);
var positionAtribLocation = gl.getAttribLocation(program,'vertPosition');
gl.vertexAttribPointer(
positionAtribLocation,
2,
gl.FLOAT,
gl.FALSE,
2 * Float32Array.BYTES_PER_ELEMENT,
0
);
gl.enableVertexAttribArray(positionAtribLocation);
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES,0,3);
}
Compilation errors for shaders can be queried using the following code:
var error_log = gl.getShaderInfoLog(vertexShader);
console.log(error_log);
In your case, you have at least written gl_position instead of gl_Position.
GLSL Shaders need to be prefixed with #version xxx In order to compile.
For safety, when I write GLSL shaders, I usually write them like this:
#version 400 core
layout(location = 0) in vec3 vertex;
void main() {
gl_Position = vec4(vertex, 1);
}
And I update the number if I need functionality that isn't available in GL4.0
Also, as another answer has already pointed out, you wrote gl_position instead of gl_Position

How to get a "Glow" shader effect in OpenGL ES 2.0?

I'm writing a 3D app for iOS. I'm new to OpenGL ES 2.0, so I'm still getting myself around writing basic shaders.
I really need to implement a "Glow" effect on some of my models, based on the texturing.
Here's a sample:
.
I'm looking for code examples for OpenGL ES 2.0. Most code I find on the internet is either for desktop OpenGL or D3D.
Any ideas?
First of all there are tons of algorithms and techniques to generate a glow effect.
I just want to present one possibility.
Create a Material that is luminescent.
For this I use a modified Blinn-Phong light model, where the direction to the light source is always the inverse direction of the normal vector of the fragment.
varying vec3 vertPos;
varying vec3 vertNV;
varying vec3 vertCol;
uniform float u_glow;
void main()
{
vec3 color = vertCol;
float shininess = 10.0;
vec3 normalV = normalize( vertNV );
vec3 eyeV = normalize( -vertPos );
vec3 halfV = normalize( eyeV + normalV );
float NdotH = max( 0.0, dot( normalV, halfV ) );
float glowFac = ( shininess + 2.0 ) * pow( NdotH, shininess ) / ( 2.0 * 3.14159265 );
gl_FragColor = vec4( u_glow * (0.1 + color.rgb * glowFac * 0.5), 1.0 );
}
In a second step a gaussian blur algorithm is performed on the output. The scene is written to frame buffer with a texture bound to the color plane. A screen space pass uses the texture as the input to blur the output.
For performance reasons, the blur algorithm is first performed along the X-axis of the viewport and in a further step along the Y-axis of the viewport.
varying vec2 vertPos;
uniform sampler2D u_textureCol;
uniform vec2 u_textureSize;
uniform float u_sigma;
uniform int u_width;
float CalcGauss( float x, float sigma )
{
float coeff = 1.0 / (2.0 * 3.14157 * sigma);
float expon = -(x*x) / (2.0 * sigma);
return (coeff*exp(expon));
}
void main()
{
vec2 texC = vertPos.st * 0.5 + 0.5;
vec4 texCol = texture( u_textureCol, texC );
vec4 gaussCol = vec4( texCol.rgb, 1.0 );
vec2 step = 1.0 / u_textureSize;
for ( int i = 1; i <= u_width; ++ i )
{
vec2 actStep = vec2( float(i) * step.x, 0.0 ); // this is for the X-axis
// vec2 actStep = vec2( 0.0, float(i) * step.y ); this would be for the Y-axis
float weight = CalcGauss( float(i) / float(u_width), u_sigma );
texCol = texture2D( u_textureCol, texC + actStep );
gaussCol += vec4( texCol.rgb * weight, weight );
texCol = texture2D( u_textureCol, texC - actStep );
gaussCol += vec4( texCol.rgb * weight, weight );
}
gaussCol.rgb /= gaussCol.w;
gl_FragColor = vec4( gaussCol.rgb, 1.0 );
}
For the implementation of a blur algorithm see also the answer to the questions:
OpenGL es 2.0 Gaussian blur on triangle
What kind of blurs can be implemented in pixel shaders?
See the following similar WebGL example which puts all together:
var readInput = true;
function changeEventHandler(event){
readInput = true;
}
(function loadscene() {
var resize, gl, progDraw, progBlurX, progPost, vp_size, blurFB;
var bufCube = {};
var bufQuad = {};
var shininess = 10.0;
var glow = 10.0;
var sigma = 0.8;
function render(delteMS){
//if ( readInput ) {
readInput = false;
var sliderScale = 100;
shininess = document.getElementById( "shine" ).value;
glow = document.getElementById( "glow" ).value / sliderScale;
sigma = document.getElementById( "sigma" ).value / sliderScale;
//}
Camera.create();
Camera.vp = vp_size;
gl.enable( gl.DEPTH_TEST );
gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
// set up framebuffer
gl.bindFramebuffer( gl.FRAMEBUFFER, blurFB[0] );
gl.viewport( 0, 0, blurFB[0].width, blurFB[0].height );
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
// set up draw shader
ShaderProgram.Use( progDraw.prog );
ShaderProgram.SetUniformM44( progDraw.prog, "u_projectionMat44", Camera.Perspective() );
ShaderProgram.SetUniformM44( progDraw.prog, "u_viewMat44", Camera.LookAt() );
var modelMat = IdentityMat44()
modelMat = RotateAxis( modelMat, CalcAng( delteMS, 13.0 ), 0 );
modelMat = RotateAxis( modelMat, CalcAng( delteMS, 17.0 ), 1 );
ShaderProgram.SetUniformM44( progDraw.prog, "u_modelMat44", modelMat );
ShaderProgram.SetUniformF1( progDraw.prog, "u_shininess", shininess );
ShaderProgram.SetUniformF1( progDraw.prog, "u_glow", glow );
// draw scene
VertexBuffer.Draw( bufCube );
// set blur-X framebuffer and bind frambuffer texture
gl.bindFramebuffer( gl.FRAMEBUFFER, blurFB[1] );
gl.viewport( 0, 0, blurFB[1].width, blurFB[1].height );
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
var texUnit = 1;
gl.activeTexture( gl.TEXTURE0 + texUnit );
gl.bindTexture( gl.TEXTURE_2D, blurFB[0].color0_texture );
// set up blur-X shader
ShaderProgram.Use( progBlurX.prog );
ShaderProgram.SetUniformI1( progBlurX.prog , "u_texture", texUnit )
ShaderProgram.SetUniformF2( progBlurX.prog , "u_textureSize", vp_size );
ShaderProgram.SetUniformF1( progBlurX.prog , "u_sigma", sigma )
// draw full screen space
gl.enableVertexAttribArray( progBlurX.inPos );
gl.bindBuffer( gl.ARRAY_BUFFER, bufQuad.pos );
gl.vertexAttribPointer( progBlurX.inPos, 2, gl.FLOAT, false, 0, 0 );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufQuad.inx );
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
gl.disableVertexAttribArray( progBlurX.inPos );
// reset framebuffer and bind frambuffer texture
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
gl.viewport( 0, 0, vp_size[0], vp_size[1] );
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
texUnit = 2;
gl.activeTexture( gl.TEXTURE0 + texUnit );
gl.bindTexture( gl.TEXTURE_2D, blurFB[1].color0_texture );
// set up pst process shader
ShaderProgram.Use( progPost.prog );
ShaderProgram.SetUniformI1( progPost.prog, "u_texture", texUnit )
ShaderProgram.SetUniformF2( progPost.prog, "u_textureSize", vp_size );
ShaderProgram.SetUniformF1( progPost.prog, "u_sigma", sigma );
// draw full screen space
gl.enableVertexAttribArray( progPost.inPos );
gl.bindBuffer( gl.ARRAY_BUFFER, bufQuad.pos );
gl.vertexAttribPointer( progPost.inPos, 2, gl.FLOAT, false, 0, 0 );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufQuad.inx );
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
gl.disableVertexAttribArray( progPost.inPos );
requestAnimationFrame(render);
}
function resize() {
//vp_size = [gl.drawingBufferWidth, gl.drawingBufferHeight];
vp_size = [window.innerWidth, window.innerHeight]
canvas.width = vp_size[0];
canvas.height = vp_size[1];
var fbsize = Math.max(vp_size[0], vp_size[1])-1;
fbsize = 1 << 31 - Math.clz32(fbsize); // nearest power of 2
fbsize = fbsize * 2
blurFB = [];
for ( var i = 0; i < 2; ++ i ) {
fb = gl.createFramebuffer();
fb.width = fbsize;
fb.height = fbsize;
gl.bindFramebuffer( gl.FRAMEBUFFER, fb );
fb.color0_texture = gl.createTexture();
gl.bindTexture( gl.TEXTURE_2D, fb.color0_texture );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, fb.width, fb.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
fb.renderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer( gl.RENDERBUFFER, fb.renderbuffer );
gl.renderbufferStorage( gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, fb.width, fb.height );
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fb.color0_texture, 0 );
gl.framebufferRenderbuffer( gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, fb.renderbuffer );
gl.bindTexture( gl.TEXTURE_2D, null );
gl.bindRenderbuffer( gl.RENDERBUFFER, null );
gl.bindFramebuffer( gl.FRAMEBUFFER, null );
blurFB.push( fb );
}
}
function initScene() {
canvas = document.getElementById( "canvas");
gl = canvas.getContext( "experimental-webgl" );
if ( !gl )
return null;
progDraw = {}
progDraw.prog = ShaderProgram.Create(
[ { source : "draw-shader-vs", stage : gl.VERTEX_SHADER },
{ source : "draw-shader-fs", stage : gl.FRAGMENT_SHADER }
] );
if ( !progDraw.prog )
return null;
progDraw.inPos = gl.getAttribLocation( progDraw.prog, "inPos" );
progDraw.inNV = gl.getAttribLocation( progDraw.prog, "inNV" );
progDraw.inCol = gl.getAttribLocation( progDraw.prog, "inCol" );
progBlurX = {}
progBlurX.prog = ShaderProgram.Create(
[ { source : "post-shader-vs", stage : gl.VERTEX_SHADER },
{ source : "blurX-shader-fs", stage : gl.FRAGMENT_SHADER }
] );
progBlurX.inPos = gl.getAttribLocation( progBlurX.prog, "inPos" );
if ( !progBlurX.prog )
return;
progPost = {}
progPost.prog = ShaderProgram.Create(
[ { source : "post-shader-vs", stage : gl.VERTEX_SHADER },
{ source : "blurY-shader-fs", stage : gl.FRAGMENT_SHADER }
] );
progPost.inPos = gl.getAttribLocation( progPost.prog, "inPos" );
if ( !progPost.prog )
return;
// create cube
var cubePos = [
-1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0,
-1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0 ];
var cubeCol = [ 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ];
var cubeHlpInx = [ 0, 1, 2, 3, 1, 5, 6, 2, 5, 4, 7, 6, 4, 0, 3, 7, 3, 2, 6, 7, 1, 0, 4, 5 ];
var cubePosData = [];
for ( var i = 0; i < cubeHlpInx.length; ++ i ) {
cubePosData.push( cubePos[cubeHlpInx[i]*3], cubePos[cubeHlpInx[i]*3+1], cubePos[cubeHlpInx[i]*3+2] );
}
var cubeNVData = [];
for ( var i1 = 0; i1 < cubeHlpInx.length; i1 += 4 ) {
var nv = [0, 0, 0];
for ( i2 = 0; i2 < 4; ++ i2 ) {
var i = i1 + i2;
nv[0] += cubePosData[i*3]; nv[1] += cubePosData[i*3+1]; nv[2] += cubePosData[i*3+2];
}
for ( i2 = 0; i2 < 4; ++ i2 )
cubeNVData.push( nv[0], nv[1], nv[2] );
}
var cubeColData = [];
for ( var is = 0; is < 6; ++ is ) {
for ( var ip = 0; ip < 4; ++ ip ) {
cubeColData.push( cubeCol[is*3], cubeCol[is*3+1], cubeCol[is*3+2] );
}
}
var cubeInxData = [];
for ( var i = 0; i < cubeHlpInx.length; i += 4 ) {
cubeInxData.push( i, i+1, i+2, i, i+2, i+3 );
}
bufCube = VertexBuffer.Create(
[ { data : cubePosData, attrSize : 3, attrLoc : progDraw.inPos },
{ data : cubeNVData, attrSize : 3, attrLoc : progDraw.inNV },
{ data : cubeColData, attrSize : 3, attrLoc : progDraw.inCol } ],
cubeInxData );
bufQuad.pos = gl.createBuffer();
gl.bindBuffer( gl.ARRAY_BUFFER, bufQuad.pos );
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( [ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ] ), gl.STATIC_DRAW );
bufQuad.inx = gl.createBuffer();
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufQuad.inx );
gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( [ 0, 1, 2, 0, 2, 3 ] ), gl.STATIC_DRAW );
window.onresize = resize;
resize();
requestAnimationFrame(render);
}
function Fract( val ) {
return val - Math.trunc( val );
}
function CalcAng( deltaTime, intervall ) {
return Fract( deltaTime / (1000*intervall) ) * 2.0 * Math.PI;
}
function CalcMove( deltaTime, intervall, range ) {
var pos = self.Fract( deltaTime / (1000*intervall) ) * 2.0
var pos = pos < 1.0 ? pos : (2.0-pos)
return range[0] + (range[1] - range[0]) * pos;
}
function EllipticalPosition( a, b, angRag ) {
var a_b = a * a - b * b
var ea = (a_b <= 0) ? 0 : Math.sqrt( a_b );
var eb = (a_b >= 0) ? 0 : Math.sqrt( -a_b );
return [ a * Math.sin( angRag ) - ea, b * Math.cos( angRag ) - eb, 0 ];
}
glArrayType = typeof Float32Array !="undefined" ? Float32Array : ( typeof WebGLFloatArray != "undefined" ? WebGLFloatArray : Array );
function IdentityMat44() {
var m = new glArrayType(16);
m[0] = 1; m[1] = 0; m[2] = 0; m[3] = 0;
m[4] = 0; m[5] = 1; m[6] = 0; m[7] = 0;
m[8] = 0; m[9] = 0; m[10] = 1; m[11] = 0;
m[12] = 0; m[13] = 0; m[14] = 0; m[15] = 1;
return m;
};
function RotateAxis(matA, angRad, axis) {
var aMap = [ [1, 2], [2, 0], [0, 1] ];
var a0 = aMap[axis][0], a1 = aMap[axis][1];
var sinAng = Math.sin(angRad), cosAng = Math.cos(angRad);
var matB = new glArrayType(16);
for ( var i = 0; i < 16; ++ i ) matB[i] = matA[i];
for ( var i = 0; i < 3; ++ i ) {
matB[a0*4+i] = matA[a0*4+i] * cosAng + matA[a1*4+i] * sinAng;
matB[a1*4+i] = matA[a0*4+i] * -sinAng + matA[a1*4+i] * cosAng;
}
return matB;
}
function Cross( a, b ) { return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0], 0.0 ]; }
function Dot( a, b ) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; }
function Normalize( v ) {
var len = Math.sqrt( v[0] * v[0] + v[1] * v[1] + v[2] * v[2] );
return [ v[0] / len, v[1] / len, v[2] / len ];
}
var Camera = {};
Camera.create = function() {
this.pos = [0, 3, 0.0];
this.target = [0, 0, 0];
this.up = [0, 0, 1];
this.fov_y = 90;
this.vp = [800, 600];
this.near = 0.5;
this.far = 100.0;
}
Camera.Perspective = function() {
var fn = this.far + this.near;
var f_n = this.far - this.near;
var r = this.vp[0] / this.vp[1];
var t = 1 / Math.tan( Math.PI * this.fov_y / 360 );
var m = IdentityMat44();
m[0] = t/r; m[1] = 0; m[2] = 0; m[3] = 0;
m[4] = 0; m[5] = t; m[6] = 0; m[7] = 0;
m[8] = 0; m[9] = 0; m[10] = -fn / f_n; m[11] = -1;
m[12] = 0; m[13] = 0; m[14] = -2 * this.far * this.near / f_n; m[15] = 0;
return m;
}
Camera.LookAt = function() {
var mz = Normalize( [ this.pos[0]-this.target[0], this.pos[1]-this.target[1], this.pos[2]-this.target[2] ] );
var mx = Normalize( Cross( this.up, mz ) );
var my = Normalize( Cross( mz, mx ) );
var tx = Dot( mx, this.pos );
var ty = Dot( my, this.pos );
var tz = Dot( [-mz[0], -mz[1], -mz[2]], this.pos );
var m = IdentityMat44();
m[0] = mx[0]; m[1] = my[0]; m[2] = mz[0]; m[3] = 0;
m[4] = mx[1]; m[5] = my[1]; m[6] = mz[1]; m[7] = 0;
m[8] = mx[2]; m[9] = my[2]; m[10] = mz[2]; m[11] = 0;
m[12] = tx; m[13] = ty; m[14] = tz; m[15] = 1;
return m;
}
var ShaderProgram = {};
ShaderProgram.Create = function( shaderList ) {
var shaderObjs = [];
for ( var i_sh = 0; i_sh < shaderList.length; ++ i_sh ) {
var shderObj = this.CompileShader( shaderList[i_sh].source, shaderList[i_sh].stage );
if ( shderObj == 0 )
return 0;
shaderObjs.push( shderObj );
}
var progObj = this.LinkProgram( shaderObjs )
if ( progObj != 0 ) {
progObj.attribIndex = {};
var noOfAttributes = gl.getProgramParameter( progObj, gl.ACTIVE_ATTRIBUTES );
for ( var i_n = 0; i_n < noOfAttributes; ++ i_n ) {
var name = gl.getActiveAttrib( progObj, i_n ).name;
progObj.attribIndex[name] = gl.getAttribLocation( progObj, name );
}
progObj.unifomLocation = {};
var noOfUniforms = gl.getProgramParameter( progObj, gl.ACTIVE_UNIFORMS );
for ( var i_n = 0; i_n < noOfUniforms; ++ i_n ) {
var name = gl.getActiveUniform( progObj, i_n ).name;
progObj.unifomLocation[name] = gl.getUniformLocation( progObj, name );
}
}
return progObj;
}
ShaderProgram.AttributeIndex = function( progObj, name ) { return progObj.attribIndex[name]; }
ShaderProgram.UniformLocation = function( progObj, name ) { return progObj.unifomLocation[name]; }
ShaderProgram.Use = function( progObj ) { gl.useProgram( progObj ); }
ShaderProgram.SetUniformI1 = function( progObj, name, val ) { if(progObj.unifomLocation[name]) gl.uniform1i( progObj.unifomLocation[name], val ); }
ShaderProgram.SetUniformF1 = function( progObj, name, val ) { if(progObj.unifomLocation[name]) gl.uniform1f( progObj.unifomLocation[name], val ); }
ShaderProgram.SetUniformF2 = function( progObj, name, arr ) { if(progObj.unifomLocation[name]) gl.uniform2fv( progObj.unifomLocation[name], arr ); }
ShaderProgram.SetUniformF3 = function( progObj, name, arr ) { if(progObj.unifomLocation[name]) gl.uniform3fv( progObj.unifomLocation[name], arr ); }
ShaderProgram.SetUniformF4 = function( progObj, name, arr ) { if(progObj.unifomLocation[name]) gl.uniform4fv( progObj.unifomLocation[name], arr ); }
ShaderProgram.SetUniformM33 = function( progObj, name, mat ) { if(progObj.unifomLocation[name]) gl.uniformMatrix3fv( progObj.unifomLocation[name], false, mat ); }
ShaderProgram.SetUniformM44 = function( progObj, name, mat ) { if(progObj.unifomLocation[name]) gl.uniformMatrix4fv( progObj.unifomLocation[name], false, mat ); }
ShaderProgram.CompileShader = function( source, shaderStage ) {
var shaderScript = document.getElementById(source);
if (shaderScript)
source = shaderScript.text;
var shaderObj = gl.createShader( shaderStage );
gl.shaderSource( shaderObj, source );
gl.compileShader( shaderObj );
var status = gl.getShaderParameter( shaderObj, gl.COMPILE_STATUS );
if ( !status ) alert(gl.getShaderInfoLog(shaderObj));
return status ? shaderObj : null;
}
ShaderProgram.LinkProgram = function( shaderObjs ) {
var prog = gl.createProgram();
for ( var i_sh = 0; i_sh < shaderObjs.length; ++ i_sh )
gl.attachShader( prog, shaderObjs[i_sh] );
gl.linkProgram( prog );
status = gl.getProgramParameter( prog, gl.LINK_STATUS );
if ( !status ) alert("Could not initialise shaders");
gl.useProgram( null );
return status ? prog : null;
}
var VertexBuffer = {};
VertexBuffer.Create = function( attributes, indices ) {
var buffer = {};
buffer.buf = [];
buffer.attr = []
for ( var i = 0; i < attributes.length; ++ i ) {
buffer.buf.push( gl.createBuffer() );
buffer.attr.push( { size : attributes[i].attrSize, loc : attributes[i].attrLoc } );
gl.bindBuffer( gl.ARRAY_BUFFER, buffer.buf[i] );
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( attributes[i].data ), gl.STATIC_DRAW );
}
buffer.inx = gl.createBuffer();
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, buffer.inx );
gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( indices ), gl.STATIC_DRAW );
buffer.inxLen = indices.length;
gl.bindBuffer( gl.ARRAY_BUFFER, null );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null );
return buffer;
}
VertexBuffer.Draw = function( bufObj ) {
for ( var i = 0; i < bufObj.buf.length; ++ i ) {
gl.bindBuffer( gl.ARRAY_BUFFER, bufObj.buf[i] );
gl.vertexAttribPointer( bufObj.attr[i].loc, bufObj.attr[i].size, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( bufObj.attr[i].loc );
}
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufObj.inx );
gl.drawElements( gl.TRIANGLES, bufObj.inxLen, gl.UNSIGNED_SHORT, 0 );
for ( var i = 0; i < bufObj.buf.length; ++ i )
gl.disableVertexAttribArray( bufObj.attr[i].loc );
gl.bindBuffer( gl.ARRAY_BUFFER, null );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null );
}
initScene();
})();
html,body {
height: 100%;
width: 100%;
margin: 0;
overflow: hidden;
}
#gui {
position : absolute;
top : 0;
left : 0;
}
<script id="draw-shader-vs" type="x-shader/x-vertex">
precision highp float;
attribute vec3 inPos;
attribute vec3 inNV;
attribute vec3 inCol;
varying vec3 vertPos;
varying vec3 vertNV;
varying vec3 vertCol;
uniform mat4 u_projectionMat44;
uniform mat4 u_viewMat44;
uniform mat4 u_modelMat44;
void main()
{
mat4 mv = u_viewMat44 * u_modelMat44;
vertCol = inCol;
vertNV = normalize(mat3(mv) * inNV);
vec4 viewPos = mv * vec4( inPos, 1.0 );
vertPos = viewPos.xyz;
gl_Position = u_projectionMat44 * viewPos;
}
</script>
<script id="draw-shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec3 vertPos;
varying vec3 vertNV;
varying vec3 vertCol;
uniform float u_shininess;
uniform float u_glow;
void main()
{
vec3 color = vertCol;
vec3 normalV = normalize( vertNV );
vec3 eyeV = normalize( -vertPos );
vec3 halfV = normalize( eyeV + normalV );
float NdotH = max( 0.0, dot( normalV, halfV ) );
float shineFac = ( u_shininess + 2.0 ) * pow( NdotH, u_shininess ) / ( 2.0 * 3.14159265 );
gl_FragColor = vec4( u_glow*0.1 + color.rgb * u_glow * shineFac * 0.5, 1.0 );
}
</script>
<script id="post-shader-vs" type="x-shader/x-vertex">
precision mediump float;
attribute vec2 inPos;
varying vec2 pos;
void main()
{
pos = inPos;
gl_Position = vec4( inPos, 0.0, 1.0 );
}
</script>
<script id="blurX-shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 pos;
uniform sampler2D u_texture;
uniform vec2 u_textureSize;
uniform float u_sigma;
float CalcGauss( float x, float sigma )
{
float coeff = 1.0 / (2.0 * 3.14157 * sigma);
float expon = -(x*x) / (2.0 * sigma);
return (coeff*exp(expon));
}
void main()
{
vec2 texC = pos.st * 0.5 + 0.5;
vec4 texCol = texture2D( u_texture, texC );
vec4 gaussCol = vec4( texCol.rgb, 1.0 );
float stepX = 1.0 / u_textureSize.x;
for ( int i = 1; i <= 20; ++ i )
{
float weight = CalcGauss( float(i) / 32.0, u_sigma * 0.5 );
texCol = texture2D( u_texture, texC + vec2( float(i) * stepX, 0.0 ) );
gaussCol += vec4( texCol.rgb * weight, weight );
texCol = texture2D( u_texture, texC - vec2( float(i) * stepX, 0.0 ) );
gaussCol += vec4( texCol.rgb * weight, weight );
}
gaussCol.rgb /= gaussCol.w;
gl_FragColor = vec4( gaussCol.rgb, 1.0 );
}
</script>
<script id="blurY-shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 pos;
uniform sampler2D u_texture;
uniform vec2 u_textureSize;
uniform float u_sigma;
float CalcGauss( float x, float sigma )
{
float coeff = 1.0 / (2.0 * 3.14157 * sigma);
float expon = -(x*x) / (2.0 * sigma);
return (coeff*exp(expon));
}
void main()
{
vec2 texC = pos.st * 0.5 + 0.5;
vec4 texCol = texture2D( u_texture, texC );
vec4 gaussCol = vec4( texCol.rgb, 1.0 );
float stepY = 1.0 / u_textureSize.y;
for ( int i = 1; i <= 20; ++ i )
{
float weight = CalcGauss( float(i) / 32.0, u_sigma * 0.5 );
texCol = texture2D( u_texture, texC + vec2( 0.0, float(i) * stepY ) );
gaussCol += vec4( texCol.rgb * weight, weight );
texCol = texture2D( u_texture, texC - vec2( 0.0, float(i) * stepY ) );
gaussCol += vec4( texCol.rgb * weight, weight );
}
vec3 hdrCol = 2.0 * gaussCol.xyz / gaussCol.w;
vec3 mappedCol = vec3( 1.0 ) - exp( -hdrCol.rgb * 3.0 );
gl_FragColor = vec4( clamp( mappedCol.rgb, 0.0, 1.0 ), 1.0 );
}
</script>
<div>
<form id="gui" name="inputs">
<table>
<tr> <td> <font color= #CCF>shininess</font> </td>
<td> <input type="range" id="shine" min="0" max="50" value="10" onchange="changeEventHandler(event);"/></td> </tr>
<tr> <td> <font color= #CCF>glow</font> </td>
<td> <input type="range" id="glow" min="100" max="400" value="250" onchange="changeEventHandler(event);"/></td> </tr>
<tr> <td> <font color= #CCF>blur</font> </td>
<td> <input type="range" id="sigma" min="1" max="100" value="60" onchange="changeEventHandler(event);"/></td> </tr>
</table>
</form>
</div>
<canvas id="canvas" style="border: none;" width="100%" height="100%"></canvas>
The website GLSL Sandbox has a collection of shader examples. This one has the glow and appears to be able to compile for ES.
You should be able to modify these to pull uv's from your texture.
Here is some code directly from this site:
#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
void main(void){
vec2 p = (gl_FragCoord.xy * 2.0 - resolution) / min(resolution.x, resolution.y);
vec3 color1 = vec3(0.0, 0.3, 0.5);
vec3 color2 = vec3(0.5, 0.0, 0.3);
float f = 0.0;
float g = 0.0;
float h = 0.0;
float PI = 3.14159265;
for(float i = 0.0; i < 40.0; i++){
if (floor(mouse.x * 41.0) < i)
break;
float s = sin(time + i * PI / 20.0) * 0.8;
float c = cos(time + i * PI / 20.0) * 0.8;
float d = abs(p.x + c);
float e = abs(p.y + s);
f += 0.001 / d;
g += 0.001 / e;
h += 0.00003 / (d * e);
}
gl_FragColor = vec4(f * color1 + g * color2 + vec3(h), 1.0);
}

Resources