Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions src/geometry/Cube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import {vec3, vec4} from 'gl-matrix';
import Drawable from '../rendering/gl/Drawable';
import {gl} from '../globals';

class Cube extends Drawable {
// buffer: ArrayBuffer;
indices: Uint32Array;
positions: Float32Array;
normals: Float32Array;
center: vec4;

constructor(center: vec3) {
super(); // Call the constructor of the super class. This is required.
this.center = vec4.fromValues(center[0], center[1], center[2], 1);
}

create() {
this.indices = new Uint32Array([0, 1, 2, 0, 2, 3,
4, 5, 6, 4, 6, 7,
8, 9, 10, 8, 10, 11,
12, 13, 14, 12, 14, 15,
16, 17, 18, 16, 18, 19,
20, 21, 22, 20, 22, 23]);

this.normals = new Float32Array([0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,

0, 0, -1, 0,
0, 0, -1, 0,
0, 0, -1, 0,
0, 0, -1, 0,

1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,

-1, 0, 0, 0,
-1, 0, 0, 0,
-1, 0, 0, 0,
-1, 0, 0, 0,

0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0,

0, -1, 0, 0,
0, -1, 0, 0,
0, -1, 0, 0,
0, -1, 0, 0]);

this.positions = new Float32Array([-1, -1, 1, 1,
1, -1, 1, 1,
1, 1, 1, 1,
-1, 1, 1, 1,

-1, -1, -1, 1,
1, -1, -1, 1,
1, 1, -1, 1,
-1, 1, -1, 1,

1, -1, -1, 1,
1, 1, -1, 1,
1, 1, 1, 1,
1, -1, 1, 1,

-1, -1, -1, 1,
-1, 1, -1, 1,
-1, 1, 1, 1,
-1, -1, 1, 1,

-1, 1, -1, 1,
1, 1, -1, 1,
1, 1, 1, 1,
-1, 1, 1, 1,

-1, -1, -1, 1,
1, -1, -1, 1,
1, -1, 1, 1,
-1, -1, 1, 1]);


this.generateIdx();
this.generatePos();
this.generateNor();

this.count = this.indices.length;
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufIdx);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);

gl.bindBuffer(gl.ARRAY_BUFFER, this.bufNor);
gl.bufferData(gl.ARRAY_BUFFER, this.normals, gl.STATIC_DRAW);

gl.bindBuffer(gl.ARRAY_BUFFER, this.bufPos);
gl.bufferData(gl.ARRAY_BUFFER, this.positions, gl.STATIC_DRAW);

console.log(`Created cube`);
}
};

export default Cube;
30 changes: 27 additions & 3 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {vec3} from 'gl-matrix';
import {vec3, vec4} from 'gl-matrix';
const Stats = require('stats-js');
import * as DAT from 'dat.gui';
import Icosphere from './geometry/Icosphere';
import Square from './geometry/Square';
import Cube from './geometry/Cube';
import OpenGLRenderer from './rendering/gl/OpenGLRenderer';
import Camera from './Camera';
import {setGL} from './globals';
Expand All @@ -13,17 +14,25 @@ import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram';
const controls = {
tesselations: 5,
'Load Scene': loadScene, // A function pointer, essentially
//'color.r' : 1,
//'color.g' : 0,
//'color.b' : 0,
color : [255,0,0,1]
};

let icosphere: Icosphere;
let square: Square;
let cube: Cube;
let prevTesselations: number = 5;

function loadScene() {
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, controls.tesselations);
icosphere.create();
square = new Square(vec3.fromValues(0, 0, 0));
square.create();
cube = new Cube(vec3.fromValues(0, 0, 0));
cube.create();

}

function main() {
Expand All @@ -39,6 +48,10 @@ function main() {
const gui = new DAT.GUI();
gui.add(controls, 'tesselations', 0, 8).step(1);
gui.add(controls, 'Load Scene');
//gui.add(controls, 'color.r', 0, 1).step(0.05);
//gui.add(controls, 'color.g', 0, 1).step(0.05);
//gui.add(controls, 'color.b', 0, 1).step(0.05);
gui.addColor(controls, 'color');

// get canvas and webgl context
const canvas = <HTMLCanvasElement> document.getElementById('canvas');
Expand All @@ -64,22 +77,33 @@ function main() {
new Shader(gl.FRAGMENT_SHADER, require('./shaders/lambert-frag.glsl')),
]);

const customShader = new ShaderProgram([
new Shader(gl.VERTEX_SHADER, require('./shaders/custom-vert.glsl')),
new Shader(gl.FRAGMENT_SHADER, require('./shaders/custom-frag.glsl')),
]);

// This function will be called every frame
function tick() {
camera.update();
stats.begin();
gl.viewport(0, 0, window.innerWidth, window.innerHeight);
renderer.clear();
//let col = vec4.fromValues(controls['color.r'], controls['color.g'], controls['color.b'], 1)
let col = controls.color
if(controls.tesselations != prevTesselations)
{
prevTesselations = controls.tesselations;
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, prevTesselations);
icosphere.create();
}
renderer.render(camera, lambert, [
renderer.render(camera,
//lambert,
customShader,
[
icosphere,
// square,
]);
// cube
], col);
stats.end();

// Tell the browser to call `tick` again whenever it renders a new frame
Expand Down
5 changes: 3 additions & 2 deletions src/rendering/gl/OpenGLRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ class OpenGLRenderer {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}

render(camera: Camera, prog: ShaderProgram, drawables: Array<Drawable>) {
render(camera: Camera, prog: ShaderProgram, drawables: Array<Drawable>, col: number[]) {
let model = mat4.create();
let viewProj = mat4.create();
let color = vec4.fromValues(1, 0, 0, 1);
//let color = vec4.fromValues(1, 0, 0, 1);
let color = vec4.fromValues(col[0]/255, col[1]/255, col[2]/255, col[3]);

mat4.identity(model);
mat4.multiply(viewProj, camera.projectionMatrix, camera.viewMatrix);
Expand Down
66 changes: 66 additions & 0 deletions src/shaders/custom-frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#version 300 es

// This is a fragment shader. If you've opened this file first, please
// open and read lambert.vert.glsl before reading on.
// Unlike the vertex shader, the fragment shader actually does compute
// the shading of geometry. For every pixel in your program's output
// screen, the fragment shader is run for every bit of geometry that
// particular pixel overlaps. By implicitly interpolating the position
// data passed into the fragment shader by the vertex shader, the fragment shader
// can compute what color to apply to its pixel based on things like vertex
// position, light position, and vertex color.
precision highp float;

uniform vec4 u_Color; // The color with which to render this instance of geometry.

// These are the interpolated values out of the rasterizer, so you can't know
// their specific values without knowing the vertices that contributed to them
in vec4 fs_Nor;
in vec4 fs_LightVec;
in vec4 fs_Col;

out vec4 out_Col; // This is the final output color that you will see on your
// screen for the pixel that is currently being processed.

// // Randomization function
float randNoise(vec3 xyz, float frequency){
float r = fract(fract(cos(xyz.x * frequency) * 47453.5453) + xyz.y);
//float y = fract(cos(co.y*(91.3458)) * 47453.5453);
return r;
}

float noise (vec3 xyz) {
float r = 0.f;
float persistance = 1.0f / 20.f;
for(int i = 0; i < 8; i++) {
float frequency = pow(2.0f, float(i));
//float amplitude = pow(persistance, float(i));
float amplitude = pow(persistance, float(i));
r += randNoise(xyz, frequency);
}
return r;
}

void main()
{
// Material base color (before shading)
float r = noise(fs_Nor.xyz);
uColor.x = uColor.x * r;
uColor.y = uColor.y * r;
uColor.z = uColor.z * r;
//vec4 diffuseColor = vec4(fract(u_Color.x * r), fract(u_Color.y * r), fract(u_Color.z * r), u_Color.w);
vec4 diffuseColor = normalize(u_Color);
// Calculate the diffuse term for Lambert shading
float diffuseTerm = dot(normalize(fs_Nor), normalize(fs_LightVec));
// Avoid negative lighting values
// diffuseTerm = clamp(diffuseTerm, 0, 1);

float ambientTerm = 0.2;

float lightIntensity = diffuseTerm + ambientTerm; //Add a small float value to the color multiplier
//to simulate ambient lighting. This ensures that faces that are not
//lit by our point light are not completely black.

// Compute final shaded color
out_Col = vec4(diffuseColor.rgb * lightIntensity, diffuseColor.a);
}
53 changes: 53 additions & 0 deletions src/shaders/custom-vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#version 300 es

//This is a vertex shader. While it is called a "shader" due to outdated conventions, this file
//is used to apply matrix transformations to the arrays of vertex data passed to it.
//Since this code is run on your GPU, each vertex is transformed simultaneously.
//If it were run on your CPU, each vertex would have to be processed in a FOR loop, one at a time.
//This simultaneous transformation allows your program to run much faster, especially when rendering
//geometry with millions of vertices.

uniform mat4 u_Model; // The matrix that defines the transformation of the
// object we're rendering. In this assignment,
// this will be the result of traversing your scene graph.

uniform mat4 u_ModelInvTr; // The inverse transpose of the model matrix.
// This allows us to transform the object's normals properly
// if the object has been non-uniformly scaled.

uniform mat4 u_ViewProj; // The matrix that defines the camera's transformation.
// We've written a static matrix for you to use for HW2,
// but in HW3 you'll have to generate one yourself

in vec4 vs_Pos; // The array of vertex positions passed to the shader

in vec4 vs_Nor; // The array of vertex normals passed to the shader

in vec4 vs_Col; // The array of vertex colors passed to the shader.

out vec4 fs_Nor; // The array of normals that has been transformed by u_ModelInvTr. This is implicitly passed to the fragment shader.
out vec4 fs_LightVec; // The direction in which our virtual light lies, relative to each vertex. This is implicitly passed to the fragment shader.
out vec4 fs_Col; // The color of each vertex. This is implicitly passed to the fragment shader.

const vec4 lightPos = vec4(5, 5, 3, 1); //The position of our virtual light, which is used to compute the shading of
//the geometry in the fragment shader.


void main()
{
fs_Col = vs_Col; // Pass the vertex colors to the fragment shader for interpolation

mat3 invTranspose = mat3(u_ModelInvTr);
fs_Nor = vec4(invTranspose * vec3(vs_Nor), 0); // Pass the vertex normals to the fragment shader for interpolation.
// Transform the geometry's normals by the inverse transpose of the
// model matrix. This is necessary to ensure the normals remain
// perpendicular to the surface after the surface is transformed by
// the model matrix.

vec4 modelposition = u_Model * vs_Pos; // Temporarily store the transformed vertex positions for use below

fs_LightVec = lightPos - modelposition; // Compute the direction in which the light source lies

gl_Position = u_ViewProj * modelposition;// gl_Position is a built-in variable of OpenGL which is
// used to render the final positions of the geometry's vertices
}