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
2 changes: 0 additions & 2 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


name: Build and Deploy
on:
push:
Expand Down
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
# HW 0: Intro to Javascript and WebGL
## Yilin Liu
[Live Demo](https://bigfranklin1.github.io/CIS566-hw00-intro-base/)
## Objectives Achieved
1. A color palette to modify the shading color

2. A drop-down menu to switch shaders

3. A cube class that inherits from Drawable

4. A fragment shader that blends 3D perlin noise with shading color

5. A vertex shader that takes trigonometric function to animate the cube's vertices
## Screenshots

### Lambert
Added a color palette in dat.gui to change the diffuse color.
![image info](./images/lambert.png)
### Perlin Noise
Implemented a 3D Perlin Noise based on [code](https://www.shadertoy.com/view/ttsBWl) from shadertoy.
![image info](./images/perlin_noise.gif)

### Custom Vertex Shader
Added a custom vertex shader that uses a sin function to modify cube's vertices. The vertices will shrink towards the origin of the world (not its center though) to a center distance and then bounce back to the original positions.
![image info](./images/cube_transform.gif)

<p align="center">
<img width="360" height="360" src="https://user-images.githubusercontent.com/1758825/132532354-e3a45402-e484-499e-bfa7-2d73b9f2c946.png">
Expand Down
3 changes: 3 additions & 0 deletions dist/.vs/ProjectSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"CurrentProjectSetting": null
}
7 changes: 7 additions & 0 deletions dist/.vs/VSWorkspaceState.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\index.html",
"PreviewInSolutionExplorer": false
}
Binary file added dist/.vs/dist/v16/.suo
Binary file not shown.
Binary file added dist/.vs/slnx.sqlite
Binary file not shown.
Binary file added images/cube_transform.gif
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 images/lambert.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 images/perlin.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 images/perlin_noise.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
117 changes: 117 additions & 0 deletions src/geometry/Cube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
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([
// front
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,
// right
1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,
// back
0, 0, -1, 0,
0, 0, -1, 0,
0, 0, -1, 0,
0, 0, -1, 0,
// left
-1, 0, 0, 0,
-1, 0, 0, 0,
-1, 0, 0, 0,
-1, 0, 0, 0,
// top
0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0,
0, 1, 0, 0,
// bottom
0, -1, 0, 0,
0, -1, 0, 0,
0, -1, 0, 0,
0, -1, 0, 0
]);
this.positions = new Float32Array([
// front
this.center[0] - 1, this.center[1] - 1, this.center[2] + 1, 1,
this.center[0] + 1, this.center[1] - 1, this.center[2] + 1, 1,
this.center[0] + 1, this.center[1] + 1, this.center[2] + 1, 1,
this.center[0] - 1, this.center[1] + 1, this.center[2] + 1, 1,
// right
this.center[0] + 1, this.center[1] - 1, this.center[2] + 1, 1,
this.center[0] + 1, this.center[1] - 1, this.center[2] - 1, 1,
this.center[0] + 1, this.center[1] + 1, this.center[2] - 1, 1,
this.center[0] + 1, this.center[1] + 1, this.center[2] + 1, 1,
// back
this.center[0] - 1, this.center[1] - 1, this.center[2] - 1, 1,
this.center[0] + 1, this.center[1] - 1, this.center[2] - 1, 1,
this.center[0] + 1, this.center[1] + 1, this.center[2] - 1, 1,
this.center[0] - 1, this.center[1] + 1, this.center[2] - 1, 1,
// left
this.center[0] - 1, this.center[1] - 1, this.center[2] + 1, 1,
this.center[0] - 1, this.center[1] - 1, this.center[2] - 1, 1,
this.center[0] - 1, this.center[1] + 1, this.center[2] - 1, 1,
this.center[0] - 1, this.center[1] + 1, this.center[2] + 1, 1,
// top
this.center[0] + 1, this.center[1] + 1, this.center[2] + 1, 1,
this.center[0] + 1, this.center[1] + 1, this.center[2] - 1, 1,
this.center[0] - 1, this.center[1] + 1, this.center[2] - 1, 1,
this.center[0] - 1, this.center[1] + 1, this.center[2] + 1, 1,
// bottom
this.center[0] + 1, this.center[1] - 1, this.center[2] + 1, 1,
this.center[0] - 1, this.center[1] - 1, this.center[2] + 1, 1,
this.center[0] - 1, this.center[1] - 1, this.center[2] - 1, 1,
this.center[0] + 1, this.center[1] - 1, this.center[2] - 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;
66 changes: 58 additions & 8 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import {vec3} from 'gl-matrix';
import {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 +17,30 @@ import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram';
const controls = {
tesselations: 5,
'Load Scene': loadScene, // A function pointer, essentially
'Shader': 0,
'Color': [ 0, 128, 255 ],
'Shaders': 'Transform',
'Noise Color': [ 255, 255, 255 ],
};

let icosphere: Icosphere;
let square: Square;
let cube: Cube;
let time: vec4 = vec4.fromValues(0, 0, 0, 0);
let color: vec4;
let noiseColor: vec4;

let prevTesselations: number = 5;

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

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

cube = new Cube(vec3.fromValues(0, 0, 0));
cube.create();
}

function main() {
Expand All @@ -39,6 +56,10 @@ function main() {
const gui = new DAT.GUI();
gui.add(controls, 'tesselations', 0, 8).step(1);
gui.add(controls, 'Load Scene');
gui.addColor(controls, 'Color');
gui.addColor(controls, 'Noise Color');
// gui.add(controls, 'Shader', 0, 1).step(1);
gui.add(controls, 'Shaders', [ 'Lambert', 'Perlin Noise', 'Transform' ] );

// get canvas and webgl context
const canvas = <HTMLCanvasElement> document.getElementById('canvas');
Expand All @@ -63,23 +84,52 @@ function main() {
new Shader(gl.VERTEX_SHADER, require('./shaders/lambert-vert.glsl')),
new Shader(gl.FRAGMENT_SHADER, require('./shaders/lambert-frag.glsl')),
]);

const perlin = new ShaderProgram([
new Shader(gl.VERTEX_SHADER, require('./shaders/perlin-vert.glsl')),
new Shader(gl.FRAGMENT_SHADER, require('./shaders/perlin-frag.glsl')),
]);
const transform = new ShaderProgram([
new Shader(gl.VERTEX_SHADER, require('./shaders/transform-vert.glsl')),
new Shader(gl.FRAGMENT_SHADER, require('./shaders/lambert-frag.glsl')),
]);
// This function will be called every frame
function tick() {
time = vec4.fromValues(time[0] + 0.01,0,0,0);
color = vec4.fromValues(controls.Color[0] /255, controls.Color[1] / 255, controls.Color[2] / 255, 1);
noiseColor = vec4.fromValues(controls['Noise Color'][0] /255, controls['Noise Color'][1] / 255, controls['Noise Color'][2] / 255, 1);

camera.update();
stats.begin();
gl.viewport(0, 0, window.innerWidth, window.innerHeight);
renderer.clear();
if(controls.tesselations != prevTesselations)
{
prevTesselations = controls.tesselations;
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, prevTesselations);
icosphere = new Icosphere(vec3.fromValues(3, 0, 0), 1, prevTesselations);
icosphere.create();
}
renderer.render(camera, lambert, [
icosphere,
// square,
]);
var shader;
if(controls.Shaders == 'Lambert'){
shader = lambert;
renderer.render(camera, time, color, noiseColor, shader, [
cube, icosphere,
]);
}
if(controls.Shaders == 'Perlin Noise'){
shader = perlin;
renderer.render(camera, time, color, noiseColor, shader, [
cube, icosphere,
]);

}
if(controls.Shaders == 'Transform'){
shader = transform;
renderer.render(camera, time, color, noiseColor, shader, [
cube,
]);
}


stats.end();

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

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

// 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.setNoiseColor(noiseColor);

prog.setTime(time);
// prog.setColor(color);

for (let drawable of drawables) {
prog.draw(drawable);
Expand Down
18 changes: 18 additions & 0 deletions src/rendering/gl/ShaderProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class ShaderProgram {
unifModelInvTr: WebGLUniformLocation;
unifViewProj: WebGLUniformLocation;
unifColor: WebGLUniformLocation;
unifNoiseColor: WebGLUniformLocation;
unifTime: WebGLUniformLocation;
unifCenter: WebGLUniformLocation;

constructor(shaders: Array<Shader>) {
this.prog = gl.createProgram();
Expand All @@ -48,6 +51,9 @@ class ShaderProgram {
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.unifNoiseColor = gl.getUniformLocation(this.prog, "u_NoiseColor");
this.unifTime = gl.getUniformLocation(this.prog, "u_Time");
this.unifCenter = gl.getUniformLocation(this.prog, "u_Center");
}

use() {
Expand All @@ -56,6 +62,12 @@ class ShaderProgram {
activeProgram = this.prog;
}
}
setTime(t: vec4){
this.use();
if(this.unifTime !== -1){
gl.uniform4fv(this.unifTime, t);
}
}

setModelMatrix(model: mat4) {
this.use();
Expand Down Expand Up @@ -85,6 +97,12 @@ class ShaderProgram {
}
}

setNoiseColor(color: vec4) {
this.use();
if (this.unifNoiseColor !== -1) {
gl.uniform4fv(this.unifNoiseColor, color);
}
}
draw(d: Drawable) {
this.use();

Expand Down
Loading