Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hansen Yi - CIS 566 Homework 0 #26

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
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
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@
</p>
<p align="center">(source: Ken Perlin)</p>

## Description
- Added a Cube class that inherits from Drawable to be used to render cubes
- Updated the GUI to contain an option to change the color of the rendered geometry
- Created a custom fragment shader that utilized perlin noise based on 3D inputs to modify the fragment's color, as well as a custom vertex shader that utilizes sin and cos to modify the cube's vertex positions non-uniformly over time

## Screenshots
![Demo Screenshot 1](https://github.com/hansen-yi/hw00-intro-base/assets/97490525/12107d7b-5cf6-49c1-9e2d-1f91625d6306)
![Demo Screenshot 2](https://github.com/hansen-yi/hw00-intro-base/assets/97490525/eac8f130-d2c0-4023-b898-a9a6da75cbc1)
![Demo Screenshot 3](https://github.com/hansen-yi/hw00-intro-base/assets/97490525/ed229187-9535-4976-b6f4-7c8a7f9840f4)
![Demo Screenshot 4](https://github.com/hansen-yi/hw00-intro-base/assets/97490525/4c4ba6be-1844-48d6-843d-73f22561a06b)
![Demo Screenshot 5](https://github.com/hansen-yi/hw00-intro-base/assets/97490525/d7a31636-fe42-4695-9071-6dd892c0aee8)

## Link to Live Demo
https://hansen-yi.github.io/hw00-intro-base/

## Objective
- Check that the tools and build configuration we will be using for the class works.
- Start learning Typescript and WebGL2
Expand Down
3,866 changes: 2,298 additions & 1,568 deletions package-lock.json

Large diffs are not rendered by default.

136 changes: 136 additions & 0 deletions src/geometry/Cube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
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.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;
33 changes: 28 additions & 5 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 @@ -14,16 +15,24 @@ const controls = {
tesselations: 5,
'Load Scene': loadScene, // A function pointer, essentially
};
const palette = {
color: [255, 0, 0],
}

let icosphere: Icosphere;
let square: Square;
let prevTesselations: number = 5;
let cube: Cube;
let prevColor: Array<number> = [255, 0, 0];
let time: number = 0;

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

// get canvas and webgl context
const canvas = <HTMLCanvasElement> document.getElementById('canvas');
Expand All @@ -60,8 +70,10 @@ function main() {
gl.enable(gl.DEPTH_TEST);

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

// This function will be called every frame
Expand All @@ -76,10 +88,21 @@ function main() {
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, prevTesselations);
icosphere.create();
}
// console.log(prevColor);
if(palette.color != prevColor)
{
console.log(prevColor);
prevColor = palette.color;
lambert.setGeometryColor(vec4.fromValues(prevColor[0] / 255.0, prevColor[1] / 255.0, prevColor[2] / 255.0, 1));
}
time++;
renderer.render(camera, lambert, [
icosphere,
// icosphere,
// square,
]);
cube,
],
vec4.fromValues(prevColor[0] / 255.0, prevColor[1] / 255.0, prevColor[2] / 255.0, 1),
time);
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,16 +22,17 @@ 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>, color: vec4, time: 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);

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

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

constructor(shaders: Array<Shader>) {
this.prog = gl.createProgram();
Expand All @@ -48,6 +49,7 @@ 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.unifTime = gl.getUniformLocation(this.prog, "u_Time");
}

use() {
Expand Down Expand Up @@ -84,7 +86,14 @@ class ShaderProgram {
gl.uniform4fv(this.unifColor, color);
}
}


setTime(time: number) {
this.use();
if (this.unifTime !== -1) {
gl.uniform1f(this.unifTime, time);
}
}

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

Expand All @@ -103,7 +112,7 @@ class ShaderProgram {

if (this.attrPos != -1) gl.disableVertexAttribArray(this.attrPos);
if (this.attrNor != -1) gl.disableVertexAttribArray(this.attrNor);
}
}
};

export default ShaderProgram;
69 changes: 69 additions & 0 deletions src/shaders/custom-vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#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

uniform float u_Time;

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.

// in float time;

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.
out vec4 fs_Pos;

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_Pos = modelposition;

float t = abs(cos(u_Time / 1000.f / 6.28 * dot(vs_Pos, vs_Pos)));
//modelposition.xyz = sin(u_Time).xyz;
//modelposition += t;
float time = u_Time / 50.;
float oldX = modelposition.x;
modelposition.x *= 0.18 * cos(sin(time * 119.f / 2002. + modelposition.x)) + cos(modelposition.y * time / 30.);
modelposition.y *= cos(sin(time * 416.f / 2002. + modelposition.y)) + cos(modelposition.z * time / 20.);
modelposition.z *= cos(sin(time * 816.f / 2002. + modelposition.z)) + cos(oldX * time);
fs_Pos = modelposition;

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
}
Loading