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

Anthony Ge hw0 #9

Open
wants to merge 11 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
1 change: 1 addition & 0 deletions .github/workflows/build-and-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ on:
push:
branches:
- master
workflow_dispatch:
jobs:
build-and-deploy:
runs-on: ubuntu-latest
Expand Down
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@
</p>
<p align="center">(source: Ken Perlin)</p>

# Anthony Ge Submission
For this assignment, I made a wobbly egg using 3D value noise, GL alphablending, and simple sin-based vertex deformation.
Demo live here: [https://geant04.github.io/hw00-intro-base/](https://geant04.github.io/hw00-intro-base/)

![Egg.](/egg.gif)
![Cube.](/image.png)

Vertex Deformation:
- Vertically displaced vertices based on the x and y position, using sin and cosine

Fragment Deformation:
- Used local vertex position to sample a deterministic 3D value noise function, discarding pixels under 0.30 and smoothstepping the value otherwise
- Mapped noise value to a cosine gradient and mixed with diffuse color, along with a combination of the rgb from vertex color to produce final fragment rgb

References
- 3D value noise: [https://www.shadertoy.com/view/4dS3Wd](https://www.shadertoy.com/view/4dS3Wd)
- Cosine gradient color mapping: [http://dev.thi.ng/gradients/](http://dev.thi.ng/gradients/)


## Objective
- Check that the tools and build configuration we will be using for the class works.
- Start learning Typescript and WebGL2
Expand Down
Binary file added egg.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 image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4,638 changes: 2,872 additions & 1,766 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{
"scripts": {
"start": "webpack-dev-server --no-hot --live-reload",
"build": "webpack"
"build": "webpack",
"predeploy": "npm run build",
"deploy": "gh-pages -d dist"
},
"devDependencies": {
"@types/dat.gui": "^0.7.7",
"@types/dat.gui": "^0.7.13",
"@types/stats.js": "^0.17.3",
"@types/webgl2": "0.0.6",
"gh-pages": "^6.1.1",
"ts-loader": "^9.2.5",
"typescript": "^4.4.2",
"webpack": "^5.52.0",
Expand Down
98 changes: 98 additions & 0 deletions src/geometry/Cube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import Drawable from "../rendering/gl/Drawable";
import {gl} from '../globals';
import {vec3, vec4} from 'gl-matrix';

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, // front
0, 2, 3,
4, 5, 6, // back
4, 6, 7,
8, 9, 10, // top
8, 10, 11,
12, 13, 14, // bottom
12, 14, 15,
16, 17, 18, // right
16, 18, 19,
20, 21, 22, // left
20, 22, 23
]);

this.normals = new Float32Array([0, 0, 1, 0, // front
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, 1, 0,
0, 0, -1, 0, // back
0, 0, -1, 0,
0, 0, -1, 0,
0, 0, -1, 0,
0, 1, 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,
1, 0, 0, 0, // right
1, 0, 0, 0,
1, 0, 0, 0,
1, 0, 0, 0,
-1, 0, 0, 0, // left
-1, 0, 0, 0,
-1, 0, 0, 0,
-1, 0, 0, 0
]);
this.positions = new Float32Array([-1, -1, 1, 1, // front
1, -1, 1, 1,
1, 1, 1, 1,
-1, 1, 1, 1,
-1, -1, -1, 1, // back
1, -1, -1, 1,
1, 1, -1, 1,
-1, 1, -1, 1,
-1, 1, 1, 1, // top
1, 1, 1, 1,
1, 1, -1, 1,
-1, 1, -1, 1,
-1, -1, 1, 1, // bottom
1, -1, 1, 1,
1, -1, -1, 1,
-1, -1, -1, 1,
1, -1, 1, 1, // right
1, 1, 1, 1,
1, 1, -1, 1,
1, -1, -1, 1,
-1, -1, 1, 1, // left
-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);
}
}

export default Cube;
62 changes: 54 additions & 8 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
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';
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,
color: [255, 0, 0],
persistence: 0.5,
amplitude: 0.5,
frequency: 2.0,
lacunarity: 2.0,
octaves: 8,
cube: false,
'Load Scene': loadScene, // A function pointer, essentially
};

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

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 @@ -38,6 +51,13 @@ function main() {
// Add controls to the gui
const gui = new DAT.GUI();
gui.add(controls, 'tesselations', 0, 8).step(1);
gui.addColor(controls, 'color');
gui.add(controls, 'persistence', 0.0, 1.0);
gui.add(controls, 'amplitude', 0.0, 1.0);
gui.add(controls, 'frequency', 0.0, 10.0);
gui.add(controls, 'lacunarity', 0.0, 10.0);
gui.add(controls, 'octaves', 0, 10).step(1);
gui.add(controls, 'cube', false);
gui.add(controls, 'Load Scene');

// get canvas and webgl context
Expand All @@ -58,14 +78,23 @@ function main() {
const renderer = new OpenGLRenderer(canvas);
renderer.setClearColor(0.2, 0.2, 0.2, 1);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

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.FRAGMENT_SHADER, require('./shaders/fbm-frag.glsl')),
]);

// This function will be called every frame
function tick() {
function tick(timeStamp: number) {
if (start == undefined)
{
start = timeStamp;
}

const elapsed = timeStamp - start;

camera.update();
stats.begin();
gl.viewport(0, 0, window.innerWidth, window.innerHeight);
Expand All @@ -76,10 +105,27 @@ function main() {
icosphere = new Icosphere(vec3.fromValues(0, 0, 0), 1, prevTesselations);
icosphere.create();
}
renderer.render(camera, lambert, [
icosphere,
// square,
]);

let geomColor = vec4.fromValues(
controls.color[0] / 255.0,
controls.color[1] / 255.0,
controls.color[2] / 255.0,
1.0,
);

lambert.setFloat("u_Persistence", controls.persistence);
lambert.setFloat("u_Amplitude", controls.amplitude);
lambert.setFloat("u_Frequency", controls.frequency);
lambert.setFloat("u_Lacunarity", controls.lacunarity);
lambert.setFloat("u_Time", timeStamp / 1000.0);
lambert.setInt("u_Octaves", controls.octaves);

let objects = []

if (controls.cube) objects.push(cube)
if (!controls.cube) objects.push(icosphere)

renderer.render(camera, lambert, geomColor, objects);
stats.end();

// Tell the browser to call `tick` again whenever it renders a new frame
Expand All @@ -97,7 +143,7 @@ function main() {
camera.updateProjectionMatrix();

// Start the render loop
tick();
tick(0.0);
}

main();
4 changes: 2 additions & 2 deletions src/rendering/gl/OpenGLRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ 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, color: vec4, drawables: Array<Drawable>) {
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);
Expand Down
19 changes: 19 additions & 0 deletions src/rendering/gl/ShaderProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,25 @@ class ShaderProgram {
}
}

setFloat(name: string, value: number) {
var uniformLocation = gl.getUniformLocation(this.prog, name);

this.use(); // use shaderProgram
if (uniformLocation !== -1) {
gl.uniform1f(uniformLocation, value);
}
}

setInt(name: string, value: number) {
var uniformLocation = gl.getUniformLocation(this.prog, name);

this.use();
if (uniformLocation !== -1)
{
gl.uniform1i(uniformLocation, value);
}
}

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

Expand Down
Loading