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
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
# Project Description

[Live demo](https://adityagupta1.github.io/hw00-intro-base/)

In addition to the default icosphere, I've added two cubes and a grid to make a more interesting scene. Each object has the same shader, which includes a vertex shader that creates ripples with trigonometric functions and a fragment shader that mixes between warped patches of color and circular bubble-like patterns. The strength of the vertex displacement is modulated by another trigonometric function so you can see the mesh with full displacement and with no displacement. Both the vertex displacement and fragment color are also affected by time.

Additionally, the underside of the mesh shows some light emission separate from the normal Lambertian reflection. The color picker in the GUI also affects the overall color of the mesh, but some parts are affected more than others.

The frame rate of the project isn't great due to the many different noise functions used, but I think it looks really cool.

### No displacement
<img src="screenshots/no_displacement.png" width=500px />

### Fully displaced
<img src="screenshots/fully_displaced.png" width=500px />

### Underside
<img src="screenshots/underside.png" width=500px />

### Blue-green color
<img src="screenshots/seaweed.png" width=500px />

# HW 0: Intro to Javascript and WebGL

<p align="center">
Expand Down
4,086 changes: 4,066 additions & 20 deletions package-lock.json

Large diffs are not rendered by default.

Binary file added screenshots/fully_displaced.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/no_displacement.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/seaweed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/underside.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 115 additions & 0 deletions src/geometry/Cube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {vec3, vec4} from 'gl-matrix';
import Drawable from '../rendering/gl/Drawable';
import {gl} from '../globals';

class Cube extends Drawable {
indices: Uint32Array;
positions: Float32Array;
normals: Float32Array;
center: vec3;
sideLength: number;

constructor(center: vec3 = vec3.fromValues(0, 0, 0), sideLength: number = 2.0) {
super();
this.center = center;
this.sideLength = sideLength;
}

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
]);

for (let i = 0; i < this.positions.length; i++) {
if (i % 4 != 3) {
this.positions[i] *= this.sideLength / 2.0;
this.positions[i] += this.center[i % 4];
}
}

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);
}
};

export default Cube;
79 changes: 79 additions & 0 deletions src/geometry/Grid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {vec3, vec4} from 'gl-matrix';
import Drawable from '../rendering/gl/Drawable';
import {gl} from '../globals';

// XZ plane
class Grid extends Drawable {
indices: Uint32Array;
positions: Float32Array;
normals: Float32Array;
center: vec3;
sideLength: number;
resolution: number;

constructor(center: vec3, sideLength: number, resolution: number) {
super(); // Call the constructor of the super class. This is required.
this.center = center;
this.sideLength = sideLength;
this.resolution = resolution;
}

create() {
let vertsPerSide = this.resolution + 1;
let totalVerts = vertsPerSide * vertsPerSide;
let corner = vec3.fromValues(this.center[0] - this.sideLength / 2.0, this.center[1], this.center[2] - this.sideLength / 2.0);

this.indices = new Uint32Array(this.resolution * this.resolution * 6);
this.normals = new Float32Array(totalVerts * 4);
this.positions = new Float32Array(totalVerts * 4);

let edgeLength = 1.0 / this.resolution * this.sideLength;
for (let i = 0; i < totalVerts; ++i) {
let j = i * 4;

this.normals[j] = 0;
this.normals[j + 1] = 1;
this.normals[j + 2] = 0;
this.normals[j + 3] = 0;

this.positions[j] = corner[0] + ((i % vertsPerSide) * edgeLength);
this.positions[j + 1] = corner[1];
this.positions[j + 2] = corner[2] + ((i / vertsPerSide) * edgeLength);
this.positions[j + 3] = 1;
}

let nextIdx = 0;
// up to but not including last vertex on a side
for (let x = 0; x < this.resolution; ++x) {
for (let z = 0; z < this.resolution; ++z) {
let cornerVert = z * vertsPerSide + x;

this.indices[nextIdx] = cornerVert;
this.indices[nextIdx + 1] = cornerVert + 1;
this.indices[nextIdx + 2] = cornerVert + vertsPerSide;

this.indices[nextIdx + 3] = cornerVert + 1;
this.indices[nextIdx + 4] = cornerVert + vertsPerSide;
this.indices[nextIdx + 5] = cornerVert + vertsPerSide + 1;

nextIdx += 6;
}
}

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);
}
};

export default Grid;
31 changes: 18 additions & 13 deletions src/geometry/Square.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,30 @@ class Square extends Drawable {
indices: Uint32Array;
positions: Float32Array;
normals: Float32Array;
center: vec4;
center: vec3;

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);
this.center = center;
}

create() {

this.indices = new Uint32Array([0, 1, 2,
0, 2, 3]);
this.normals = new Float32Array([0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0]);
this.positions = new Float32Array([-1, -1, 0, 1,
1, -1, 0, 1,
1, 1, 0, 1,
-1, 1, 0, 1]);
this.indices = new Uint32Array([0, 1, 2,
0, 2, 3]);
this.normals = new Float32Array([0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0]);
this.positions = new Float32Array([-1, -1, 0, 1,
1, -1, 0, 1,
1, 1, 0, 1,
-1, 1, 0, 1]);

for (let i = 0; i < this.positions.length; i++) {
if (i % 4 != 3) {
this.positions[i] += this.center[i % 4];
}
}

this.generateIdx();
this.generatePos();
Expand Down
36 changes: 31 additions & 5 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,39 @@ import OpenGLRenderer from './rendering/gl/OpenGLRenderer';
import Camera from './Camera';
import {setGL} from './globals';
import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram';
import Cube from './geometry/Cube';
import Grid from './geometry/Grid';

// Define an object with application parameters and button callbacks
// This will be referred to by dat.GUI's functions that add GUI elements.
const controls = {
tesselations: 5,
color: [255, 255, 255],
'Load Scene': loadScene, // A function pointer, essentially
};

let icosphere: Icosphere;
let square: Square;
let prevTesselations: number = 5;
let cube1: Cube;
let cube2: Cube;
let grid: Grid;

let prevTesselations: number = controls.tesselations;

function loadScene() {
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, controls.tesselations);
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1.2, controls.tesselations);
icosphere.create();

square = new Square(vec3.fromValues(0, 0, 0));
square.create();

cube1 = new Cube(vec3.fromValues(2, 0, 0), 0.8);
cube1.create();
cube2 = new Cube(vec3.fromValues(-2, 0, 0), 0.8);
cube2.create();

grid = new Grid(vec3.fromValues(0, 0, 0), 5.0, 50);
grid.create();
}

function main() {
Expand All @@ -40,6 +56,10 @@ function main() {
gui.add(controls, 'tesselations', 0, 8).step(1);
gui.add(controls, 'Load Scene');

gui.addColor(controls, 'color').onChange((newColor: number[]) => {
renderer.setUniformColor(newColor);
});

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

renderer.setUniformColor(controls.color);

// This function will be called every frame
function tick() {
camera.update();
stats.begin();
gl.viewport(0, 0, window.innerWidth, window.innerHeight);
renderer.clear();
if(controls.tesselations != prevTesselations)
{

if (controls.tesselations != prevTesselations) {
prevTesselations = controls.tesselations;
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, prevTesselations);
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, controls.tesselations);
icosphere.create();
}

renderer.render(camera, lambert, [
icosphere,
// square,
cube1,
cube2,
grid,
]);
stats.end();

Expand Down
19 changes: 15 additions & 4 deletions src/rendering/gl/OpenGLRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ import ShaderProgram from './ShaderProgram';

// In this file, `gl` is accessible because it is imported above
class OpenGLRenderer {
constructor(public canvas: HTMLCanvasElement) {
}
uniformColor: vec4 = vec4.fromValues(0, 0, 0, 1);
time: number = 0;
prevTime: number = new Date().getTime();

constructor(public canvas: HTMLCanvasElement) {}

setClearColor(r: number, g: number, b: number, a: number) {
gl.clearColor(r, g, b, a);
Expand All @@ -22,16 +25,24 @@ class OpenGLRenderer {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}

setUniformColor(color255: number[]) {
this.uniformColor = vec4.fromValues(color255[0] / 255, color255[1] / 255, color255[2] / 255, 1);
}

render(camera: Camera, prog: ShaderProgram, drawables: Array<Drawable>) {
let model = mat4.create();
let viewProj = mat4.create();
let color = vec4.fromValues(1, 0, 0, 1);

mat4.identity(model);
mat4.multiply(viewProj, camera.projectionMatrix, camera.viewMatrix);
prog.setModelMatrix(model);
prog.setViewProjMatrix(viewProj);
prog.setGeometryColor(color);
prog.setGeometryColor(this.uniformColor);

let currentTime = new Date().getTime();
this.time += currentTime - this.prevTime;
this.prevTime = currentTime;
prog.setTime(this.time);

for (let drawable of drawables) {
prog.draw(drawable);
Expand Down
Loading