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
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# HW 0: Noisy Planet Part 1 (Intro to Javascript and WebGL)

## Submission Information
This project does a handful of things:
1. Adds a 'cube' class that creates VBO data representing a 3D cube.
2. Adds some GUI options (detailed below).
3. Implements a fragment shader using perlin noise and "FBM".
4. Implements a vertex shader.

### GUI overview
<p align="center">
<img src="https://user-images.githubusercontent.com/6472567/133539341-feb7a316-1e1c-4804-8ec0-b4a9860c2d00.png">
</p>
<p align="center">Main GUI</p>

This project adds 2 feaures of note: Setting the default Shader color (the 'color' option) which is a bias added to the fragment shader algorithm, and the "warpDirectionX", "warpDirectionY", and "warpDirectionZ" controls which set the vector along which the shapes are transformed.

### Shaders
The fragment shader is relatively uninteresting. It simply implements Perlin noise using a quintic interpolation function with a custom color wheel. It is ran multiple times with an FBM-like algorithm to produce the current output. I am not very satisfied with the choice of random functions currently (for generating the perlin vectors), but I didn't have the bandwith to improve it much.

The vertex shader is a bit more interesting: It takes in a vector, and projects each vertex on to that vector. Based on the projected vertices' position on the vector, they are periodically shrunk via 'sin' over time. The results are more interesting than I originally thought with different vectors or the "warpDirection" as specified in the UI.

### Live Demo Location
Enjoy: https://ciscprocess.github.io/hw00-webgl-intro/

# Original Assignment
<p align="center">
<img width="360" height="360" src="https://user-images.githubusercontent.com/1758825/132532354-e3a45402-e484-499e-bfa7-2d73b9f2c946.png">
</p>
Expand Down
118 changes: 118 additions & 0 deletions src/geometry/Cube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
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: 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]);

for (let i = 0; i < this.positions.length; i += 4) {
this.positions[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);

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

export default Cube;
46 changes: 37 additions & 9 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
import {vec3} from 'gl-matrix';
import { vec3, vec4, mat4 } 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';
import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram';
import { setGL } from './globals';
import ShaderProgram, { Shader } from './rendering/gl/ShaderProgram';

// 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,
'Load Scene': loadScene, // A function pointer, essentially
color: [128, 128, 128],
warpDirectionX: 1,
warpDirectionY: 0,
warpDirectionZ: 0
};

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,10 +48,14 @@ function main() {
const gui = new DAT.GUI();
gui.add(controls, 'tesselations', 0, 8).step(1);
gui.add(controls, 'Load Scene');
gui.add(controls, 'warpDirectionX');
gui.add(controls, 'warpDirectionY');
gui.add(controls, 'warpDirectionZ');
gui.addColor(controls, 'color');

// get canvas and webgl context
const canvas = <HTMLCanvasElement> document.getElementById('canvas');
const gl = <WebGL2RenderingContext> canvas.getContext('webgl2');
const canvas = <HTMLCanvasElement>document.getElementById('canvas');
const gl = <WebGL2RenderingContext>canvas.getContext('webgl2');
if (!gl) {
alert('WebGL 2 not supported!');
}
Expand Down Expand Up @@ -70,23 +83,38 @@ function main() {
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.create();
}

lambert.tickTime();
lambert.setGeometryColor(
vec4.fromValues(
controls.color[0] / 255.,
controls.color[1] / 255.,
controls.color[2] / 255.,
1));

lambert.setWarpDirection(
vec3.fromValues(
controls.warpDirectionX,
controls.warpDirectionY,
controls.warpDirectionZ));

lambert.setModelMatrix(mat4.translate(mat4.create(), mat4.create(), vec3.fromValues(4, 0, 0)));
renderer.render(camera, lambert, [
icosphere,
// square,
cube
]);
stats.end();

// Tell the browser to call `tick` again whenever it renders a new frame
requestAnimationFrame(tick);
}

window.addEventListener('resize', function() {
window.addEventListener('resize', function () {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.setAspectRatio(window.innerWidth / window.innerHeight);
camera.updateProjectionMatrix();
Expand Down
6 changes: 2 additions & 4 deletions src/rendering/gl/OpenGLRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {mat4, vec4} from 'gl-matrix';
import { mat4, vec4 } from 'gl-matrix';
import Drawable from './Drawable';
import Camera from '../../Camera';
import {gl} from '../../globals';
import { gl } from '../../globals';
import ShaderProgram from './ShaderProgram';

// In this file, `gl` is accessible because it is imported above
Expand All @@ -25,13 +25,11 @@ class OpenGLRenderer {
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);

for (let drawable of drawables) {
prog.draw(drawable);
Expand Down
33 changes: 28 additions & 5 deletions src/rendering/gl/ShaderProgram.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {vec4, mat4} from 'gl-matrix';
import { vec4, vec3, mat4 } from 'gl-matrix';
import Drawable from './Drawable';
import {gl} from '../../globals';
import { gl } from '../../globals';

var activeProgram: WebGLProgram = null;

Expand All @@ -24,14 +24,18 @@ class ShaderProgram {
attrPos: number;
attrNor: number;
attrCol: number;
ticks: number;

unifModel: WebGLUniformLocation;
unifModelInvTr: WebGLUniformLocation;
unifViewProj: WebGLUniformLocation;
unifColor: WebGLUniformLocation;
unifTime: WebGLUniformLocation;
unifWarpDir: WebGLUniformLocation;

constructor(shaders: Array<Shader>) {
this.prog = gl.createProgram();
this.ticks = 0;

for (let shader of shaders) {
gl.attachShader(this.prog, shader.shader);
Expand All @@ -44,10 +48,12 @@ class ShaderProgram {
this.attrPos = gl.getAttribLocation(this.prog, "vs_Pos");
this.attrNor = gl.getAttribLocation(this.prog, "vs_Nor");
this.attrCol = gl.getAttribLocation(this.prog, "vs_Col");
this.unifModel = gl.getUniformLocation(this.prog, "u_Model");
this.unifModel = gl.getUniformLocation(this.prog, "u_Model");
this.unifModelInvTr = gl.getUniformLocation(this.prog, "u_ModelInvTr");
this.unifViewProj = gl.getUniformLocation(this.prog, "u_ViewProj");
this.unifColor = gl.getUniformLocation(this.prog, "u_Color");
this.unifViewProj = gl.getUniformLocation(this.prog, "u_ViewProj");
this.unifColor = gl.getUniformLocation(this.prog, "u_Color");
this.unifTime = gl.getUniformLocation(this.prog, "u_Time");
this.unifWarpDir = gl.getUniformLocation(this.prog, "u_WarpDir");
}

use() {
Expand All @@ -57,6 +63,16 @@ class ShaderProgram {
}
}

tickTime() {
this.use();
if (this.unifTime !== -1) {
gl.uniform1i(this.unifTime, this.ticks++);
console.log('tiiicks: ' + this.ticks);
} else {
console.log('Cannot find time var.');
}
}

setModelMatrix(model: mat4) {
this.use();
if (this.unifModel !== -1) {
Expand Down Expand Up @@ -85,6 +101,13 @@ class ShaderProgram {
}
}

setWarpDirection(dir: vec3) {
this.use();
if (this.unifWarpDir !== -1) {
gl.uniform3fv(this.unifWarpDir, dir);
}
}

draw(d: Drawable) {
this.use();

Expand Down
Loading