From 3e4e8e22cf9d8ce726f6e5121b075e4823f91b3d Mon Sep 17 00:00:00 2001 From: Serena Gandhi <60444726+gserena01@users.noreply.github.com> Date: Wed, 20 Oct 2021 16:02:23 -0400 Subject: [PATCH 01/34] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c1cda32..b9e420a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +![image](https://user-images.githubusercontent.com/60444726/138163560-f8537878-23f3-4a77-aae0-31b7e6201581.png) + + # Homework 4: L-systems For this assignment, you will design a set of formal grammar rules to create From 27343c1228a27734f18cc41078a892e8691921a6 Mon Sep 17 00:00:00 2001 From: Serena Gandhi <60444726+gserena01@users.noreply.github.com> Date: Thu, 21 Oct 2021 08:08:44 -0400 Subject: [PATCH 02/34] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b9e420a..32109b5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ ![image](https://user-images.githubusercontent.com/60444726/138163560-f8537878-23f3-4a77-aae0-31b7e6201581.png) +![Screenshot 2021-10-20 200324](https://user-images.githubusercontent.com/60444726/138274074-d694a82b-69f7-44e3-a6fc-c970d17ae49c.png) # Homework 4: L-systems From 6143ace18d1e4c64f3397fac458b3aca9477780a Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Thu, 28 Oct 2021 22:44:16 -0400 Subject: [PATCH 03/34] faulty setup --- package-lock.json | 41 +++- resources/cylinder.mtl | 10 + resources/cylinder.obj | 140 +++++++++++ src/geometry/Mesh.ts | 38 ++- src/geometry/ScreenQuad.ts | 4 +- src/globals.ts | 21 +- src/main.ts | 9 +- src/rendering/gl/Drawable.ts | 35 ++- src/rendering/gl/ShaderProgram.ts | 1 + src/shaders/flat-frag.glsl | 337 +++++++++++++++++++++++++- src/shaders/l-system/DrawingRule.ts | 23 ++ src/shaders/l-system/ExpansionRule.ts | 22 ++ src/shaders/l-system/L-System.ts | 191 +++++++++++++++ src/shaders/l-system/Turtle.ts | 62 +++++ 14 files changed, 913 insertions(+), 21 deletions(-) create mode 100644 resources/cylinder.mtl create mode 100644 resources/cylinder.obj create mode 100644 src/shaders/l-system/DrawingRule.ts create mode 100644 src/shaders/l-system/ExpansionRule.ts create mode 100644 src/shaders/l-system/L-System.ts create mode 100644 src/shaders/l-system/Turtle.ts diff --git a/package-lock.json b/package-lock.json index 095aa6c..f370cda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1743,7 +1743,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -1764,12 +1765,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1784,17 +1787,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1911,7 +1917,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1923,6 +1930,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -1937,6 +1945,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -1944,12 +1953,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -1968,6 +1979,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2048,7 +2060,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2060,6 +2073,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2145,7 +2159,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -2181,6 +2196,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -2200,6 +2216,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -2243,12 +2260,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/resources/cylinder.mtl b/resources/cylinder.mtl new file mode 100644 index 0000000..f231bdf --- /dev/null +++ b/resources/cylinder.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/resources/cylinder.obj b/resources/cylinder.obj new file mode 100644 index 0000000..f8857dc --- /dev/null +++ b/resources/cylinder.obj @@ -0,0 +1,140 @@ +# Blender v2.91.2 OBJ File: '' +# www.blender.org +mtllib cylinder.mtl +o Cylinder +v 0.000000 -1.000000 -0.250000 +v 0.000000 1.000000 -0.250000 +v 0.095671 -1.000000 -0.230970 +v 0.095671 1.000000 -0.230970 +v 0.176777 -1.000000 -0.176777 +v 0.176777 1.000000 -0.176777 +v 0.230970 -1.000000 -0.095671 +v 0.230970 1.000000 -0.095671 +v 0.250000 -1.000000 0.000000 +v 0.250000 1.000000 0.000000 +v 0.230970 -1.000000 0.095671 +v 0.230970 1.000000 0.095671 +v 0.176777 -1.000000 0.176777 +v 0.176777 1.000000 0.176777 +v 0.095671 -1.000000 0.230970 +v 0.095671 1.000000 0.230970 +v 0.000000 -1.000000 0.250000 +v 0.000000 1.000000 0.250000 +v -0.095671 -1.000000 0.230970 +v -0.095671 1.000000 0.230970 +v -0.176777 -1.000000 0.176777 +v -0.176777 1.000000 0.176777 +v -0.230970 -1.000000 0.095671 +v -0.230970 1.000000 0.095671 +v -0.250000 -1.000000 -0.000000 +v -0.250000 1.000000 -0.000000 +v -0.230970 -1.000000 -0.095671 +v -0.230970 1.000000 -0.095671 +v -0.176777 -1.000000 -0.176777 +v -0.176777 1.000000 -0.176777 +v -0.095671 -1.000000 -0.230970 +v -0.095671 1.000000 -0.230970 +vt 1.000000 0.500000 +vt 1.000000 1.000000 +vt 0.937500 1.000000 +vt 0.937500 0.500000 +vt 0.875000 1.000000 +vt 0.875000 0.500000 +vt 0.812500 1.000000 +vt 0.812500 0.500000 +vt 0.750000 1.000000 +vt 0.750000 0.500000 +vt 0.687500 1.000000 +vt 0.687500 0.500000 +vt 0.625000 1.000000 +vt 0.625000 0.500000 +vt 0.562500 1.000000 +vt 0.562500 0.500000 +vt 0.500000 1.000000 +vt 0.500000 0.500000 +vt 0.437500 1.000000 +vt 0.437500 0.500000 +vt 0.375000 1.000000 +vt 0.375000 0.500000 +vt 0.312500 1.000000 +vt 0.312500 0.500000 +vt 0.250000 1.000000 +vt 0.250000 0.500000 +vt 0.187500 1.000000 +vt 0.187500 0.500000 +vt 0.125000 1.000000 +vt 0.125000 0.500000 +vt 0.341844 0.471731 +vt 0.250000 0.490000 +vt 0.158156 0.471731 +vt 0.080294 0.419706 +vt 0.028269 0.341844 +vt 0.010000 0.250000 +vt 0.028269 0.158156 +vt 0.080294 0.080294 +vt 0.158156 0.028269 +vt 0.250000 0.010000 +vt 0.341844 0.028269 +vt 0.419706 0.080294 +vt 0.471731 0.158156 +vt 0.490000 0.250000 +vt 0.471731 0.341844 +vt 0.419706 0.419706 +vt 0.062500 1.000000 +vt 0.062500 0.500000 +vt 0.000000 1.000000 +vt 0.000000 0.500000 +vt 0.750000 0.490000 +vt 0.841844 0.471731 +vt 0.919706 0.419706 +vt 0.971731 0.341844 +vt 0.990000 0.250000 +vt 0.971731 0.158156 +vt 0.919706 0.080294 +vt 0.841844 0.028269 +vt 0.750000 0.010000 +vt 0.658156 0.028269 +vt 0.580294 0.080294 +vt 0.528269 0.158156 +vt 0.510000 0.250000 +vt 0.528269 0.341844 +vt 0.580294 0.419706 +vt 0.658156 0.471731 +vn 0.1951 0.0000 -0.9808 +vn 0.5556 0.0000 -0.8315 +vn 0.8315 0.0000 -0.5556 +vn 0.9808 0.0000 -0.1951 +vn 0.9808 0.0000 0.1951 +vn 0.8315 0.0000 0.5556 +vn 0.5556 0.0000 0.8315 +vn 0.1951 0.0000 0.9808 +vn -0.1951 0.0000 0.9808 +vn -0.5556 0.0000 0.8315 +vn -0.8315 0.0000 0.5556 +vn -0.9808 0.0000 0.1951 +vn -0.9808 0.0000 -0.1951 +vn -0.8315 0.0000 -0.5556 +vn 0.0000 1.0000 0.0000 +vn -0.5556 0.0000 -0.8315 +vn -0.1951 0.0000 -0.9808 +vn 0.0000 -1.0000 -0.0000 +usemtl None +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 6/5/2 5/6/2 +f 5/6/3 6/5/3 8/7/3 7/8/3 +f 7/8/4 8/7/4 10/9/4 9/10/4 +f 9/10/5 10/9/5 12/11/5 11/12/5 +f 11/12/6 12/11/6 14/13/6 13/14/6 +f 13/14/7 14/13/7 16/15/7 15/16/7 +f 15/16/8 16/15/8 18/17/8 17/18/8 +f 17/18/9 18/17/9 20/19/9 19/20/9 +f 19/20/10 20/19/10 22/21/10 21/22/10 +f 21/22/11 22/21/11 24/23/11 23/24/11 +f 23/24/12 24/23/12 26/25/12 25/26/12 +f 25/26/13 26/25/13 28/27/13 27/28/13 +f 27/28/14 28/27/14 30/29/14 29/30/14 +f 4/31/15 2/32/15 32/33/15 30/34/15 28/35/15 26/36/15 24/37/15 22/38/15 20/39/15 18/40/15 16/41/15 14/42/15 12/43/15 10/44/15 8/45/15 6/46/15 +f 29/30/16 30/29/16 32/47/16 31/48/16 +f 31/48/17 32/47/17 2/49/17 1/50/17 +f 1/51/18 3/52/18 5/53/18 7/54/18 9/55/18 11/56/18 13/57/18 15/58/18 17/59/18 19/60/18 21/61/18 23/62/18 25/63/18 27/64/18 29/65/18 31/66/18 diff --git a/src/geometry/Mesh.ts b/src/geometry/Mesh.ts index c5591ce..ae6b099 100644 --- a/src/geometry/Mesh.ts +++ b/src/geometry/Mesh.ts @@ -10,6 +10,13 @@ class Mesh extends Drawable { colors: Float32Array; uvs: Float32Array; center: vec4; + offsets: Float32Array; // Data for bufTranslate + + tCol1: Float32Array; // Data for bufTransform1 + tCol2: Float32Array; // Data for bufTransform2 + tCol3: Float32Array; // Data for bufTransform3 + tCol4: Float32Array; // Data for bufTransform4 + objString: string; @@ -28,7 +35,6 @@ class Mesh extends Drawable { var loadedMesh = new Loader.Mesh(this.objString); - //posTemp = loadedMesh.vertices; for (var i = 0; i < loadedMesh.vertices.length; i++) { posTemp.push(loadedMesh.vertices[i]); if (i % 3 == 2) posTemp.push(1.0); @@ -42,7 +48,7 @@ class Mesh extends Drawable { uvsTemp = loadedMesh.textures; idxTemp = loadedMesh.indices; - // white vert color for now + // color white this.colors = new Float32Array(posTemp.length); for (var i = 0; i < posTemp.length; ++i){ this.colors[i] = 1.0; @@ -59,6 +65,11 @@ class Mesh extends Drawable { this.generateUV(); this.generateCol(); + this.generateTransform1(); + this.generateTransform2(); + this.generateTransform3(); + this.generateTransform4(); + this.count = this.indices.length; gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufIdx); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); @@ -76,8 +87,29 @@ class Mesh extends Drawable { gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW); console.log(`Created Mesh from OBJ`); - this.objString = ""; // hacky clear + this.objString = ""; } + + setInstanceVBOs(col1s: Float32Array, col2s: Float32Array, col3s: Float32Array, col4s: Float32Array, + colors: Float32Array) { +this.colors = colors; +this.tCol1 = col1s; +this.tCol2 = col2s; +this.tCol3 = col3s; +this.tCol4 = col4s; +console.log("DEBUG COLS: " + this.tCol1); + +gl.bindBuffer(gl.ARRAY_BUFFER, this.bufCol); +gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); +gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform1); +gl.bufferData(gl.ARRAY_BUFFER, this.tCol1, gl.STATIC_DRAW); +gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform2); +gl.bufferData(gl.ARRAY_BUFFER, this.tCol2, gl.STATIC_DRAW); +gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform3); +gl.bufferData(gl.ARRAY_BUFFER, this.tCol3, gl.STATIC_DRAW); +gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform4); +gl.bufferData(gl.ARRAY_BUFFER, this.tCol4, gl.STATIC_DRAW); +} }; export default Mesh; diff --git a/src/geometry/ScreenQuad.ts b/src/geometry/ScreenQuad.ts index fb678da..f873d29 100644 --- a/src/geometry/ScreenQuad.ts +++ b/src/geometry/ScreenQuad.ts @@ -15,8 +15,8 @@ class ScreenQuad extends Drawable { this.indices = new Uint32Array([0, 1, 2, 0, 2, 3]); this.positions = new Float32Array([-1, -1, 0.999, 1, - 1, -1, 0.999, 1, - 1, 1, 0.999, 1, + 1, -1, 0.999, 1, + 1, 1, 0.999, 1, -1, 1, 0.999, 1]); this.generateIdx(); diff --git a/src/globals.ts b/src/globals.ts index cac5bf2..31f6787 100644 --- a/src/globals.ts +++ b/src/globals.ts @@ -1,5 +1,24 @@ - export var gl: WebGL2RenderingContext; export function setGL(_gl: WebGL2RenderingContext) { gl = _gl; } + +export function readTextFile(file: string): string +{ + var text = ""; + var rawFile = new XMLHttpRequest(); + rawFile.open("GET", file, false); + rawFile.onreadystatechange = function () + { + if(rawFile.readyState === 4) + { + if(rawFile.status === 200 || rawFile.status == 0) + { + var allText = rawFile.responseText; + text = allText; + } + } + } + rawFile.send(null); + return text; +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 932c78f..e4e4ca4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,6 +7,7 @@ import OpenGLRenderer from './rendering/gl/OpenGLRenderer'; import Camera from './Camera'; import {setGL} from './globals'; import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram'; +import LSystem from './shaders/l-system/L-System'; // Define an object with application parameters and button callbacks // This will be referred to by dat.GUI's functions that add GUI elements. @@ -16,6 +17,7 @@ const controls = { let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; +let coral : LSystem = new LSystem(); function loadScene() { square = new Square(); @@ -23,6 +25,9 @@ function loadScene() { screenQuad = new ScreenQuad(); screenQuad.create(); + coral.createMeshes(); + coral.makeTree(); + // Set up instanced rendering data arrays here. // This example creates a set of positional // offsets and gradiated colors for a 100x100 grid @@ -74,8 +79,10 @@ function main() { // Initial call to load scene loadScene(); + //const camera = new Camera(vec3.fromValues(10, 10, 10), vec3.fromValues(0, 0, 0)); const camera = new Camera(vec3.fromValues(50, 50, 10), vec3.fromValues(50, 50, 0)); + const renderer = new OpenGLRenderer(canvas); renderer.setClearColor(0.2, 0.2, 0.2, 1); gl.enable(gl.BLEND); @@ -101,7 +108,7 @@ function main() { renderer.clear(); renderer.render(camera, flat, [screenQuad]); renderer.render(camera, instancedShader, [ - square, + coral.branch ]); stats.end(); diff --git a/src/rendering/gl/Drawable.ts b/src/rendering/gl/Drawable.ts index d5420f6..b364858 100644 --- a/src/rendering/gl/Drawable.ts +++ b/src/rendering/gl/Drawable.ts @@ -9,6 +9,10 @@ abstract class Drawable { bufTranslate: WebGLBuffer; bufCol: WebGLBuffer; bufUV: WebGLBuffer; + bufTransform1: WebGLBuffer; + bufTransform2: WebGLBuffer; + bufTransform3: WebGLBuffer; + bufTransform4: WebGLBuffer; idxGenerated: boolean = false; posGenerated: boolean = false; @@ -16,18 +20,27 @@ abstract class Drawable { colGenerated: boolean = false; translateGenerated: boolean = false; uvGenerated: boolean = false; + transform1Generated: boolean = false; + transform2Generated: boolean = false; + transform3Generated: boolean = false; + transform4Generated: boolean = false; + numInstances: number = 0; // How many instances of this Drawable the shader program should draw abstract create() : void; - destory() { + destroy() { gl.deleteBuffer(this.bufIdx); gl.deleteBuffer(this.bufPos); gl.deleteBuffer(this.bufNor); gl.deleteBuffer(this.bufCol); gl.deleteBuffer(this.bufTranslate); gl.deleteBuffer(this.bufUV); + gl.deleteBuffer(this.bufTransform1); + gl.deleteBuffer(this.bufTransform2); + gl.deleteBuffer(this.bufTransform3); + gl.deleteBuffer(this.bufTransform4); } generateIdx() { @@ -60,6 +73,24 @@ abstract class Drawable { this.bufUV = gl.createBuffer(); } + generateTransform1() { + this.transform1Generated = true; + this.bufTransform1 = gl.createBuffer(); + } + + generateTransform2() { + this.transform2Generated = true; + this.bufTransform2 = gl.createBuffer(); + } + generateTransform3() { + this.transform3Generated = true; + this.bufTransform3 = gl.createBuffer(); + } + generateTransform4() { + this.transform4Generated = true; + this.bufTransform4 = gl.createBuffer(); + } + bindIdx(): boolean { if (this.idxGenerated) { gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufIdx); @@ -102,6 +133,8 @@ abstract class Drawable { return this.uvGenerated; } + + elemCount(): number { return this.count; } diff --git a/src/rendering/gl/ShaderProgram.ts b/src/rendering/gl/ShaderProgram.ts index fa9f450..2c1c5e3 100644 --- a/src/rendering/gl/ShaderProgram.ts +++ b/src/rendering/gl/ShaderProgram.ts @@ -50,6 +50,7 @@ class ShaderProgram { this.attrPos = gl.getAttribLocation(this.prog, "vs_Pos"); this.attrCol = gl.getAttribLocation(this.prog, "vs_Col"); + this.attrNor = gl.getAttribLocation(this.prog, "vs_Nor"); this.attrTranslate = gl.getAttribLocation(this.prog, "vs_Translate"); this.attrUV = gl.getAttribLocation(this.prog, "vs_UV"); this.unifModel = gl.getUniformLocation(this.prog, "u_Model"); diff --git a/src/shaders/flat-frag.glsl b/src/shaders/flat-frag.glsl index 99362d2..81827ad 100644 --- a/src/shaders/flat-frag.glsl +++ b/src/shaders/flat-frag.glsl @@ -8,6 +8,339 @@ uniform float u_Time; in vec2 fs_Pos; out vec4 out_Col; -void main() { - out_Col = vec4(0.5 * (fs_Pos + vec2(1.0)), 0.0, 1.0); +const int MAX_RAY_STEPS = 128; +const float FOV = 45.0; +const float EPSILON = 1e-6; + +const vec3 WORLD_UP = vec3(0.0, 1.0, 0.0); +const vec3 WORLD_RIGHT = vec3(-1.0, 0.0, 0.0); +const vec3 WORLD_FORWARD = vec3(0.0, 0.0, 1.0); +const float HALF_PI = 1.570796327; +const float MAX_RAY_LENGTH = 12.0; + +// COLORS +const vec3 MUG_COLOR = vec3(140.0, 150.0, 170.0) / 255.0 * 0.8; +const vec3 SCISSORS_COLOR = vec3(196.0, 202.0, 206.0) / 255.0; +const vec3 FLOOR_COLOR = vec3(91.0, 96.0, 101.0) / 255.0 * 0.5; +const vec3 GOLD_COLOR = vec3(215.0, 190.0, 105.0) / 255.0; +const vec3 backgroundColor = vec3(0.2, 0.4, 0.9); + +// LIGHTS +const vec3 LIGHT_POS = vec3(-1.0, 3.0, 2.0); +const vec3 LIGHT_COLOR = vec3(1.0, .88, .7); + + +// structs +struct Ray +{ + vec3 origin; + vec3 direction; +}; + +struct Intersection +{ + vec3 position; + vec3 normal; + float distance_t; + int material_id; +}; + +// TOOLBOX FUNCTIONS ------------------------------------------------------- +float GetBias(float t, float bias) +{ + return (t / ((((1.0/bias) - 2.0)*(1.0 - t))+1.0)); +} + + +float GetGain(float t, float gain) +{ + if(t < 0.5) + return GetBias(t * 2.0,gain)/2.0; + else + return GetBias(t * 2.0 - 1.0,1.0 - gain)/2.0 + 0.5; +} + +// SDF functions ---------------------------------------------------------- + +float sdfPlane( vec3 p, vec3 n, float h ) +{ + // n must be normalized + return dot(p,n) + h; + // return queryPos.y - h; +} + +float sdfSphere(vec3 query_position, vec3 position, float radius) +{ + return length(query_position - position) - radius; +} + +float sdBox( vec3 p, vec3 b ) +{ + vec3 q = abs(p) - b; + return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0); +} + +float sdRoundedCylinder( vec3 p, float ra, float rb, float h ) +{ + vec2 d = vec2( length(p.xz)-2.0*ra+rb, abs(p.y) - h ); + return min(max(d.x,d.y),0.0) + length(max(d,0.0)) - rb; +} + +float sdCappedCone( vec3 p, float h, float r1, float r2 ) +{ + vec2 q = vec2( length(p.xz), p.y ); + vec2 k1 = vec2(r2,h); + vec2 k2 = vec2(r2-r1,2.0*h); + vec2 ca = vec2(q.x-min(q.x,(q.y<0.0)?r1:r2), abs(q.y)-h); + vec2 cb = q - k1 + k2*clamp( dot(k1-q,k2)/dot(k2, k2), 0.0, 1.0 ); + float s = (cb.x<0.0 && ca.y<0.0) ? -1.0 : 1.0; + return s*sqrt( min(dot(ca, ca),dot(cb, cb)) ); +} + +float sdHexPrism( vec3 p, vec2 h ) +{ + const vec3 k = vec3(-0.8660254, 0.5, 0.57735); + p = abs(p); + p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy; + vec2 d = vec2( + length(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x), + p.z-h.y ); + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); +} + + +// SDF Modifiers------------------------------------------------------------- +float opRound(float sdf, float rad ) +{ + return sdf - rad; +} + +float smin( float a, float b, float k ) +{ + float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 ); + return mix( b, a, h ) - k*h*(1.0-h); +} + +float opSmoothSubtraction( float d1, float d2, float k ) { + float h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 ); + return mix( d2, -d1, h ) + k*h*(1.0-h); +} + +vec3 opElongate(in vec3 p, in vec3 h ) +{ + vec3 q = p - clamp( p, -h, h ); + return q; +} + +float sphereRep( vec3 p, vec3 c ) +{ + vec3 q = mod(p+0.5*c,c)-0.5*c; + return sdfSphere( q, vec3(0.0), 1.0 ); +} + +// from https://github.com/dmnsgn/glsl-rotate/blob/master/rotation-3d-x.glsl +mat3 rotation3dX(float angle) { + float s = sin(angle); + float c = cos(angle); + + return mat3( + 1.0, 0.0, 0.0, + 0.0, c, s, + 0.0, -s, c + ); +} + +// from https://github.com/dmnsgn/glsl-rotate/blob/master/rotation-3d-y.glsl +mat3 rotation3dY(float angle) { + float s = sin(angle); + float c = cos(angle); + + return mat3( + c, 0.0, -s, + 0.0, 1.0, 0.0, + s, 0.0, c + ); +} + +// from https://github.com/dmnsgn/glsl-rotate/blob/master/rotation-3d-z.glsl +mat3 rotation3dZ(float angle) { + float s = sin(angle); + float c = cos(angle); + + return mat3( + c, s, 0.0, + -s, c, 0.0, + 0.0, 0.0, 1.0 + ); +} + +// Scene Building------------------------------------------------------------------------- + +// Build for a Bubble +float sceneSDFBubble(vec3 queryPos) { + float t = sdfSphere(queryPos, vec3(0.0), 10.0); + + return t; +} + +vec3 animateHorizontal(vec3 p) { + return p + vec3(8.0, 0.0, 0.0) * (GetBias(sin(u_Time * .025) + 1.0, 0.7) - 0.5); +} + +vec3 animateYRotation(vec3 p) { + return transpose(rotation3dY(GetGain((.5 * sin(u_Time * .025) + 0.5), 0.7) * 6.0)) * p; +} + +float sceneSDF(vec3 queryPos, out int hitObj) +{ + + // Bounding sphere, so we only have to check for geometry within certain bounds + float bounding_box_dist = sdBox(queryPos, vec3(12.0)); + // if(bounding_box_dist <= .00001) { + + // Bubbles + float t = sceneSDFBubble(animateHorizontal((queryPos))); + hitObj = 1; + + float t2 = sceneSDFBubble(queryPos); + if (t2 < t) { + t = t2; + hitObj = 0; + } + + return t; + // } + hitObj = -2; + return bounding_box_dist; +} + +vec3 estimateNormal(vec3 p, out int hitObj) { + vec2 d = vec2(0.0, EPSILON); + float x = sceneSDF(p + d.yxx, hitObj) - sceneSDF(p - d.yxx, hitObj); + float y = sceneSDF(p + d.xyx, hitObj) - sceneSDF(p - d.xyx, hitObj); + float z = sceneSDF(p + d.xxy, hitObj) - sceneSDF(p - d.xxy, hitObj); + return normalize(abs(vec3(x, y, z))); +} + +Ray getRay(vec2 uv) +{ + Ray r; + float aspect_ratio = u_Dimensions.x / u_Dimensions.y; + float len = length(u_Ref - u_Eye); + + vec3 look = normalize(u_Ref - u_Eye); + vec3 camera_RIGHT = normalize(cross(look, u_Up)); + + vec3 screen_vertical = u_Up * len * tan(FOV / 2.0); + vec3 screen_horizontal = camera_RIGHT * len * aspect_ratio * tan(FOV / 2.0); + vec3 screen_point = (u_Ref + uv.x * screen_horizontal + uv.y * screen_vertical); + + r.origin = u_Eye; + r.direction = normalize(screen_point - u_Eye); + + return r; +} + +bool isRayTooLong(vec3 queryPoint, vec3 origin) +{ + return length(queryPoint - origin) > MAX_RAY_LENGTH; +} + +Intersection getRaymarchedIntersection(vec2 uv, out int hitObj) +{ + Intersection intersection; + intersection.distance_t = -1.0; + + Ray r = getRay(uv); + float distancet = 0.0; + + for (int step; step < MAX_RAY_STEPS; step++) { + vec3 qPoint = r.origin + r.direction * distancet; + if(isRayTooLong(qPoint, r.origin)) { + break; + } + float currentDistance = sceneSDF(qPoint, hitObj); + if (currentDistance < EPSILON) { + // something was hit by our ray! + intersection.distance_t = distancet; + intersection.normal = estimateNormal(qPoint, hitObj); + intersection.position = r.origin + distancet * r.direction; + return intersection; + } + distancet += currentDistance; + + } + + return intersection; } + +// SHADING ------------------------------------------------------------------------------------------------------------ + +float shadeLambert(vec3 norm, vec3 lightVec) { + // Calculate the diffuse term for Lambert shading + float diffuseTerm = dot(normalize(norm), normalize(lightVec)); + + // Avoid negative lighting values + diffuseTerm = clamp(diffuseTerm, 0.f, 1.f); + + // add ambient lighting + float ambientTerm = 0.2; + float lightIntensity = diffuseTerm + ambientTerm; + + return lightIntensity; +} + +vec3 computeMaterial(int hitObj, vec3 p, vec3 n) { + float t; + + vec3 albedo; + switch(hitObj) { + case 0: // Mug + albedo = MUG_COLOR; + break; + case 1: // Scissors + albedo = SCISSORS_COLOR; + break; + case 2: // Floor + albedo = FLOOR_COLOR; + break; // Background + case 3: // Mug Lip + albedo = GOLD_COLOR; + break; + case -1: + return backgroundColor; + break; + case -2: + return backgroundColor; + break; + } + + vec3 color = vec3(0.0); + + color = albedo; + + return color; +} + +vec3 getSceneColor(vec2 uv) +{ + int hitObj = -1; + Intersection intersection = getRaymarchedIntersection(uv, hitObj); + if (intersection.distance_t > 0.0) + { + // shade everything with lambert + float lightIntensity = shadeLambert(intersection.normal, LIGHT_POS - intersection.position); + return lightIntensity * computeMaterial(hitObj, intersection.position, intersection.normal); + } + return backgroundColor; +} + +// MAIN -------------------------------------------------------------------------------------------------------------- + +void main() { + // Using Raymarching: + vec3 col = getSceneColor(fs_Pos); + // Output to screen + out_Col = vec4(col,1.0); + +} \ No newline at end of file diff --git a/src/shaders/l-system/DrawingRule.ts b/src/shaders/l-system/DrawingRule.ts new file mode 100644 index 0000000..1a45402 --- /dev/null +++ b/src/shaders/l-system/DrawingRule.ts @@ -0,0 +1,23 @@ +class DrawingRule { + outputs: Array<[any, number]> = []; + + addOutput(oper : any, probability : number) { + this.outputs.push([oper, probability]); + } + + getOutput() : any { + let rand = Math.random(); + let probabilitySum : number = 0.0; + let i : number = 0; + while(i < this.outputs.length) { + probabilitySum += this.outputs[i][1]; + if (rand < probabilitySum) { + return this.outputs[i][0]; + } + i++; + } + return; + } + }; + +export default DrawingRule; \ No newline at end of file diff --git a/src/shaders/l-system/ExpansionRule.ts b/src/shaders/l-system/ExpansionRule.ts new file mode 100644 index 0000000..623e516 --- /dev/null +++ b/src/shaders/l-system/ExpansionRule.ts @@ -0,0 +1,22 @@ +class ExpansionRule { + outputs: Array<[string, number]> = []; + + addOutput(newString : string, probability : number) { + this.outputs.push([newString, probability]); + } + + getOutput() : string { + let rand = Math.random(); + let probabilitySum : number = 0.0; + let i : number = 0; + while(i < this.outputs.length) { + probabilitySum += this.outputs[i][1]; + if (rand < probabilitySum) { + return this.outputs[i][0]; + } + i++; + } + return; + } +}; +export default ExpansionRule; \ No newline at end of file diff --git a/src/shaders/l-system/L-System.ts b/src/shaders/l-system/L-System.ts new file mode 100644 index 0000000..e464876 --- /dev/null +++ b/src/shaders/l-system/L-System.ts @@ -0,0 +1,191 @@ +import DrawingRule from "./DrawingRule"; +import ExpansionRule from "./ExpansionRule"; +import Turtle from "./Turtle"; +import Mesh from "../../geometry/Mesh"; +import {readTextFile} from "../../globals" +import { vec3, mat4, quat } from "gl-matrix"; +import OpenGLRenderer from '../../rendering/gl/OpenGLRenderer'; + +class LSystem { + turtleStack: Array = []; + turtle : Turtle = new Turtle(vec3.fromValues(0.0, 0.0, 0.0), vec3.fromValues(0.0, 1.0, 0.0)); + drawingRules: Map = new Map(); + expansionRules: Map = new Map(); + seed: string; + axioms : Array = []; + iterations : number = 6; + // Set up instanced rendering data arrays. + branchCols1 : Array = []; + branchCols2 : Array = []; + branchCols3 : Array = []; + branchCols4 : Array = []; + branchColorsBO : Array = []; + + branchNum : number = 0; + leafNum : number = 0; + + // import objs: + branch : Mesh = new Mesh(readTextFile('resources/cylinder.obj'), vec3.fromValues(0, 0, 0)); + + drawBranch : () => void; + setSeed : (s: string) => void; + pushTurtle : () => void; + popTurtle : () => void; + populateExpansionRules : () => void; + populateDrawingRules : () => void; + putBranch : (scale : vec3) => void; + createMeshes : () => void; + drawTree : () => void; + makeTree : () => void; + + constructor() { + this.turtleStack = []; + this.turtle = new Turtle(vec3.fromValues(0.0, 0.0, 0.0), vec3.fromValues(0.0, 1.0, 0.0)); + + + // define functions below to maintain context of "this" + + this.setSeed = (s: string) => { + this.seed = s; + } + + this.pushTurtle = () => { + let newTurtle : Turtle = new Turtle(this.turtle.position, this.turtle.orientation); + this.turtleStack.push(newTurtle); + this.turtle.depth += 1; + } + + this.popTurtle = () => { + let newTurtle : Turtle = this.turtleStack.pop(); + this.turtle.orientation = newTurtle.orientation; + this.turtle.position = newTurtle.position; + this.turtle.depth -= 1; + } + + this.populateExpansionRules = () => { + let rule1 : ExpansionRule = new ExpansionRule(); + rule1.addOutput("FF-[--FF++FF]+[++FF]", 1.0); + this.expansionRules.set("F", rule1); + + let rule2: ExpansionRule = new ExpansionRule(); + rule2.addOutput("++[F]", 1.0); + this.expansionRules.set("X", rule2); + } + + this.populateDrawingRules = () => { + let pushRule : DrawingRule = new DrawingRule(); + pushRule.addOutput(this.pushTurtle, 1.0); + this.drawingRules.set('[', pushRule); + + let popRule : DrawingRule = new DrawingRule(); + popRule.addOutput(this.popTurtle, 1.0); + this.drawingRules.set(']', popRule); + + let rotateLeftXRule : DrawingRule = new DrawingRule(); + rotateLeftXRule.addOutput(this.turtle.rotateLeftX, 1.0); + this.drawingRules.set('+', rotateLeftXRule); + + let rotateRightXRule : DrawingRule = new DrawingRule(); + rotateRightXRule.addOutput(this.turtle.rotateRightX, 1.0); + this.drawingRules.set('-', rotateRightXRule); + + let forwardRule : DrawingRule = new DrawingRule(); + forwardRule.addOutput(this.drawBranch, 1.0); + this.drawingRules.set('F', forwardRule); + + + } + + this.putBranch = (scale : vec3) => { + // Calculate transformation + let transform : mat4 = mat4.create(); + let q : quat = quat.create(); + quat.rotationTo(q, vec3.fromValues(0, 1, 0), this.turtle.orientation); + mat4.fromRotationTranslationScale(transform, q, this.turtle.position, scale); + for(let i = 0; i < 4; i++) { + this.branchCols1.push(transform[i]); + this.branchCols2.push(transform[4 + i]); + this.branchCols3.push(transform[8 + i]); + this.branchCols4.push(transform[12 + i]); + } + + this.branchColorsBO.push(13. / 255.); + this.branchColorsBO.push(91. / 255.); + this.branchColorsBO.push(80. / 255.); + this.branchColorsBO.push(1.0); + this.branchNum++; + } + + + + this.createMeshes = () => { + this.branch.create(); + } + + this.drawTree = () => { + // reset everything + this.turtle.reset(); + this.branchNum = 0; + this.branchCols1 = []; + this.branchCols2 = []; + this.branchCols3 = []; + this.branchCols4 = []; + this.branchColorsBO = []; + + // Draw based on grammar + for(let i = 0; i < this.axioms[this.iterations].length; i++) { + let func = this.drawingRules.get(this.axioms[this.iterations].charAt(i)).getOutput(); + if(func) { + func(); + } + } + + + let bCol1: Float32Array = new Float32Array(this.branchCols1); + let bCol2: Float32Array = new Float32Array(this.branchCols2); + let bCol3: Float32Array = new Float32Array(this.branchCols3); + let bCol4: Float32Array = new Float32Array(this.branchCols4); + let bcolors: Float32Array = new Float32Array(this.branchColorsBO); + this.branch.create(); + this.branch.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); + this.branch.setNumInstances(this.branchNum); + } + + this.makeTree = () => { + this.setSeed("FX"); + this.axioms = [this.seed]; + + this.populateExpansionRules(); + this.populateDrawingRules(); + + let currExpansion = this.seed; + // expanding the grammar + for (let i = 0; i < 6; i++) { + let expandedString : string = ""; + for (let j = 0; j < currExpansion.length; j++) { + let currRule = this.expansionRules.get(currExpansion.charAt(j)); + if (currRule) { + expandedString += currRule.getOutput(); + } else { + expandedString += currExpansion.charAt(j); + } + } + currExpansion = expandedString; + this.axioms.push(expandedString); + } + this.drawTree(); + + } + + this.drawBranch = () => { + this.turtle.moveForward(); + this.putBranch(vec3.fromValues(0.25 - this.turtle.depth * 0.05, 0.25, + 0.25 - this.turtle.depth * 0.05)); + } + + } + + +}; + +export default LSystem; \ No newline at end of file diff --git a/src/shaders/l-system/Turtle.ts b/src/shaders/l-system/Turtle.ts new file mode 100644 index 0000000..c77f710 --- /dev/null +++ b/src/shaders/l-system/Turtle.ts @@ -0,0 +1,62 @@ +import {vec3} from 'gl-matrix'; + +// vec3 operations from: https://glmatrix.net/docs/module-vec3.html + +class Turtle { + position: vec3 = vec3.fromValues(0.0, 0.0, 0.0); + orientation: vec3 = vec3.fromValues(0.0, 1.0, 0.0); + depth: number = 0; + + moveForward : () => void; + rotateRightX : () => void; + rotateLeftX : () => void; + + + constructor(pos: vec3, orient: vec3) { + this.position = pos; + this.orientation = orient; + this.depth = 0; + + this.moveForward = () => { + vec3.add(this.position, this.position, vec3.scale(vec3.create(), this.orientation, 10.0)); + } + this.rotateRightX = () => { + vec3.rotateX(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), -0.35); + } + this.rotateLeftX = () => { + vec3.rotateX(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), 0.35); + } + + } + // rotate at a random angle + + reset() { + this.position = vec3.fromValues(0.0, 0.0, 0.0); + this.orientation = vec3.fromValues(0.0, 1.0, 0.0); + this.depth = 0; + } + + + + + rotateLeftY() { + vec3.rotateY(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), 0.35); + } + + rotateLeftZ() { + vec3.rotateZ(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), 0.35); + } + + + + rotateRightY() { + vec3.rotateY(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), -0.35); + } + + rotateRightZ() { + vec3.rotateZ(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), -0.35); + } + +}; + +export default Turtle; \ No newline at end of file From 1ddf5301a0e4547c8eefa485005fbf22de18eabd Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sat, 30 Oct 2021 08:19:20 -0400 Subject: [PATCH 04/34] helping with shading --- src/rendering/gl/Drawable.ts | 28 +++++++++++++++++++++++ src/rendering/gl/ShaderProgram.ts | 38 +++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/src/rendering/gl/Drawable.ts b/src/rendering/gl/Drawable.ts index b364858..6f2a00a 100644 --- a/src/rendering/gl/Drawable.ts +++ b/src/rendering/gl/Drawable.ts @@ -133,6 +133,34 @@ abstract class Drawable { return this.uvGenerated; } + bindTrans1(): boolean { + if (this.transform1Generated) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform1); + } + return this.transform1Generated; + } + + bindTrans2(): boolean { + if (this.transform2Generated) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform2); + } + return this.transform2Generated; + } + + bindTrans3(): boolean { + if (this.transform3Generated) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform3); + } + return this.transform3Generated; + } + + bindTrans4(): boolean { + if (this.transform4Generated) { + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform4); + } + return this.transform4Generated; + } + elemCount(): number { diff --git a/src/rendering/gl/ShaderProgram.ts b/src/rendering/gl/ShaderProgram.ts index 2c1c5e3..54421a1 100644 --- a/src/rendering/gl/ShaderProgram.ts +++ b/src/rendering/gl/ShaderProgram.ts @@ -26,6 +26,11 @@ class ShaderProgram { attrCol: number; // This time, it's an instanced rendering attribute, so each particle can have a unique color. Not per-vertex, but per-instance. attrTranslate: number; // Used in the vertex shader during instanced rendering to offset the vertex positions to the particle's drawn position. attrUV: number; + attrTransform1: number; // Represents the columns of the transform matrix + attrTransform2: number; + attrTransform3: number; + attrTransform4: number; + unifModel: WebGLUniformLocation; unifModelInvTr: WebGLUniformLocation; @@ -53,6 +58,11 @@ class ShaderProgram { this.attrNor = gl.getAttribLocation(this.prog, "vs_Nor"); this.attrTranslate = gl.getAttribLocation(this.prog, "vs_Translate"); this.attrUV = gl.getAttribLocation(this.prog, "vs_UV"); + this.attrTransform1 = gl.getAttribLocation(this.prog, "vs_Transform1"); + this.attrTransform2 = gl.getAttribLocation(this.prog, "vs_Transform2"); + this.attrTransform3 = gl.getAttribLocation(this.prog, "vs_Transform3"); + this.attrTransform4 = gl.getAttribLocation(this.prog, "vs_Transform4"); + this.unifModel = gl.getUniformLocation(this.prog, "u_Model"); this.unifModelInvTr = gl.getUniformLocation(this.prog, "u_ModelInvTr"); this.unifViewProj = gl.getUniformLocation(this.prog, "u_ViewProj"); @@ -160,6 +170,30 @@ class ShaderProgram { // TODO: Set up attribute data for additional instanced rendering data as needed + if (this.attrTransform1 != -1 && d.bindTrans1()) { + gl.enableVertexAttribArray(this.attrTransform1); + gl.vertexAttribPointer(this.attrTransform1, 4, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.attrTransform1, 1); // Advance 1 index in translate VBO for each drawn instance + } + + if (this.attrTransform2 != -1 && d.bindTrans2()) { + gl.enableVertexAttribArray(this.attrTransform2); + gl.vertexAttribPointer(this.attrTransform2, 4, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.attrTransform2, 1); // Advance 1 index in translate VBO for each drawn instance + } + + if (this.attrTransform3 != -1 && d.bindTrans3()) { + gl.enableVertexAttribArray(this.attrTransform3); + gl.vertexAttribPointer(this.attrTransform3, 4, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.attrTransform3, 1); // Advance 1 index in translate VBO for each drawn instance + } + + if (this.attrTransform4 != -1 && d.bindTrans4()) { + gl.enableVertexAttribArray(this.attrTransform4); + gl.vertexAttribPointer(this.attrTransform4, 4, gl.FLOAT, false, 0, 0); + gl.vertexAttribDivisor(this.attrTransform4, 1); // Advance 1 index in translate VBO for each drawn instance + } + d.bindIdx(); // drawElementsInstanced uses the vertexAttribDivisor for each "in" variable to // determine how to link it to each drawn instance of the bound VBO. @@ -179,6 +213,10 @@ class ShaderProgram { if (this.attrCol != -1) gl.disableVertexAttribArray(this.attrCol); if (this.attrTranslate != -1) gl.disableVertexAttribArray(this.attrTranslate); if (this.attrUV != -1) gl.disableVertexAttribArray(this.attrUV); + if (this.attrTransform1 != -1) gl.disableVertexAttribArray(this.attrTransform1); + if (this.attrTransform2 != -1) gl.disableVertexAttribArray(this.attrTransform2); + if (this.attrTransform3 != -1) gl.disableVertexAttribArray(this.attrTransform3); + if (this.attrTransform4 != -1) gl.disableVertexAttribArray(this.attrTransform4); } }; From 31598ca7a225d00e938c4a8c40f7626bb54507bb Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sat, 30 Oct 2021 08:22:28 -0400 Subject: [PATCH 05/34] merging ish --- src/geometry/Mesh.ts | 2 +- src/geometry/ScreenQuad.ts | 4 +- src/globals.ts | 2 + src/main.ts | 55 +++++- src/shaders/flat-frag.glsl | 337 +------------------------------- src/shaders/instanced-vert.glsl | 14 +- 6 files changed, 68 insertions(+), 346 deletions(-) diff --git a/src/geometry/Mesh.ts b/src/geometry/Mesh.ts index ae6b099..6884bb4 100644 --- a/src/geometry/Mesh.ts +++ b/src/geometry/Mesh.ts @@ -25,6 +25,7 @@ class Mesh extends Drawable { this.center = vec4.fromValues(center[0], center[1], center[2], 1); this.objString = objString; + console.log("DEBUG: OBJSTRING: " + objString); } create() { @@ -97,7 +98,6 @@ this.tCol1 = col1s; this.tCol2 = col2s; this.tCol3 = col3s; this.tCol4 = col4s; -console.log("DEBUG COLS: " + this.tCol1); gl.bindBuffer(gl.ARRAY_BUFFER, this.bufCol); gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); diff --git a/src/geometry/ScreenQuad.ts b/src/geometry/ScreenQuad.ts index f873d29..fb678da 100644 --- a/src/geometry/ScreenQuad.ts +++ b/src/geometry/ScreenQuad.ts @@ -15,8 +15,8 @@ class ScreenQuad extends Drawable { this.indices = new Uint32Array([0, 1, 2, 0, 2, 3]); this.positions = new Float32Array([-1, -1, 0.999, 1, - 1, -1, 0.999, 1, - 1, 1, 0.999, 1, + 1, -1, 0.999, 1, + 1, 1, 0.999, 1, -1, 1, 0.999, 1]); this.generateIdx(); diff --git a/src/globals.ts b/src/globals.ts index 31f6787..378fd2f 100644 --- a/src/globals.ts +++ b/src/globals.ts @@ -1,8 +1,10 @@ + export var gl: WebGL2RenderingContext; export function setGL(_gl: WebGL2RenderingContext) { gl = _gl; } + export function readTextFile(file: string): string { var text = ""; diff --git a/src/main.ts b/src/main.ts index e4e4ca4..f0138fb 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,7 +7,9 @@ import OpenGLRenderer from './rendering/gl/OpenGLRenderer'; import Camera from './Camera'; import {setGL} from './globals'; import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram'; -import LSystem from './shaders/l-system/L-System'; +import Mesh from './geometry/Mesh'; +import {readTextFile} from '../src/globals' + // Define an object with application parameters and button callbacks // This will be referred to by dat.GUI's functions that add GUI elements. @@ -17,16 +19,56 @@ const controls = { let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; -let coral : LSystem = new LSystem(); +let branch: Mesh; function loadScene() { square = new Square(); square.create(); screenQuad = new ScreenQuad(); screenQuad.create(); + branch = new Mesh(readTextFile('resources/cylinder.obj'), vec3.fromValues(0, 0, 0)); + branch.create(); + + let colorsArrayBranch = []; + + + let cols1ArrayBranch = []; + cols1ArrayBranch.push(5.0); + cols1ArrayBranch.push(0.0); + cols1ArrayBranch.push(0.0); + cols1ArrayBranch.push(0.0); + + let cols2ArrayBranch = []; + cols2ArrayBranch.push(0.0); + cols2ArrayBranch.push(5.0); + cols2ArrayBranch.push(0.0); + cols2ArrayBranch.push(0.0); + + let cols3ArrayBranch = []; + cols3ArrayBranch.push(0.0); + cols3ArrayBranch.push(0.0); + cols3ArrayBranch.push(5.0); + cols3ArrayBranch.push(0.0); + + let cols4ArrayBranch = []; + cols4ArrayBranch.push(50.0); + cols4ArrayBranch.push(50.0); + cols4ArrayBranch.push(0.0); + cols4ArrayBranch.push(1.0); + + colorsArrayBranch.push(1.0); + colorsArrayBranch.push(0.0); + colorsArrayBranch.push(1.0); + colorsArrayBranch.push(1.0); + + let t1: Float32Array = new Float32Array(cols1ArrayBranch); + let t2: Float32Array = new Float32Array(cols2ArrayBranch); + let t3: Float32Array = new Float32Array(cols3ArrayBranch); + let t4: Float32Array = new Float32Array(cols4ArrayBranch); + let branchColors: Float32Array = new Float32Array(colorsArrayBranch); + branch.setInstanceVBOs(t1, t2, t3, t4, branchColors); + branch.setNumInstances(1); - coral.createMeshes(); - coral.makeTree(); // Set up instanced rendering data arrays here. // This example creates a set of positional @@ -79,10 +121,8 @@ function main() { // Initial call to load scene loadScene(); - //const camera = new Camera(vec3.fromValues(10, 10, 10), vec3.fromValues(0, 0, 0)); const camera = new Camera(vec3.fromValues(50, 50, 10), vec3.fromValues(50, 50, 0)); - const renderer = new OpenGLRenderer(canvas); renderer.setClearColor(0.2, 0.2, 0.2, 1); gl.enable(gl.BLEND); @@ -108,7 +148,8 @@ function main() { renderer.clear(); renderer.render(camera, flat, [screenQuad]); renderer.render(camera, instancedShader, [ - coral.branch + //square, + branch ]); stats.end(); diff --git a/src/shaders/flat-frag.glsl b/src/shaders/flat-frag.glsl index 81827ad..99362d2 100644 --- a/src/shaders/flat-frag.glsl +++ b/src/shaders/flat-frag.glsl @@ -8,339 +8,6 @@ uniform float u_Time; in vec2 fs_Pos; out vec4 out_Col; -const int MAX_RAY_STEPS = 128; -const float FOV = 45.0; -const float EPSILON = 1e-6; - -const vec3 WORLD_UP = vec3(0.0, 1.0, 0.0); -const vec3 WORLD_RIGHT = vec3(-1.0, 0.0, 0.0); -const vec3 WORLD_FORWARD = vec3(0.0, 0.0, 1.0); -const float HALF_PI = 1.570796327; -const float MAX_RAY_LENGTH = 12.0; - -// COLORS -const vec3 MUG_COLOR = vec3(140.0, 150.0, 170.0) / 255.0 * 0.8; -const vec3 SCISSORS_COLOR = vec3(196.0, 202.0, 206.0) / 255.0; -const vec3 FLOOR_COLOR = vec3(91.0, 96.0, 101.0) / 255.0 * 0.5; -const vec3 GOLD_COLOR = vec3(215.0, 190.0, 105.0) / 255.0; -const vec3 backgroundColor = vec3(0.2, 0.4, 0.9); - -// LIGHTS -const vec3 LIGHT_POS = vec3(-1.0, 3.0, 2.0); -const vec3 LIGHT_COLOR = vec3(1.0, .88, .7); - - -// structs -struct Ray -{ - vec3 origin; - vec3 direction; -}; - -struct Intersection -{ - vec3 position; - vec3 normal; - float distance_t; - int material_id; -}; - -// TOOLBOX FUNCTIONS ------------------------------------------------------- -float GetBias(float t, float bias) -{ - return (t / ((((1.0/bias) - 2.0)*(1.0 - t))+1.0)); -} - - -float GetGain(float t, float gain) -{ - if(t < 0.5) - return GetBias(t * 2.0,gain)/2.0; - else - return GetBias(t * 2.0 - 1.0,1.0 - gain)/2.0 + 0.5; -} - -// SDF functions ---------------------------------------------------------- - -float sdfPlane( vec3 p, vec3 n, float h ) -{ - // n must be normalized - return dot(p,n) + h; - // return queryPos.y - h; -} - -float sdfSphere(vec3 query_position, vec3 position, float radius) -{ - return length(query_position - position) - radius; -} - -float sdBox( vec3 p, vec3 b ) -{ - vec3 q = abs(p) - b; - return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0); -} - -float sdRoundedCylinder( vec3 p, float ra, float rb, float h ) -{ - vec2 d = vec2( length(p.xz)-2.0*ra+rb, abs(p.y) - h ); - return min(max(d.x,d.y),0.0) + length(max(d,0.0)) - rb; -} - -float sdCappedCone( vec3 p, float h, float r1, float r2 ) -{ - vec2 q = vec2( length(p.xz), p.y ); - vec2 k1 = vec2(r2,h); - vec2 k2 = vec2(r2-r1,2.0*h); - vec2 ca = vec2(q.x-min(q.x,(q.y<0.0)?r1:r2), abs(q.y)-h); - vec2 cb = q - k1 + k2*clamp( dot(k1-q,k2)/dot(k2, k2), 0.0, 1.0 ); - float s = (cb.x<0.0 && ca.y<0.0) ? -1.0 : 1.0; - return s*sqrt( min(dot(ca, ca),dot(cb, cb)) ); -} - -float sdHexPrism( vec3 p, vec2 h ) -{ - const vec3 k = vec3(-0.8660254, 0.5, 0.57735); - p = abs(p); - p.xy -= 2.0*min(dot(k.xy, p.xy), 0.0)*k.xy; - vec2 d = vec2( - length(p.xy-vec2(clamp(p.x,-k.z*h.x,k.z*h.x), h.x))*sign(p.y-h.x), - p.z-h.y ); - return min(max(d.x,d.y),0.0) + length(max(d,0.0)); -} - - -// SDF Modifiers------------------------------------------------------------- -float opRound(float sdf, float rad ) -{ - return sdf - rad; -} - -float smin( float a, float b, float k ) -{ - float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 ); - return mix( b, a, h ) - k*h*(1.0-h); -} - -float opSmoothSubtraction( float d1, float d2, float k ) { - float h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 ); - return mix( d2, -d1, h ) + k*h*(1.0-h); -} - -vec3 opElongate(in vec3 p, in vec3 h ) -{ - vec3 q = p - clamp( p, -h, h ); - return q; -} - -float sphereRep( vec3 p, vec3 c ) -{ - vec3 q = mod(p+0.5*c,c)-0.5*c; - return sdfSphere( q, vec3(0.0), 1.0 ); -} - -// from https://github.com/dmnsgn/glsl-rotate/blob/master/rotation-3d-x.glsl -mat3 rotation3dX(float angle) { - float s = sin(angle); - float c = cos(angle); - - return mat3( - 1.0, 0.0, 0.0, - 0.0, c, s, - 0.0, -s, c - ); -} - -// from https://github.com/dmnsgn/glsl-rotate/blob/master/rotation-3d-y.glsl -mat3 rotation3dY(float angle) { - float s = sin(angle); - float c = cos(angle); - - return mat3( - c, 0.0, -s, - 0.0, 1.0, 0.0, - s, 0.0, c - ); -} - -// from https://github.com/dmnsgn/glsl-rotate/blob/master/rotation-3d-z.glsl -mat3 rotation3dZ(float angle) { - float s = sin(angle); - float c = cos(angle); - - return mat3( - c, s, 0.0, - -s, c, 0.0, - 0.0, 0.0, 1.0 - ); -} - -// Scene Building------------------------------------------------------------------------- - -// Build for a Bubble -float sceneSDFBubble(vec3 queryPos) { - float t = sdfSphere(queryPos, vec3(0.0), 10.0); - - return t; -} - -vec3 animateHorizontal(vec3 p) { - return p + vec3(8.0, 0.0, 0.0) * (GetBias(sin(u_Time * .025) + 1.0, 0.7) - 0.5); -} - -vec3 animateYRotation(vec3 p) { - return transpose(rotation3dY(GetGain((.5 * sin(u_Time * .025) + 0.5), 0.7) * 6.0)) * p; -} - -float sceneSDF(vec3 queryPos, out int hitObj) -{ - - // Bounding sphere, so we only have to check for geometry within certain bounds - float bounding_box_dist = sdBox(queryPos, vec3(12.0)); - // if(bounding_box_dist <= .00001) { - - // Bubbles - float t = sceneSDFBubble(animateHorizontal((queryPos))); - hitObj = 1; - - float t2 = sceneSDFBubble(queryPos); - if (t2 < t) { - t = t2; - hitObj = 0; - } - - return t; - // } - hitObj = -2; - return bounding_box_dist; -} - -vec3 estimateNormal(vec3 p, out int hitObj) { - vec2 d = vec2(0.0, EPSILON); - float x = sceneSDF(p + d.yxx, hitObj) - sceneSDF(p - d.yxx, hitObj); - float y = sceneSDF(p + d.xyx, hitObj) - sceneSDF(p - d.xyx, hitObj); - float z = sceneSDF(p + d.xxy, hitObj) - sceneSDF(p - d.xxy, hitObj); - return normalize(abs(vec3(x, y, z))); -} - -Ray getRay(vec2 uv) -{ - Ray r; - float aspect_ratio = u_Dimensions.x / u_Dimensions.y; - float len = length(u_Ref - u_Eye); - - vec3 look = normalize(u_Ref - u_Eye); - vec3 camera_RIGHT = normalize(cross(look, u_Up)); - - vec3 screen_vertical = u_Up * len * tan(FOV / 2.0); - vec3 screen_horizontal = camera_RIGHT * len * aspect_ratio * tan(FOV / 2.0); - vec3 screen_point = (u_Ref + uv.x * screen_horizontal + uv.y * screen_vertical); - - r.origin = u_Eye; - r.direction = normalize(screen_point - u_Eye); - - return r; -} - -bool isRayTooLong(vec3 queryPoint, vec3 origin) -{ - return length(queryPoint - origin) > MAX_RAY_LENGTH; -} - -Intersection getRaymarchedIntersection(vec2 uv, out int hitObj) -{ - Intersection intersection; - intersection.distance_t = -1.0; - - Ray r = getRay(uv); - float distancet = 0.0; - - for (int step; step < MAX_RAY_STEPS; step++) { - vec3 qPoint = r.origin + r.direction * distancet; - if(isRayTooLong(qPoint, r.origin)) { - break; - } - float currentDistance = sceneSDF(qPoint, hitObj); - if (currentDistance < EPSILON) { - // something was hit by our ray! - intersection.distance_t = distancet; - intersection.normal = estimateNormal(qPoint, hitObj); - intersection.position = r.origin + distancet * r.direction; - return intersection; - } - distancet += currentDistance; - - } - - return intersection; -} - -// SHADING ------------------------------------------------------------------------------------------------------------ - -float shadeLambert(vec3 norm, vec3 lightVec) { - // Calculate the diffuse term for Lambert shading - float diffuseTerm = dot(normalize(norm), normalize(lightVec)); - - // Avoid negative lighting values - diffuseTerm = clamp(diffuseTerm, 0.f, 1.f); - - // add ambient lighting - float ambientTerm = 0.2; - float lightIntensity = diffuseTerm + ambientTerm; - - return lightIntensity; -} - -vec3 computeMaterial(int hitObj, vec3 p, vec3 n) { - float t; - - vec3 albedo; - switch(hitObj) { - case 0: // Mug - albedo = MUG_COLOR; - break; - case 1: // Scissors - albedo = SCISSORS_COLOR; - break; - case 2: // Floor - albedo = FLOOR_COLOR; - break; // Background - case 3: // Mug Lip - albedo = GOLD_COLOR; - break; - case -1: - return backgroundColor; - break; - case -2: - return backgroundColor; - break; - } - - vec3 color = vec3(0.0); - - color = albedo; - - return color; -} - -vec3 getSceneColor(vec2 uv) -{ - int hitObj = -1; - Intersection intersection = getRaymarchedIntersection(uv, hitObj); - if (intersection.distance_t > 0.0) - { - // shade everything with lambert - float lightIntensity = shadeLambert(intersection.normal, LIGHT_POS - intersection.position); - return lightIntensity * computeMaterial(hitObj, intersection.position, intersection.normal); - } - return backgroundColor; -} - -// MAIN -------------------------------------------------------------------------------------------------------------- - void main() { - // Using Raymarching: - vec3 col = getSceneColor(fs_Pos); - // Output to screen - out_Col = vec4(col,1.0); - -} \ No newline at end of file + out_Col = vec4(0.5 * (fs_Pos + vec2(1.0)), 0.0, 1.0); +} diff --git a/src/shaders/instanced-vert.glsl b/src/shaders/instanced-vert.glsl index d8b8996..1ee1a92 100644 --- a/src/shaders/instanced-vert.glsl +++ b/src/shaders/instanced-vert.glsl @@ -10,20 +10,32 @@ in vec4 vs_Pos; // Non-instanced; each particle is the same quad drawn in a diff in vec4 vs_Nor; // Non-instanced, and presently unused in vec4 vs_Col; // An instanced rendering attribute; each particle instance has a different color in vec3 vs_Translate; // Another instance rendering attribute used to position each quad instance in the scene +in vec4 vs_Transform1; +in vec4 vs_Transform2; +in vec4 vs_Transform3; +in vec4 vs_Transform4; + in vec2 vs_UV; // Non-instanced, and presently unused in main(). Feel free to use it for your meshes. out vec4 fs_Col; out vec4 fs_Pos; +out vec4 fs_Nor; void main() { fs_Col = vs_Col; fs_Pos = vs_Pos; + + mat4 TransformMatrix = mat4(vs_Transform1, vs_Transform2, vs_Transform3, vs_Transform4); + fs_Nor = TransformMatrix * vs_Nor; + fs_Pos = TransformMatrix * vs_Pos; + vec3 offset = vs_Translate; offset.z = (sin((u_Time + offset.x) * 3.14159 * 0.1) + cos((u_Time + offset.y) * 3.14159 * 0.1)) * 1.5; vec3 billboardPos = offset + vs_Pos.x * u_CameraAxes[0] + vs_Pos.y * u_CameraAxes[1]; - gl_Position = u_ViewProj * vec4(billboardPos, 1.0); + gl_Position = u_ViewProj * vec4(vec3(fs_Pos), 1.0); + // gl_Position = u_ViewProj * vec4(billboardPos, 1.0); } From 01fdf87a0bb650675363f26b0ccc2ebfb8341343 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sat, 30 Oct 2021 08:29:58 -0400 Subject: [PATCH 06/34] re-formatting --- src/geometry/Mesh.ts | 56 +++++++++--------- src/main.ts | 96 ++++++++++++++++--------------- src/rendering/gl/Drawable.ts | 9 +-- src/rendering/gl/ShaderProgram.ts | 58 +++++++++++-------- 4 files changed, 118 insertions(+), 101 deletions(-) diff --git a/src/geometry/Mesh.ts b/src/geometry/Mesh.ts index 6884bb4..da5c56b 100644 --- a/src/geometry/Mesh.ts +++ b/src/geometry/Mesh.ts @@ -1,7 +1,7 @@ -import {vec3, vec4} from 'gl-matrix'; -import Drawable from '../rendering/gl/Drawable'; -import {gl} from '../globals'; -import * as Loader from 'webgl-obj-loader'; +import { vec3, vec4 } from "gl-matrix"; +import Drawable from "../rendering/gl/Drawable"; +import { gl } from "../globals"; +import * as Loader from "webgl-obj-loader"; class Mesh extends Drawable { indices: Uint32Array; @@ -17,7 +17,6 @@ class Mesh extends Drawable { tCol3: Float32Array; // Data for bufTransform3 tCol4: Float32Array; // Data for bufTransform4 - objString: string; constructor(objString: string, center: vec3) { @@ -28,7 +27,7 @@ class Mesh extends Drawable { console.log("DEBUG: OBJSTRING: " + objString); } - create() { + create() { let posTemp: Array = []; let norTemp: Array = []; let uvsTemp: Array = []; @@ -51,7 +50,7 @@ class Mesh extends Drawable { // color white this.colors = new Float32Array(posTemp.length); - for (var i = 0; i < posTemp.length; ++i){ + for (var i = 0; i < posTemp.length; ++i) { this.colors[i] = 1.0; } @@ -91,25 +90,30 @@ class Mesh extends Drawable { this.objString = ""; } - setInstanceVBOs(col1s: Float32Array, col2s: Float32Array, col3s: Float32Array, col4s: Float32Array, - colors: Float32Array) { -this.colors = colors; -this.tCol1 = col1s; -this.tCol2 = col2s; -this.tCol3 = col3s; -this.tCol4 = col4s; - -gl.bindBuffer(gl.ARRAY_BUFFER, this.bufCol); -gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); -gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform1); -gl.bufferData(gl.ARRAY_BUFFER, this.tCol1, gl.STATIC_DRAW); -gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform2); -gl.bufferData(gl.ARRAY_BUFFER, this.tCol2, gl.STATIC_DRAW); -gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform3); -gl.bufferData(gl.ARRAY_BUFFER, this.tCol3, gl.STATIC_DRAW); -gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform4); -gl.bufferData(gl.ARRAY_BUFFER, this.tCol4, gl.STATIC_DRAW); + setInstanceVBOs( + col1s: Float32Array, + col2s: Float32Array, + col3s: Float32Array, + col4s: Float32Array, + colors: Float32Array + ) { + this.colors = colors; + this.tCol1 = col1s; + this.tCol2 = col2s; + this.tCol3 = col3s; + this.tCol4 = col4s; + + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufCol); + gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform1); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol1, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform2); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol2, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform3); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol3, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform4); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol4, gl.STATIC_DRAW); + } } -}; export default Mesh; diff --git a/src/main.ts b/src/main.ts index f0138fb..44d9e1c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,20 +1,18 @@ -import {vec3} from 'gl-matrix'; -import * as Stats from 'stats-js'; -import * as DAT from 'dat-gui'; -import Square from './geometry/Square'; -import ScreenQuad from './geometry/ScreenQuad'; -import OpenGLRenderer from './rendering/gl/OpenGLRenderer'; -import Camera from './Camera'; -import {setGL} from './globals'; -import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram'; -import Mesh from './geometry/Mesh'; -import {readTextFile} from '../src/globals' - +import { vec3 } from "gl-matrix"; +import * as Stats from "stats-js"; +import * as DAT from "dat-gui"; +import Square from "./geometry/Square"; +import ScreenQuad from "./geometry/ScreenQuad"; +import OpenGLRenderer from "./rendering/gl/OpenGLRenderer"; +import Camera from "./Camera"; +import { setGL } from "./globals"; +import ShaderProgram, { Shader } from "./rendering/gl/ShaderProgram"; +import Mesh from "./geometry/Mesh"; +import { readTextFile } from "../src/globals"; // 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 = { -}; +const controls = {}; let square: Square; let screenQuad: ScreenQuad; @@ -26,33 +24,35 @@ function loadScene() { square.create(); screenQuad = new ScreenQuad(); screenQuad.create(); - branch = new Mesh(readTextFile('resources/cylinder.obj'), vec3.fromValues(0, 0, 0)); + branch = new Mesh( + readTextFile("resources/cylinder.obj"), + vec3.fromValues(0, 0, 0) + ); branch.create(); - let colorsArrayBranch = []; - + let colorsArrayBranch = []; - let cols1ArrayBranch = []; + let cols1ArrayBranch = []; cols1ArrayBranch.push(5.0); cols1ArrayBranch.push(0.0); cols1ArrayBranch.push(0.0); cols1ArrayBranch.push(0.0); let cols2ArrayBranch = []; - cols2ArrayBranch.push(0.0); - cols2ArrayBranch.push(5.0); + cols2ArrayBranch.push(0.0); + cols2ArrayBranch.push(5.0); cols2ArrayBranch.push(0.0); cols2ArrayBranch.push(0.0); let cols3ArrayBranch = []; - cols3ArrayBranch.push(0.0); - cols3ArrayBranch.push(0.0); + cols3ArrayBranch.push(0.0); + cols3ArrayBranch.push(0.0); cols3ArrayBranch.push(5.0); cols3ArrayBranch.push(0.0); let cols4ArrayBranch = []; - cols4ArrayBranch.push(50.0); - cols4ArrayBranch.push(50.0); + cols4ArrayBranch.push(50.0); + cols4ArrayBranch.push(50.0); cols4ArrayBranch.push(0.0); cols4ArrayBranch.push(1.0); @@ -69,7 +69,6 @@ function loadScene() { branch.setInstanceVBOs(t1, t2, t3, t4, branchColors); branch.setNumInstances(1); - // Set up instanced rendering data arrays here. // This example creates a set of positional // offsets and gradiated colors for a 100x100 grid @@ -78,8 +77,8 @@ function loadScene() { let offsetsArray = []; let colorsArray = []; let n: number = 100.0; - for(let i = 0; i < n; i++) { - for(let j = 0; j < n; j++) { + for (let i = 0; i < n; i++) { + for (let j = 0; j < n; j++) { offsetsArray.push(i); offsetsArray.push(j); offsetsArray.push(0); @@ -100,19 +99,19 @@ function main() { // Initial display for framerate const stats = Stats(); stats.setMode(0); - stats.domElement.style.position = 'absolute'; - stats.domElement.style.left = '0px'; - stats.domElement.style.top = '0px'; + stats.domElement.style.position = "absolute"; + stats.domElement.style.left = "0px"; + stats.domElement.style.top = "0px"; document.body.appendChild(stats.domElement); // Add controls to the gui const gui = new DAT.GUI(); // get canvas and webgl context - const canvas = document.getElementById('canvas'); - const gl = canvas.getContext('webgl2'); + const canvas = document.getElementById("canvas"); + const gl = canvas.getContext("webgl2"); if (!gl) { - alert('WebGL 2 not supported!'); + alert("WebGL 2 not supported!"); } // `setGL` is a function imported above which sets the value of `gl` in the `globals.ts` module. // Later, we can import `gl` from `globals.ts` to access it @@ -121,7 +120,10 @@ function main() { // Initial call to load scene loadScene(); - const camera = new Camera(vec3.fromValues(50, 50, 10), vec3.fromValues(50, 50, 0)); + const camera = new Camera( + vec3.fromValues(50, 50, 10), + vec3.fromValues(50, 50, 0) + ); const renderer = new OpenGLRenderer(canvas); renderer.setClearColor(0.2, 0.2, 0.2, 1); @@ -129,13 +131,13 @@ function main() { gl.blendFunc(gl.ONE, gl.ONE); // Additive blending const instancedShader = new ShaderProgram([ - new Shader(gl.VERTEX_SHADER, require('./shaders/instanced-vert.glsl')), - new Shader(gl.FRAGMENT_SHADER, require('./shaders/instanced-frag.glsl')), + new Shader(gl.VERTEX_SHADER, require("./shaders/instanced-vert.glsl")), + new Shader(gl.FRAGMENT_SHADER, require("./shaders/instanced-frag.glsl")), ]); const flat = new ShaderProgram([ - new Shader(gl.VERTEX_SHADER, require('./shaders/flat-vert.glsl')), - new Shader(gl.FRAGMENT_SHADER, require('./shaders/flat-frag.glsl')), + new Shader(gl.VERTEX_SHADER, require("./shaders/flat-vert.glsl")), + new Shader(gl.FRAGMENT_SHADER, require("./shaders/flat-frag.glsl")), ]); // This function will be called every frame @@ -149,7 +151,7 @@ function main() { renderer.render(camera, flat, [screenQuad]); renderer.render(camera, instancedShader, [ //square, - branch + branch, ]); stats.end(); @@ -157,12 +159,16 @@ function main() { requestAnimationFrame(tick); } - window.addEventListener('resize', function() { - renderer.setSize(window.innerWidth, window.innerHeight); - camera.setAspectRatio(window.innerWidth / window.innerHeight); - camera.updateProjectionMatrix(); - flat.setDimensions(window.innerWidth, window.innerHeight); - }, false); + window.addEventListener( + "resize", + function () { + renderer.setSize(window.innerWidth, window.innerHeight); + camera.setAspectRatio(window.innerWidth / window.innerHeight); + camera.updateProjectionMatrix(); + flat.setDimensions(window.innerWidth, window.innerHeight); + }, + false + ); renderer.setSize(window.innerWidth, window.innerHeight); camera.setAspectRatio(window.innerWidth / window.innerHeight); diff --git a/src/rendering/gl/Drawable.ts b/src/rendering/gl/Drawable.ts index 6f2a00a..e93df14 100644 --- a/src/rendering/gl/Drawable.ts +++ b/src/rendering/gl/Drawable.ts @@ -1,4 +1,4 @@ -import {gl} from '../../globals'; +import { gl } from "../../globals"; abstract class Drawable { count: number = 0; @@ -25,10 +25,9 @@ abstract class Drawable { transform3Generated: boolean = false; transform4Generated: boolean = false; - numInstances: number = 0; // How many instances of this Drawable the shader program should draw - abstract create() : void; + abstract create(): void; destroy() { gl.deleteBuffer(this.bufIdx); @@ -161,8 +160,6 @@ abstract class Drawable { return this.transform4Generated; } - - elemCount(): number { return this.count; } @@ -174,6 +171,6 @@ abstract class Drawable { setNumInstances(num: number) { this.numInstances = num; } -}; +} export default Drawable; diff --git a/src/rendering/gl/ShaderProgram.ts b/src/rendering/gl/ShaderProgram.ts index 54421a1..f20d326 100644 --- a/src/rendering/gl/ShaderProgram.ts +++ b/src/rendering/gl/ShaderProgram.ts @@ -1,6 +1,6 @@ -import {vec3, vec4, mat4, mat3} from 'gl-matrix'; -import Drawable from './Drawable'; -import {gl} from '../../globals'; +import { vec3, vec4, mat4, mat3 } from "gl-matrix"; +import Drawable from "./Drawable"; +import { gl } from "../../globals"; var activeProgram: WebGLProgram = null; @@ -16,7 +16,7 @@ export class Shader { throw gl.getShaderInfoLog(this.shader); } } -}; +} class ShaderProgram { prog: WebGLProgram; @@ -31,7 +31,6 @@ class ShaderProgram { attrTransform3: number; attrTransform4: number; - unifModel: WebGLUniformLocation; unifModelInvTr: WebGLUniformLocation; unifViewProj: WebGLUniformLocation; @@ -62,15 +61,15 @@ class ShaderProgram { this.attrTransform2 = gl.getAttribLocation(this.prog, "vs_Transform2"); this.attrTransform3 = gl.getAttribLocation(this.prog, "vs_Transform3"); this.attrTransform4 = gl.getAttribLocation(this.prog, "vs_Transform4"); - - 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.unifCameraAxes = gl.getUniformLocation(this.prog, "u_CameraAxes"); - this.unifTime = gl.getUniformLocation(this.prog, "u_Time"); - this.unifEye = gl.getUniformLocation(this.prog, "u_Eye"); - this.unifRef = gl.getUniformLocation(this.prog, "u_Ref"); - this.unifUp = gl.getUniformLocation(this.prog, "u_Up"); + this.unifViewProj = gl.getUniformLocation(this.prog, "u_ViewProj"); + this.unifCameraAxes = gl.getUniformLocation(this.prog, "u_CameraAxes"); + this.unifTime = gl.getUniformLocation(this.prog, "u_Time"); + this.unifEye = gl.getUniformLocation(this.prog, "u_Eye"); + this.unifRef = gl.getUniformLocation(this.prog, "u_Ref"); + this.unifUp = gl.getUniformLocation(this.prog, "u_Up"); } use() { @@ -82,20 +81,20 @@ class ShaderProgram { setEyeRefUp(eye: vec3, ref: vec3, up: vec3) { this.use(); - if(this.unifEye !== -1) { + if (this.unifEye !== -1) { gl.uniform3f(this.unifEye, eye[0], eye[1], eye[2]); } - if(this.unifRef !== -1) { + if (this.unifRef !== -1) { gl.uniform3f(this.unifRef, ref[0], ref[1], ref[2]); } - if(this.unifUp !== -1) { + if (this.unifUp !== -1) { gl.uniform3f(this.unifUp, up[0], up[1], up[2]); } } setDimensions(width: number, height: number) { this.use(); - if(this.unifDimensions !== -1) { + if (this.unifDimensions !== -1) { gl.uniform2f(this.unifDimensions, width, height); } } @@ -206,18 +205,29 @@ class ShaderProgram { // by the GPU, thus being the same value for the first set of four vertices, // then advancing to a new value for the next four, then the next four, and // so on. - gl.drawElementsInstanced(d.drawMode(), d.elemCount(), gl.UNSIGNED_INT, 0, d.numInstances); + gl.drawElementsInstanced( + d.drawMode(), + d.elemCount(), + gl.UNSIGNED_INT, + 0, + d.numInstances + ); if (this.attrPos != -1) gl.disableVertexAttribArray(this.attrPos); if (this.attrNor != -1) gl.disableVertexAttribArray(this.attrNor); if (this.attrCol != -1) gl.disableVertexAttribArray(this.attrCol); - if (this.attrTranslate != -1) gl.disableVertexAttribArray(this.attrTranslate); + if (this.attrTranslate != -1) + gl.disableVertexAttribArray(this.attrTranslate); if (this.attrUV != -1) gl.disableVertexAttribArray(this.attrUV); - if (this.attrTransform1 != -1) gl.disableVertexAttribArray(this.attrTransform1); - if (this.attrTransform2 != -1) gl.disableVertexAttribArray(this.attrTransform2); - if (this.attrTransform3 != -1) gl.disableVertexAttribArray(this.attrTransform3); - if (this.attrTransform4 != -1) gl.disableVertexAttribArray(this.attrTransform4); + if (this.attrTransform1 != -1) + gl.disableVertexAttribArray(this.attrTransform1); + if (this.attrTransform2 != -1) + gl.disableVertexAttribArray(this.attrTransform2); + if (this.attrTransform3 != -1) + gl.disableVertexAttribArray(this.attrTransform3); + if (this.attrTransform4 != -1) + gl.disableVertexAttribArray(this.attrTransform4); } -}; +} export default ShaderProgram; From b764c68cd1bd2f1f400d6566db77681306da47be Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Mon, 1 Nov 2021 16:30:17 -0400 Subject: [PATCH 07/34] I CAN DRAW SQUARES NOW! --- src/geometry/Mesh.ts | 1 + src/geometry/Square.ts | 38 ++++++ src/{shaders => }/l-system/DrawingRule.ts | 0 src/{shaders => }/l-system/ExpansionRule.ts | 0 src/{shaders => }/l-system/L-System.ts | 10 +- src/{shaders => }/l-system/Turtle.ts | 0 src/main.ts | 129 +++++++++++--------- src/rendering/gl/ShaderProgram.ts | 1 + src/shaders/instanced-vert.glsl | 11 +- 9 files changed, 126 insertions(+), 64 deletions(-) rename src/{shaders => }/l-system/DrawingRule.ts (100%) rename src/{shaders => }/l-system/ExpansionRule.ts (100%) rename src/{shaders => }/l-system/L-System.ts (96%) rename src/{shaders => }/l-system/Turtle.ts (100%) diff --git a/src/geometry/Mesh.ts b/src/geometry/Mesh.ts index da5c56b..07190d6 100644 --- a/src/geometry/Mesh.ts +++ b/src/geometry/Mesh.ts @@ -117,3 +117,4 @@ class Mesh extends Drawable { } export default Mesh; + diff --git a/src/geometry/Square.ts b/src/geometry/Square.ts index 5fdb8ba..a020345 100644 --- a/src/geometry/Square.ts +++ b/src/geometry/Square.ts @@ -8,6 +8,12 @@ class Square extends Drawable { colors: Float32Array; offsets: Float32Array; // Data for bufTranslate + tCol1: Float32Array; // Data for bufTransform1 + tCol2: Float32Array; // Data for bufTransform2 + tCol3: Float32Array; // Data for bufTransform3 + tCol4: Float32Array; // Data for bufTransform4 + + constructor() { super(); // Call the constructor of the super class. This is required. @@ -27,6 +33,12 @@ class Square extends Drawable { this.generateCol(); this.generateTranslate(); + this.generateTransform1(); + this.generateTransform2(); + this.generateTransform3(); + this.generateTransform4(); + + this.count = this.indices.length; gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.bufIdx); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); @@ -46,6 +58,32 @@ class Square extends Drawable { gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTranslate); gl.bufferData(gl.ARRAY_BUFFER, this.offsets, gl.STATIC_DRAW); } + + setInstanceTransformVBOs( + col1s: Float32Array, + col2s: Float32Array, + col3s: Float32Array, + col4s: Float32Array, + colors: Float32Array + ) { + this.colors = colors; + this.tCol1 = col1s; + this.tCol2 = col2s; + this.tCol3 = col3s; + this.tCol4 = col4s; + + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufCol); + gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform1); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol1, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform2); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol2, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform3); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol3, gl.STATIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.bufTransform4); + gl.bufferData(gl.ARRAY_BUFFER, this.tCol4, gl.STATIC_DRAW); + } }; export default Square; + diff --git a/src/shaders/l-system/DrawingRule.ts b/src/l-system/DrawingRule.ts similarity index 100% rename from src/shaders/l-system/DrawingRule.ts rename to src/l-system/DrawingRule.ts diff --git a/src/shaders/l-system/ExpansionRule.ts b/src/l-system/ExpansionRule.ts similarity index 100% rename from src/shaders/l-system/ExpansionRule.ts rename to src/l-system/ExpansionRule.ts diff --git a/src/shaders/l-system/L-System.ts b/src/l-system/L-System.ts similarity index 96% rename from src/shaders/l-system/L-System.ts rename to src/l-system/L-System.ts index e464876..e44ea2c 100644 --- a/src/shaders/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -1,10 +1,10 @@ import DrawingRule from "./DrawingRule"; import ExpansionRule from "./ExpansionRule"; import Turtle from "./Turtle"; -import Mesh from "../../geometry/Mesh"; -import {readTextFile} from "../../globals" +import Mesh from "../geometry/Mesh"; +import {readTextFile} from "../globals" import { vec3, mat4, quat } from "gl-matrix"; -import OpenGLRenderer from '../../rendering/gl/OpenGLRenderer'; +import OpenGLRenderer from '../rendering/gl/OpenGLRenderer'; class LSystem { turtleStack: Array = []; @@ -147,7 +147,7 @@ class LSystem { let bCol4: Float32Array = new Float32Array(this.branchCols4); let bcolors: Float32Array = new Float32Array(this.branchColorsBO); this.branch.create(); - this.branch.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); + // this.branch.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); this.branch.setNumInstances(this.branchNum); } @@ -172,7 +172,7 @@ class LSystem { } currExpansion = expandedString; this.axioms.push(expandedString); - } + } this.drawTree(); } diff --git a/src/shaders/l-system/Turtle.ts b/src/l-system/Turtle.ts similarity index 100% rename from src/shaders/l-system/Turtle.ts rename to src/l-system/Turtle.ts diff --git a/src/main.ts b/src/main.ts index 44d9e1c..0a0a0c3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,58 +1,59 @@ -import { vec3 } from "gl-matrix"; -import * as Stats from "stats-js"; -import * as DAT from "dat-gui"; -import Square from "./geometry/Square"; -import ScreenQuad from "./geometry/ScreenQuad"; -import OpenGLRenderer from "./rendering/gl/OpenGLRenderer"; -import Camera from "./Camera"; -import { setGL } from "./globals"; -import ShaderProgram, { Shader } from "./rendering/gl/ShaderProgram"; -import Mesh from "./geometry/Mesh"; -import { readTextFile } from "../src/globals"; +import {vec3, mat4} from 'gl-matrix'; +import * as Stats from 'stats-js'; +import * as DAT from 'dat-gui'; +import Square from './geometry/Square'; +import ScreenQuad from './geometry/ScreenQuad'; +import OpenGLRenderer from './rendering/gl/OpenGLRenderer'; +import Camera from './Camera'; +import {setGL} from './globals'; +import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram'; +import Mesh from './geometry/Mesh'; +import {readTextFile} from '../src/globals' + // 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 = {}; +const controls = { +}; let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; let branch: Mesh; +let matrix : mat4 = mat4.create(); function loadScene() { square = new Square(); square.create(); screenQuad = new ScreenQuad(); screenQuad.create(); - branch = new Mesh( - readTextFile("resources/cylinder.obj"), - vec3.fromValues(0, 0, 0) - ); + branch = new Mesh(readTextFile('resources/cylinder.obj'), vec3.fromValues(0, 0, 0)); branch.create(); - let colorsArrayBranch = []; + let colorsArrayBranch = []; + - let cols1ArrayBranch = []; + let cols1ArrayBranch = []; cols1ArrayBranch.push(5.0); cols1ArrayBranch.push(0.0); cols1ArrayBranch.push(0.0); cols1ArrayBranch.push(0.0); let cols2ArrayBranch = []; - cols2ArrayBranch.push(0.0); - cols2ArrayBranch.push(5.0); + cols2ArrayBranch.push(0.0); + cols2ArrayBranch.push(5.0); cols2ArrayBranch.push(0.0); cols2ArrayBranch.push(0.0); let cols3ArrayBranch = []; - cols3ArrayBranch.push(0.0); - cols3ArrayBranch.push(0.0); + cols3ArrayBranch.push(0.0); + cols3ArrayBranch.push(0.0); cols3ArrayBranch.push(5.0); cols3ArrayBranch.push(0.0); let cols4ArrayBranch = []; - cols4ArrayBranch.push(50.0); - cols4ArrayBranch.push(50.0); + cols4ArrayBranch.push(50.0); + cols4ArrayBranch.push(50.0); cols4ArrayBranch.push(0.0); cols4ArrayBranch.push(1.0); @@ -69,6 +70,7 @@ function loadScene() { branch.setInstanceVBOs(t1, t2, t3, t4, branchColors); branch.setNumInstances(1); + // Set up instanced rendering data arrays here. // This example creates a set of positional // offsets and gradiated colors for a 100x100 grid @@ -77,21 +79,45 @@ function loadScene() { let offsetsArray = []; let colorsArray = []; let n: number = 100.0; - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { + let sCol1 = []; + let sCol2 = []; + let sCol3 = []; + let sCol4 = []; + + for(let i = 0; i < n; i++) { + for(let j = 0; j < n; j++) { + mat4.translate(matrix, matrix, vec3.fromValues(i, j, 0)); + //mat4.scale(matrix, matrix, vec3.fromValues(5.0, 5.0, 5.0)); + for (let k : number = 0; k < 4; k++) { + sCol1.push(matrix[k]); + sCol2.push(matrix[k + 4]); + sCol3.push(matrix[k + 8]); + sCol4.push(matrix[k + 12]); + } + offsetsArray.push(i); offsetsArray.push(j); offsetsArray.push(0); - colorsArray.push(i / n); - colorsArray.push(j / n); + colorsArray.push(j / i); + colorsArray.push(j / i); colorsArray.push(1.0); colorsArray.push(1.0); // Alpha channel + mat4.identity(matrix); } } let offsets: Float32Array = new Float32Array(offsetsArray); + + let offsetsCol1 : Float32Array = new Float32Array(sCol1); + let offsetsCol2 : Float32Array = new Float32Array(sCol2); + let offsetsCol3 : Float32Array = new Float32Array(sCol3); + let offsetsCol4 : Float32Array = new Float32Array(sCol4); + + let colors: Float32Array = new Float32Array(colorsArray); - square.setInstanceVBOs(offsets, colors); + square.setInstanceTransformVBOs(offsetsCol1, offsetsCol2, offsetsCol3, offsetsCol4, colors); + console.log("DEBUG: OFFSETS: " + offsetsCol1); + //square.setInstanceVBOs(offsets, colors); square.setNumInstances(n * n); // grid of "particles" } @@ -99,19 +125,19 @@ function main() { // Initial display for framerate const stats = Stats(); stats.setMode(0); - stats.domElement.style.position = "absolute"; - stats.domElement.style.left = "0px"; - stats.domElement.style.top = "0px"; + stats.domElement.style.position = 'absolute'; + stats.domElement.style.left = '0px'; + stats.domElement.style.top = '0px'; document.body.appendChild(stats.domElement); // Add controls to the gui const gui = new DAT.GUI(); // get canvas and webgl context - const canvas = document.getElementById("canvas"); - const gl = canvas.getContext("webgl2"); + const canvas = document.getElementById('canvas'); + const gl = canvas.getContext('webgl2'); if (!gl) { - alert("WebGL 2 not supported!"); + alert('WebGL 2 not supported!'); } // `setGL` is a function imported above which sets the value of `gl` in the `globals.ts` module. // Later, we can import `gl` from `globals.ts` to access it @@ -120,10 +146,7 @@ function main() { // Initial call to load scene loadScene(); - const camera = new Camera( - vec3.fromValues(50, 50, 10), - vec3.fromValues(50, 50, 0) - ); + const camera = new Camera(vec3.fromValues(5, 5, 10), vec3.fromValues(50, 50, 0)); const renderer = new OpenGLRenderer(canvas); renderer.setClearColor(0.2, 0.2, 0.2, 1); @@ -131,13 +154,13 @@ function main() { gl.blendFunc(gl.ONE, gl.ONE); // Additive blending const instancedShader = new ShaderProgram([ - new Shader(gl.VERTEX_SHADER, require("./shaders/instanced-vert.glsl")), - new Shader(gl.FRAGMENT_SHADER, require("./shaders/instanced-frag.glsl")), + new Shader(gl.VERTEX_SHADER, require('./shaders/instanced-vert.glsl')), + new Shader(gl.FRAGMENT_SHADER, require('./shaders/instanced-frag.glsl')), ]); const flat = new ShaderProgram([ - new Shader(gl.VERTEX_SHADER, require("./shaders/flat-vert.glsl")), - new Shader(gl.FRAGMENT_SHADER, require("./shaders/flat-frag.glsl")), + new Shader(gl.VERTEX_SHADER, require('./shaders/flat-vert.glsl')), + new Shader(gl.FRAGMENT_SHADER, require('./shaders/flat-frag.glsl')), ]); // This function will be called every frame @@ -150,8 +173,8 @@ function main() { renderer.clear(); renderer.render(camera, flat, [screenQuad]); renderer.render(camera, instancedShader, [ - //square, - branch, + square, + // branch ]); stats.end(); @@ -159,16 +182,12 @@ function main() { requestAnimationFrame(tick); } - window.addEventListener( - "resize", - function () { - renderer.setSize(window.innerWidth, window.innerHeight); - camera.setAspectRatio(window.innerWidth / window.innerHeight); - camera.updateProjectionMatrix(); - flat.setDimensions(window.innerWidth, window.innerHeight); - }, - false - ); + window.addEventListener('resize', function() { + renderer.setSize(window.innerWidth, window.innerHeight); + camera.setAspectRatio(window.innerWidth / window.innerHeight); + camera.updateProjectionMatrix(); + flat.setDimensions(window.innerWidth, window.innerHeight); + }, false); renderer.setSize(window.innerWidth, window.innerHeight); camera.setAspectRatio(window.innerWidth / window.innerHeight); diff --git a/src/rendering/gl/ShaderProgram.ts b/src/rendering/gl/ShaderProgram.ts index f20d326..e887dfe 100644 --- a/src/rendering/gl/ShaderProgram.ts +++ b/src/rendering/gl/ShaderProgram.ts @@ -231,3 +231,4 @@ class ShaderProgram { } export default ShaderProgram; + diff --git a/src/shaders/instanced-vert.glsl b/src/shaders/instanced-vert.glsl index 1ee1a92..e6e789b 100644 --- a/src/shaders/instanced-vert.glsl +++ b/src/shaders/instanced-vert.glsl @@ -29,13 +29,16 @@ void main() mat4 TransformMatrix = mat4(vs_Transform1, vs_Transform2, vs_Transform3, vs_Transform4); fs_Nor = TransformMatrix * vs_Nor; - fs_Pos = TransformMatrix * vs_Pos; + vec4 newPos = TransformMatrix * vs_Pos; + fs_Pos = vs_Pos; vec3 offset = vs_Translate; - offset.z = (sin((u_Time + offset.x) * 3.14159 * 0.1) + cos((u_Time + offset.y) * 3.14159 * 0.1)) * 1.5; + //offset.z = (sin((u_Time + offset.x) * 3.14159 * 0.1) + cos((u_Time + offset.y) * 3.14159 * 0.1)) * 1.5; vec3 billboardPos = offset + vs_Pos.x * u_CameraAxes[0] + vs_Pos.y * u_CameraAxes[1]; - gl_Position = u_ViewProj * vec4(vec3(fs_Pos), 1.0); - // gl_Position = u_ViewProj * vec4(billboardPos, 1.0); + gl_Position = u_ViewProj * vec4(vec3(newPos), 1.0); + //gl_Position = u_ViewProj * vec4(billboardPos, 1.0); } + + From adaaad15236a2b8292fe07c180863f3622d8bad3 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sat, 6 Nov 2021 15:54:53 -0400 Subject: [PATCH 08/34] I CAN DRAW MY TREE --- src/geometry/Mesh.ts | 1 - src/l-system/L-System.ts | 321 ++++++++++++++++++-------------- src/l-system/Turtle.ts | 2 +- src/main.ts | 154 ++++++++------- src/shaders/instanced-frag.glsl | 6 +- src/shaders/instanced-vert.glsl | 4 - 6 files changed, 269 insertions(+), 219 deletions(-) diff --git a/src/geometry/Mesh.ts b/src/geometry/Mesh.ts index 07190d6..76d22ca 100644 --- a/src/geometry/Mesh.ts +++ b/src/geometry/Mesh.ts @@ -24,7 +24,6 @@ class Mesh extends Drawable { this.center = vec4.fromValues(center[0], center[1], center[2], 1); this.objString = objString; - console.log("DEBUG: OBJSTRING: " + objString); } create() { diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index e44ea2c..80d97b1 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -2,125 +2,144 @@ import DrawingRule from "./DrawingRule"; import ExpansionRule from "./ExpansionRule"; import Turtle from "./Turtle"; import Mesh from "../geometry/Mesh"; -import {readTextFile} from "../globals" +import { readTextFile } from "../globals"; import { vec3, mat4, quat } from "gl-matrix"; -import OpenGLRenderer from '../rendering/gl/OpenGLRenderer'; +import OpenGLRenderer from "../rendering/gl/OpenGLRenderer"; class LSystem { - turtleStack: Array = []; - turtle : Turtle = new Turtle(vec3.fromValues(0.0, 0.0, 0.0), vec3.fromValues(0.0, 1.0, 0.0)); - drawingRules: Map = new Map(); - expansionRules: Map = new Map(); - seed: string; - axioms : Array = []; - iterations : number = 6; - // Set up instanced rendering data arrays. - branchCols1 : Array = []; - branchCols2 : Array = []; - branchCols3 : Array = []; - branchCols4 : Array = []; - branchColorsBO : Array = []; - - branchNum : number = 0; - leafNum : number = 0; - - // import objs: - branch : Mesh = new Mesh(readTextFile('resources/cylinder.obj'), vec3.fromValues(0, 0, 0)); - - drawBranch : () => void; - setSeed : (s: string) => void; - pushTurtle : () => void; - popTurtle : () => void; - populateExpansionRules : () => void; - populateDrawingRules : () => void; - putBranch : (scale : vec3) => void; - createMeshes : () => void; - drawTree : () => void; - makeTree : () => void; - - constructor() { - this.turtleStack = []; - this.turtle = new Turtle(vec3.fromValues(0.0, 0.0, 0.0), vec3.fromValues(0.0, 1.0, 0.0)); - + turtleStack : Array = []; + turtle : Turtle = new Turtle( + vec3.fromValues(50.0, 50.0, 0.0), + vec3.fromValues(0.0, 1.0, 0.0) + ); + drawingRules : Map = new Map(); + expansionRules : Map = new Map(); + seed : string; + axioms : Array = []; + iterations : number = 1; + // Set up instanced rendering data arrays. + branchCols1 : Array = []; + branchCols2 : Array = []; + branchCols3 : Array = []; + branchCols4 : Array = []; + branchColorsBO : Array = []; + + branchNum: number = 0; + leafNum: number = 0; + + // import objs: + branch: Mesh = new Mesh( + readTextFile("resources/cylinder.obj"), + vec3.fromValues(0, 0, 0) + ); + + drawBranch: () => void; + setSeed: (s: string) => void; + pushTurtle: () => void; + popTurtle: () => void; + populateExpansionRules: () => void; + populateDrawingRules: () => void; + putBranch: (scale: vec3) => void; + createMeshes: () => void; + drawTree: () => void; + expandGrammar: () => void; + makeTree: () => void; + + constructor() { + this.turtleStack = []; + this.turtle = new Turtle( + vec3.fromValues(50.0, 50.0, 0.0), + vec3.fromValues(0.0, 1.0, 0.0) + ); // define functions below to maintain context of "this" - + this.setSeed = (s: string) => { - this.seed = s; - } + this.seed = s; + }; this.pushTurtle = () => { - let newTurtle : Turtle = new Turtle(this.turtle.position, this.turtle.orientation); - this.turtleStack.push(newTurtle); - this.turtle.depth += 1; - } + let newTurtle: Turtle = new Turtle( + this.turtle.position, + this.turtle.orientation + ); + this.turtleStack.push(newTurtle); + this.turtle.depth += 1; + }; this.popTurtle = () => { - let newTurtle : Turtle = this.turtleStack.pop(); - this.turtle.orientation = newTurtle.orientation; - this.turtle.position = newTurtle.position; - this.turtle.depth -= 1; - } + let newTurtle: Turtle = this.turtleStack.pop(); + this.turtle.orientation = newTurtle.orientation; + this.turtle.position = newTurtle.position; + this.turtle.depth -= 1; + }; this.populateExpansionRules = () => { - let rule1 : ExpansionRule = new ExpansionRule(); - rule1.addOutput("FF-[--FF++FF]+[++FF]", 1.0); - this.expansionRules.set("F", rule1); + let rule1: ExpansionRule = new ExpansionRule(); + // rule1.addOutput("FF-[--FF++FF]+[++FF]", 1.0); + rule1.addOutput("FF", 1.0) + this.expansionRules.set("F", rule1); - let rule2: ExpansionRule = new ExpansionRule(); - rule2.addOutput("++[F]", 1.0); - this.expansionRules.set("X", rule2); - } + let rule2: ExpansionRule = new ExpansionRule(); + rule2.addOutput("++[F]", 1.0); + this.expansionRules.set("X", rule2); + console.log("DEBUG: EXPANSION RULES: " + this.expansionRules.size); + }; this.populateDrawingRules = () => { - let pushRule : DrawingRule = new DrawingRule(); - pushRule.addOutput(this.pushTurtle, 1.0); - this.drawingRules.set('[', pushRule); - - let popRule : DrawingRule = new DrawingRule(); - popRule.addOutput(this.popTurtle, 1.0); - this.drawingRules.set(']', popRule); - - let rotateLeftXRule : DrawingRule = new DrawingRule(); - rotateLeftXRule.addOutput(this.turtle.rotateLeftX, 1.0); - this.drawingRules.set('+', rotateLeftXRule); - - let rotateRightXRule : DrawingRule = new DrawingRule(); - rotateRightXRule.addOutput(this.turtle.rotateRightX, 1.0); - this.drawingRules.set('-', rotateRightXRule); - - let forwardRule : DrawingRule = new DrawingRule(); - forwardRule.addOutput(this.drawBranch, 1.0); - this.drawingRules.set('F', forwardRule); - - - } + let pushRule: DrawingRule = new DrawingRule(); + pushRule.addOutput(this.pushTurtle, 1.0); + this.drawingRules.set("[", pushRule); + + let popRule: DrawingRule = new DrawingRule(); + popRule.addOutput(this.popTurtle, 1.0); + this.drawingRules.set("]", popRule); + + let rotateLeftXRule: DrawingRule = new DrawingRule(); + rotateLeftXRule.addOutput(this.turtle.rotateLeftX, 1.0); + this.drawingRules.set("+", rotateLeftXRule); + + let rotateRightXRule: DrawingRule = new DrawingRule(); + rotateRightXRule.addOutput(this.turtle.rotateRightX, 1.0); + this.drawingRules.set("-", rotateRightXRule); + + let forwardRule: DrawingRule = new DrawingRule(); + forwardRule.addOutput(this.drawBranch, 1.0); + this.drawingRules.set("F", forwardRule); + + console.log("DEBUG: DRAWING RULES: " + this.drawingRules.get); + }; + + this.putBranch = (scale: vec3) => { + // Calculate transformation + let transform: mat4 = mat4.create(); + let q: quat = quat.create(); + quat.rotationTo(q, vec3.fromValues(0, 1, 0), this.turtle.orientation); + mat4.fromRotationTranslationScale( + transform, + q, + this.turtle.position, + scale + ); + console.log("DEBUG: PUTBRANCH TRANSFORM: " + transform); + for (let i = 0; i < 4; i++) { + this.branchCols1.push(transform[i]); + this.branchCols2.push(transform[4 + i]); + this.branchCols3.push(transform[8 + i]); + this.branchCols4.push(transform[12 + i]); + } + console.log("DEBUG: PUTBRANCH COL1: " + this.branchCols1); - this.putBranch = (scale : vec3) => { - // Calculate transformation - let transform : mat4 = mat4.create(); - let q : quat = quat.create(); - quat.rotationTo(q, vec3.fromValues(0, 1, 0), this.turtle.orientation); - mat4.fromRotationTranslationScale(transform, q, this.turtle.position, scale); - for(let i = 0; i < 4; i++) { - this.branchCols1.push(transform[i]); - this.branchCols2.push(transform[4 + i]); - this.branchCols3.push(transform[8 + i]); - this.branchCols4.push(transform[12 + i]); - } - - this.branchColorsBO.push(13. / 255.); - this.branchColorsBO.push(91. / 255.); - this.branchColorsBO.push(80. / 255.); - this.branchColorsBO.push(1.0); - this.branchNum++; - } - - + this.branchColorsBO.push(13 / 255); + this.branchColorsBO.push(91 / 255); + this.branchColorsBO.push(80 / 255); + this.branchColorsBO.push(1.0); + this.branchNum++; + }; - this.createMeshes = () => { - this.branch.create(); - } + this.createMeshes = () => { + this.branch.create(); + }; this.drawTree = () => { // reset everything @@ -131,61 +150,79 @@ class LSystem { this.branchCols3 = []; this.branchCols4 = []; this.branchColorsBO = []; + this.branch.destroy(); + this.branch.create(); // Draw based on grammar - for(let i = 0; i < this.axioms[this.iterations].length; i++) { - let func = this.drawingRules.get(this.axioms[this.iterations].charAt(i)).getOutput(); - if(func) { + let count = 0; + for (let i = 0; i < this.axioms[this.iterations].length; i++) { + console.log("DEBUG: THIS DRAWING RULE CHARACTER: " + (this.axioms[this.iterations].charAt(i))); + let func = this.drawingRules + .get(this.axioms[this.iterations].charAt(i)) + .getOutput(); + if (func) { func(); + count++; } } + console.log("DEBUG: NUM FUNCTIONS CALLED: " + count); + + console.log("DEBUG: BRANCH COL1: " + this.branchCols1); + console.log("DEBUG: BRANCH COLors: " + this.branchColorsBO); - let bCol1: Float32Array = new Float32Array(this.branchCols1); let bCol2: Float32Array = new Float32Array(this.branchCols2); let bCol3: Float32Array = new Float32Array(this.branchCols3); let bCol4: Float32Array = new Float32Array(this.branchCols4); let bcolors: Float32Array = new Float32Array(this.branchColorsBO); - this.branch.create(); - // this.branch.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); + this.branch.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); this.branch.setNumInstances(this.branchNum); + }; + + this.expandGrammar = () => { + let currExpansion = this.seed; + // expanding the grammar + for (let i = 0; i < this.iterations; i++) { + let expandedString: string = ""; + for (let j = 0; j < currExpansion.length; j++) { + let currRule = this.expansionRules.get(currExpansion.charAt(j)); + if (currRule) { + expandedString += currRule.getOutput(); + } else { + expandedString += currExpansion.charAt(j); + } + } + currExpansion = expandedString; + this.axioms.push(expandedString); + } + console.log("DEBUG: FINAL GRAMMAR: " + this.axioms[this.iterations]); } - this.makeTree = () => { - this.setSeed("FX"); - this.axioms = [this.seed]; - - this.populateExpansionRules(); - this.populateDrawingRules(); - - let currExpansion = this.seed; - // expanding the grammar - for (let i = 0; i < 6; i++) { - let expandedString : string = ""; - for (let j = 0; j < currExpansion.length; j++) { - let currRule = this.expansionRules.get(currExpansion.charAt(j)); - if (currRule) { - expandedString += currRule.getOutput(); - } else { - expandedString += currExpansion.charAt(j); - } - } - currExpansion = expandedString; - this.axioms.push(expandedString); - } - this.drawTree(); + this.makeTree = () => { + this.setSeed("FX"); + this.axioms = [this.seed]; - } - - this.drawBranch = () => { - this.turtle.moveForward(); - this.putBranch(vec3.fromValues(0.25 - this.turtle.depth * 0.05, 0.25, - 0.25 - this.turtle.depth * 0.05)); - } - - } + this.populateExpansionRules(); + this.populateDrawingRules(); + console.log(" DRAWING RULES POPULATED"); + this.expandGrammar(); -}; + this.drawTree(); + }; -export default LSystem; \ No newline at end of file + this.drawBranch = () => { + this.turtle.moveForward(); + console.log("DEBUG: DRAWBRANCH CALLED"); + this.putBranch( + vec3.fromValues( + 0.5 - this.turtle.depth * 0.05, + 3.5, + 0.5 - this.turtle.depth * 0.05 + ) + ); + }; + } +} + +export default LSystem; diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index c77f710..850547a 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -31,7 +31,7 @@ class Turtle { // rotate at a random angle reset() { - this.position = vec3.fromValues(0.0, 0.0, 0.0); + this.position = vec3.fromValues(50.0, 50.0, 0.0); this.orientation = vec3.fromValues(0.0, 1.0, 0.0); this.depth = 0; } diff --git a/src/main.ts b/src/main.ts index 0a0a0c3..f0820ee 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,59 +1,63 @@ -import {vec3, mat4} from 'gl-matrix'; -import * as Stats from 'stats-js'; -import * as DAT from 'dat-gui'; -import Square from './geometry/Square'; -import ScreenQuad from './geometry/ScreenQuad'; -import OpenGLRenderer from './rendering/gl/OpenGLRenderer'; -import Camera from './Camera'; -import {setGL} from './globals'; -import ShaderProgram, {Shader} from './rendering/gl/ShaderProgram'; -import Mesh from './geometry/Mesh'; -import {readTextFile} from '../src/globals' - +import { vec3, mat4 } from "gl-matrix"; +import * as Stats from "stats-js"; +import * as DAT from "dat-gui"; +import Square from "./geometry/Square"; +import ScreenQuad from "./geometry/ScreenQuad"; +import OpenGLRenderer from "./rendering/gl/OpenGLRenderer"; +import Camera from "./Camera"; +import { setGL } from "./globals"; +import ShaderProgram, { Shader } from "./rendering/gl/ShaderProgram"; +import Mesh from "./geometry/Mesh"; +import LSystem from './l-system/L-System' +import { readTextFile } from "../src/globals"; // 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 = { -}; +const controls = {}; let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; let branch: Mesh; -let matrix : mat4 = mat4.create(); +let matrix: mat4 = mat4.create(); +let coral : LSystem = new LSystem(); function loadScene() { + coral.makeTree(); + console.log("DEBUG CORAL BRANCHES: " + coral.branchCols1); + square = new Square(); square.create(); screenQuad = new ScreenQuad(); screenQuad.create(); - branch = new Mesh(readTextFile('resources/cylinder.obj'), vec3.fromValues(0, 0, 0)); + branch = new Mesh( + readTextFile("resources/cylinder.obj"), + vec3.fromValues(0, 0, 0) + ); branch.create(); - let colorsArrayBranch = []; - - - let cols1ArrayBranch = []; + let colorsArrayBranch = []; + let cols1ArrayBranch = []; cols1ArrayBranch.push(5.0); cols1ArrayBranch.push(0.0); cols1ArrayBranch.push(0.0); cols1ArrayBranch.push(0.0); let cols2ArrayBranch = []; - cols2ArrayBranch.push(0.0); - cols2ArrayBranch.push(5.0); + cols2ArrayBranch.push(0.0); + cols2ArrayBranch.push(5.0); cols2ArrayBranch.push(0.0); cols2ArrayBranch.push(0.0); let cols3ArrayBranch = []; - cols3ArrayBranch.push(0.0); - cols3ArrayBranch.push(0.0); + cols3ArrayBranch.push(0.0); + cols3ArrayBranch.push(0.0); cols3ArrayBranch.push(5.0); cols3ArrayBranch.push(0.0); let cols4ArrayBranch = []; - cols4ArrayBranch.push(50.0); - cols4ArrayBranch.push(50.0); + cols4ArrayBranch.push(50.0); + cols4ArrayBranch.push(50.0); cols4ArrayBranch.push(0.0); cols4ArrayBranch.push(1.0); @@ -62,14 +66,20 @@ function loadScene() { colorsArrayBranch.push(1.0); colorsArrayBranch.push(1.0); - let t1: Float32Array = new Float32Array(cols1ArrayBranch); - let t2: Float32Array = new Float32Array(cols2ArrayBranch); - let t3: Float32Array = new Float32Array(cols3ArrayBranch); - let t4: Float32Array = new Float32Array(cols4ArrayBranch); - let branchColors: Float32Array = new Float32Array(colorsArrayBranch); - branch.setInstanceVBOs(t1, t2, t3, t4, branchColors); - branch.setNumInstances(1); - + // let t1: Float32Array = new Float32Array(cols1ArrayBranch); + // let t2: Float32Array = new Float32Array(cols2ArrayBranch); + // let t3: Float32Array = new Float32Array(cols3ArrayBranch); + // let t4: Float32Array = new Float32Array(cols4ArrayBranch); + // let branchColors: Float32Array = new Float32Array(colorsArrayBranch); + // branch.setInstanceVBOs(t1, t2, t3, t4, branchColors); + // branch.setNumInstances(1); + let t1: Float32Array = new Float32Array(coral.branchCols1); + let t2: Float32Array = new Float32Array(coral.branchCols2); + let t3: Float32Array = new Float32Array(coral.branchCols3); + let t4: Float32Array = new Float32Array(coral.branchCols4); + let branchColors: Float32Array = new Float32Array(coral.branchColorsBO); + // coral.branch.setInstanceVBOs(t1, t2, t3, t4, branchColors); + //coral.branch.setNumInstances(3); // Set up instanced rendering data arrays here. // This example creates a set of positional @@ -84,20 +94,16 @@ function loadScene() { let sCol3 = []; let sCol4 = []; - for(let i = 0; i < n; i++) { - for(let j = 0; j < n; j++) { + for (let i = 0; i < n; i++) { + for (let j = 0; j < n; j++) { mat4.translate(matrix, matrix, vec3.fromValues(i, j, 0)); //mat4.scale(matrix, matrix, vec3.fromValues(5.0, 5.0, 5.0)); - for (let k : number = 0; k < 4; k++) { + for (let k: number = 0; k < 4; k++) { sCol1.push(matrix[k]); sCol2.push(matrix[k + 4]); sCol3.push(matrix[k + 8]); sCol4.push(matrix[k + 12]); } - - offsetsArray.push(i); - offsetsArray.push(j); - offsetsArray.push(0); colorsArray.push(j / i); colorsArray.push(j / i); @@ -106,18 +112,20 @@ function loadScene() { mat4.identity(matrix); } } - let offsets: Float32Array = new Float32Array(offsetsArray); - - let offsetsCol1 : Float32Array = new Float32Array(sCol1); - let offsetsCol2 : Float32Array = new Float32Array(sCol2); - let offsetsCol3 : Float32Array = new Float32Array(sCol3); - let offsetsCol4 : Float32Array = new Float32Array(sCol4); + let offsetsCol1: Float32Array = new Float32Array(sCol1); + let offsetsCol2: Float32Array = new Float32Array(sCol2); + let offsetsCol3: Float32Array = new Float32Array(sCol3); + let offsetsCol4: Float32Array = new Float32Array(sCol4); let colors: Float32Array = new Float32Array(colorsArray); - square.setInstanceTransformVBOs(offsetsCol1, offsetsCol2, offsetsCol3, offsetsCol4, colors); - console.log("DEBUG: OFFSETS: " + offsetsCol1); - //square.setInstanceVBOs(offsets, colors); + square.setInstanceTransformVBOs( + offsetsCol1, + offsetsCol2, + offsetsCol3, + offsetsCol4, + colors + ); square.setNumInstances(n * n); // grid of "particles" } @@ -125,19 +133,19 @@ function main() { // Initial display for framerate const stats = Stats(); stats.setMode(0); - stats.domElement.style.position = 'absolute'; - stats.domElement.style.left = '0px'; - stats.domElement.style.top = '0px'; + stats.domElement.style.position = "absolute"; + stats.domElement.style.left = "0px"; + stats.domElement.style.top = "0px"; document.body.appendChild(stats.domElement); // Add controls to the gui const gui = new DAT.GUI(); // get canvas and webgl context - const canvas = document.getElementById('canvas'); - const gl = canvas.getContext('webgl2'); + const canvas = document.getElementById("canvas"); + const gl = canvas.getContext("webgl2"); if (!gl) { - alert('WebGL 2 not supported!'); + alert("WebGL 2 not supported!"); } // `setGL` is a function imported above which sets the value of `gl` in the `globals.ts` module. // Later, we can import `gl` from `globals.ts` to access it @@ -146,7 +154,10 @@ function main() { // Initial call to load scene loadScene(); - const camera = new Camera(vec3.fromValues(5, 5, 10), vec3.fromValues(50, 50, 0)); + const camera = new Camera( + vec3.fromValues(5, 5, 10), + vec3.fromValues(50, 50, 0) + ); const renderer = new OpenGLRenderer(canvas); renderer.setClearColor(0.2, 0.2, 0.2, 1); @@ -154,13 +165,13 @@ function main() { gl.blendFunc(gl.ONE, gl.ONE); // Additive blending const instancedShader = new ShaderProgram([ - new Shader(gl.VERTEX_SHADER, require('./shaders/instanced-vert.glsl')), - new Shader(gl.FRAGMENT_SHADER, require('./shaders/instanced-frag.glsl')), + new Shader(gl.VERTEX_SHADER, require("./shaders/instanced-vert.glsl")), + new Shader(gl.FRAGMENT_SHADER, require("./shaders/instanced-frag.glsl")), ]); const flat = new ShaderProgram([ - new Shader(gl.VERTEX_SHADER, require('./shaders/flat-vert.glsl')), - new Shader(gl.FRAGMENT_SHADER, require('./shaders/flat-frag.glsl')), + new Shader(gl.VERTEX_SHADER, require("./shaders/flat-vert.glsl")), + new Shader(gl.FRAGMENT_SHADER, require("./shaders/flat-frag.glsl")), ]); // This function will be called every frame @@ -173,8 +184,9 @@ function main() { renderer.clear(); renderer.render(camera, flat, [screenQuad]); renderer.render(camera, instancedShader, [ - square, - // branch + // square, + // branch, + coral.branch ]); stats.end(); @@ -182,12 +194,16 @@ function main() { requestAnimationFrame(tick); } - window.addEventListener('resize', function() { - renderer.setSize(window.innerWidth, window.innerHeight); - camera.setAspectRatio(window.innerWidth / window.innerHeight); - camera.updateProjectionMatrix(); - flat.setDimensions(window.innerWidth, window.innerHeight); - }, false); + window.addEventListener( + "resize", + function () { + renderer.setSize(window.innerWidth, window.innerHeight); + camera.setAspectRatio(window.innerWidth / window.innerHeight); + camera.updateProjectionMatrix(); + flat.setDimensions(window.innerWidth, window.innerHeight); + }, + false + ); renderer.setSize(window.innerWidth, window.innerHeight); camera.setAspectRatio(window.innerWidth / window.innerHeight); diff --git a/src/shaders/instanced-frag.glsl b/src/shaders/instanced-frag.glsl index 72e7460..049e9d3 100644 --- a/src/shaders/instanced-frag.glsl +++ b/src/shaders/instanced-frag.glsl @@ -8,6 +8,8 @@ out vec4 out_Col; void main() { - float dist = 1.0 - (length(fs_Pos.xyz) * 2.0); - out_Col = vec4(dist) * fs_Col; + // for falloff: + // float dist = 1.0 - (length(fs_Pos.xyz) * 2.0); + // out_Col = vec4(dist) * fs_Col; + out_Col = fs_Col; } diff --git a/src/shaders/instanced-vert.glsl b/src/shaders/instanced-vert.glsl index e6e789b..1b77b54 100644 --- a/src/shaders/instanced-vert.glsl +++ b/src/shaders/instanced-vert.glsl @@ -30,15 +30,11 @@ void main() mat4 TransformMatrix = mat4(vs_Transform1, vs_Transform2, vs_Transform3, vs_Transform4); fs_Nor = TransformMatrix * vs_Nor; vec4 newPos = TransformMatrix * vs_Pos; - fs_Pos = vs_Pos; vec3 offset = vs_Translate; - //offset.z = (sin((u_Time + offset.x) * 3.14159 * 0.1) + cos((u_Time + offset.y) * 3.14159 * 0.1)) * 1.5; - vec3 billboardPos = offset + vs_Pos.x * u_CameraAxes[0] + vs_Pos.y * u_CameraAxes[1]; gl_Position = u_ViewProj * vec4(vec3(newPos), 1.0); - //gl_Position = u_ViewProj * vec4(billboardPos, 1.0); } From b1a855c64da6d388e798afcbad40bbc1550744d2 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sat, 6 Nov 2021 18:40:32 -0400 Subject: [PATCH 09/34] adding infrastructure for multiple rotation angles --- src/l-system/L-System.ts | 28 +++++--------- src/l-system/Turtle.ts | 80 +++++++++++++++++++--------------------- 2 files changed, 48 insertions(+), 60 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index 80d97b1..b7f4b86 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -3,20 +3,20 @@ import ExpansionRule from "./ExpansionRule"; import Turtle from "./Turtle"; import Mesh from "../geometry/Mesh"; import { readTextFile } from "../globals"; -import { vec3, mat4, quat } from "gl-matrix"; +import { vec3, mat4, quat, mat3 } from "gl-matrix"; import OpenGLRenderer from "../rendering/gl/OpenGLRenderer"; class LSystem { turtleStack : Array = []; turtle : Turtle = new Turtle( vec3.fromValues(50.0, 50.0, 0.0), - vec3.fromValues(0.0, 1.0, 0.0) + mat3.create() ); drawingRules : Map = new Map(); expansionRules : Map = new Map(); seed : string; axioms : Array = []; - iterations : number = 1; + iterations : number = 2; // Set up instanced rendering data arrays. branchCols1 : Array = []; branchCols2 : Array = []; @@ -49,8 +49,8 @@ class LSystem { this.turtleStack = []; this.turtle = new Turtle( vec3.fromValues(50.0, 50.0, 0.0), - vec3.fromValues(0.0, 1.0, 0.0) - ); + mat3.create() + ); // define functions below to maintain context of "this" @@ -76,8 +76,7 @@ class LSystem { this.populateExpansionRules = () => { let rule1: ExpansionRule = new ExpansionRule(); - // rule1.addOutput("FF-[--FF++FF]+[++FF]", 1.0); - rule1.addOutput("FF", 1.0) + rule1.addOutput("FF-[--FF++FF]+[++FF]", 1.0); this.expansionRules.set("F", rule1); let rule2: ExpansionRule = new ExpansionRule(); @@ -95,6 +94,7 @@ class LSystem { popRule.addOutput(this.popTurtle, 1.0); this.drawingRules.set("]", popRule); + // TODO: Replace these to use appropriate rotation function let rotateLeftXRule: DrawingRule = new DrawingRule(); rotateLeftXRule.addOutput(this.turtle.rotateLeftX, 1.0); this.drawingRules.set("+", rotateLeftXRule); @@ -114,7 +114,7 @@ class LSystem { // Calculate transformation let transform: mat4 = mat4.create(); let q: quat = quat.create(); - quat.rotationTo(q, vec3.fromValues(0, 1, 0), this.turtle.orientation); + quat.fromMat3(q, this.turtle.orientation); mat4.fromRotationTranslationScale( transform, q, @@ -156,7 +156,6 @@ class LSystem { // Draw based on grammar let count = 0; for (let i = 0; i < this.axioms[this.iterations].length; i++) { - console.log("DEBUG: THIS DRAWING RULE CHARACTER: " + (this.axioms[this.iterations].charAt(i))); let func = this.drawingRules .get(this.axioms[this.iterations].charAt(i)) .getOutput(); @@ -165,10 +164,6 @@ class LSystem { count++; } } - console.log("DEBUG: NUM FUNCTIONS CALLED: " + count); - - console.log("DEBUG: BRANCH COL1: " + this.branchCols1); - console.log("DEBUG: BRANCH COLors: " + this.branchColorsBO); let bCol1: Float32Array = new Float32Array(this.branchCols1); let bCol2: Float32Array = new Float32Array(this.branchCols2); @@ -195,7 +190,6 @@ class LSystem { currExpansion = expandedString; this.axioms.push(expandedString); } - console.log("DEBUG: FINAL GRAMMAR: " + this.axioms[this.iterations]); } this.makeTree = () => { @@ -204,7 +198,6 @@ class LSystem { this.populateExpansionRules(); this.populateDrawingRules(); - console.log(" DRAWING RULES POPULATED"); this.expandGrammar(); @@ -213,12 +206,11 @@ class LSystem { this.drawBranch = () => { this.turtle.moveForward(); - console.log("DEBUG: DRAWBRANCH CALLED"); this.putBranch( vec3.fromValues( - 0.5 - this.turtle.depth * 0.05, + 1.5 - this.turtle.depth * 0.05, 3.5, - 0.5 - this.turtle.depth * 0.05 + 1.5 - this.turtle.depth * 0.05 ) ); }; diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index 850547a..a3f64b1 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -1,62 +1,58 @@ -import {vec3} from 'gl-matrix'; +import { mat3, vec3, quat } from "gl-matrix"; // vec3 operations from: https://glmatrix.net/docs/module-vec3.html class Turtle { position: vec3 = vec3.fromValues(0.0, 0.0, 0.0); - orientation: vec3 = vec3.fromValues(0.0, 1.0, 0.0); + orientation: mat3 = mat3.create(); depth: number = 0; - moveForward : () => void; - rotateRightX : () => void; - rotateLeftX : () => void; + getForward: () => vec3; + moveForward: () => void; + rotateRightX: () => void; + rotateLeftX: () => void; + rotate: (axis: vec3, angle: number) => void; - - constructor(pos: vec3, orient: vec3) { + constructor(pos: vec3, orient: mat3) { this.position = pos; this.orientation = orient; this.depth = 0; - - this.moveForward = () => { - vec3.add(this.position, this.position, vec3.scale(vec3.create(), this.orientation, 10.0)); - } - this.rotateRightX = () => { - vec3.rotateX(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), -0.35); - } - this.rotateLeftX = () => { - vec3.rotateX(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), 0.35); - } - } - // rotate at a random angle + this.getForward = () => { + return vec3.fromValues( + this.orientation[3], + this.orientation[4], + this.orientation[5] + ); + }; - reset() { - this.position = vec3.fromValues(50.0, 50.0, 0.0); - this.orientation = vec3.fromValues(0.0, 1.0, 0.0); - this.depth = 0; - } - - - - - rotateLeftY() { - vec3.rotateY(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), 0.35); - } + this.moveForward = () => { + vec3.add( + this.position, + this.position, + vec3.scale(vec3.create(), this.getForward(), 10.0) + ); + }; - rotateLeftZ() { - vec3.rotateZ(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), 0.35); - } + this.rotate = (axis: vec3, angle: number) => { + vec3.normalize(axis, axis); + let radians = (3.14159 * angle) / 180.0; - + let q: quat = quat.create(); + quat.setAxisAngle(q, axis, radians); + quat.normalize(q, q); - rotateRightY() { - vec3.rotateY(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), -0.35); + let m: mat3 = mat3.create(); + mat3.fromQuat(m, q); + mat3.multiply(this.orientation, m, this.orientation); + }; } - rotateRightZ() { - vec3.rotateZ(this.orientation, this.orientation, vec3.fromValues(0.0, 0.0, 0.0), -0.35); + reset() { + this.position = vec3.fromValues(50.0, 50.0, 0.0); + this.orientation = mat3.identity(this.orientation); + this.depth = 0; } +} -}; - -export default Turtle; \ No newline at end of file +export default Turtle; From f4ac3ed6c517331cc71ac6d944e96e8a3f9a4240 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sat, 6 Nov 2021 20:11:51 -0400 Subject: [PATCH 10/34] Tree draws properly in 2D --- src/l-system/L-System.ts | 57 ++++++++++++++++++---------------------- src/l-system/Turtle.ts | 17 ++++++++++++ 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index b7f4b86..f04ab45 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -7,22 +7,19 @@ import { vec3, mat4, quat, mat3 } from "gl-matrix"; import OpenGLRenderer from "../rendering/gl/OpenGLRenderer"; class LSystem { - turtleStack : Array = []; - turtle : Turtle = new Turtle( - vec3.fromValues(50.0, 50.0, 0.0), - mat3.create() - ); - drawingRules : Map = new Map(); - expansionRules : Map = new Map(); - seed : string; - axioms : Array = []; - iterations : number = 2; + turtleStack: Array = []; + turtle: Turtle = new Turtle(vec3.fromValues(50.0, 50.0, 0.0), mat3.create()); + drawingRules: Map = new Map(); + expansionRules: Map = new Map(); + seed: string; + axioms: Array = []; + iterations: number = 2; // Set up instanced rendering data arrays. - branchCols1 : Array = []; - branchCols2 : Array = []; - branchCols3 : Array = []; - branchCols4 : Array = []; - branchColorsBO : Array = []; + branchCols1: Array = []; + branchCols2: Array = []; + branchCols3: Array = []; + branchCols4: Array = []; + branchColorsBO: Array = []; branchNum: number = 0; leafNum: number = 0; @@ -47,10 +44,7 @@ class LSystem { constructor() { this.turtleStack = []; - this.turtle = new Turtle( - vec3.fromValues(50.0, 50.0, 0.0), - mat3.create() - ); + this.turtle = new Turtle(vec3.fromValues(50.0, 50.0, 0.0), mat3.create()); // define functions below to maintain context of "this" @@ -59,19 +53,25 @@ class LSystem { }; this.pushTurtle = () => { + let newPos : vec3 = vec3.create(); + let newOrient : mat3 = mat3.create(); let newTurtle: Turtle = new Turtle( - this.turtle.position, - this.turtle.orientation + vec3.copy(newPos, this.turtle.position), + mat3.copy(newOrient, this.turtle.orientation) ); + let newDepth : number = this.turtle.depth; + newTurtle.depth = newDepth; this.turtleStack.push(newTurtle); this.turtle.depth += 1; }; this.popTurtle = () => { - let newTurtle: Turtle = this.turtleStack.pop(); - this.turtle.orientation = newTurtle.orientation; - this.turtle.position = newTurtle.position; - this.turtle.depth -= 1; + if (this.turtle.depth > 0) { + let newTurtle: Turtle = this.turtleStack.pop(); + this.turtle.orientation = mat3.copy(mat3.create(), newTurtle.orientation); + this.turtle.position = vec3.copy(vec3.create(), newTurtle.position); + this.turtle.depth -= 1; + } }; this.populateExpansionRules = () => { @@ -82,7 +82,6 @@ class LSystem { let rule2: ExpansionRule = new ExpansionRule(); rule2.addOutput("++[F]", 1.0); this.expansionRules.set("X", rule2); - console.log("DEBUG: EXPANSION RULES: " + this.expansionRules.size); }; this.populateDrawingRules = () => { @@ -94,7 +93,6 @@ class LSystem { popRule.addOutput(this.popTurtle, 1.0); this.drawingRules.set("]", popRule); - // TODO: Replace these to use appropriate rotation function let rotateLeftXRule: DrawingRule = new DrawingRule(); rotateLeftXRule.addOutput(this.turtle.rotateLeftX, 1.0); this.drawingRules.set("+", rotateLeftXRule); @@ -107,7 +105,6 @@ class LSystem { forwardRule.addOutput(this.drawBranch, 1.0); this.drawingRules.set("F", forwardRule); - console.log("DEBUG: DRAWING RULES: " + this.drawingRules.get); }; this.putBranch = (scale: vec3) => { @@ -121,14 +118,12 @@ class LSystem { this.turtle.position, scale ); - console.log("DEBUG: PUTBRANCH TRANSFORM: " + transform); for (let i = 0; i < 4; i++) { this.branchCols1.push(transform[i]); this.branchCols2.push(transform[4 + i]); this.branchCols3.push(transform[8 + i]); this.branchCols4.push(transform[12 + i]); } - console.log("DEBUG: PUTBRANCH COL1: " + this.branchCols1); this.branchColorsBO.push(13 / 255); this.branchColorsBO.push(91 / 255); @@ -190,7 +185,7 @@ class LSystem { currExpansion = expandedString; this.axioms.push(expandedString); } - } + }; this.makeTree = () => { this.setSeed("FX"); diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index a3f64b1..62e9e73 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -8,6 +8,8 @@ class Turtle { depth: number = 0; getForward: () => vec3; + getRight: () => vec3; + getUp: () => vec3; moveForward: () => void; rotateRightX: () => void; rotateLeftX: () => void; @@ -26,6 +28,13 @@ class Turtle { ); }; + this.getRight = () => { + return vec3.fromValues(this.orientation[6], this.orientation[7], this.orientation[8]); + } + this.getUp = () => { + return vec3.fromValues(this.orientation[0], this.orientation[1], this.orientation[2]); + } + this.moveForward = () => { vec3.add( this.position, @@ -46,6 +55,14 @@ class Turtle { mat3.fromQuat(m, q); mat3.multiply(this.orientation, m, this.orientation); }; + + this.rotateRightX = () => { + this.rotate(this.getUp(), -15); + } + + this.rotateLeftX = () => { + this.rotate(this.getUp(), 15); + } } reset() { From bb1474ca6d20807f9c1b00ff06d2c9c26b7f51c3 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sat, 6 Nov 2021 20:38:41 -0400 Subject: [PATCH 11/34] Incorporating some 3D elements --- src/l-system/L-System.ts | 26 +++++++++++++++++++++----- src/l-system/Turtle.ts | 5 +++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index f04ab45..328706e 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -76,15 +76,15 @@ class LSystem { this.populateExpansionRules = () => { let rule1: ExpansionRule = new ExpansionRule(); - rule1.addOutput("FF-[--FF++FF]+[++FF]", 1.0); + rule1.addOutput("FF-[-/-/FF+*+*F^F]+[+/+F/^F]", 1.0); // * is the same as \ in houdini here this.expansionRules.set("F", rule1); let rule2: ExpansionRule = new ExpansionRule(); - rule2.addOutput("++[F]", 1.0); + rule2.addOutput("++//&&[F]", 1.0); this.expansionRules.set("X", rule2); }; - this.populateDrawingRules = () => { + this.populateDrawingRules = () => { let pushRule: DrawingRule = new DrawingRule(); pushRule.addOutput(this.pushTurtle, 1.0); this.drawingRules.set("[", pushRule); @@ -101,6 +101,22 @@ class LSystem { rotateRightXRule.addOutput(this.turtle.rotateRightX, 1.0); this.drawingRules.set("-", rotateRightXRule); + let rotatePosYRule: DrawingRule = new DrawingRule(); + rotatePosYRule.addOutput(this.turtle.rotatePosY, 1.0); + this.drawingRules.set("*", rotatePosYRule); + + let rotateNegYRule: DrawingRule = new DrawingRule(); + rotateNegYRule.addOutput(this.turtle.rotateNegY, 1.0); + this.drawingRules.set("/", rotateNegYRule); + + let rotatePosZRule: DrawingRule = new DrawingRule(); + rotatePosZRule.addOutput(this.turtle.rotatePosZ, 1.0); + this.drawingRules.set("&", rotatePosZRule); + + let rotateNegZRule: DrawingRule = new DrawingRule(); + rotateNegZRule.addOutput(this.turtle.rotateNegZ, 1.0); + this.drawingRules.set("^", rotateNegZRule); + let forwardRule: DrawingRule = new DrawingRule(); forwardRule.addOutput(this.drawBranch, 1.0); this.drawingRules.set("F", forwardRule); @@ -125,8 +141,8 @@ class LSystem { this.branchCols4.push(transform[12 + i]); } - this.branchColorsBO.push(13 / 255); - this.branchColorsBO.push(91 / 255); + this.branchColorsBO.push(255 / 255); + this.branchColorsBO.push(127 / 255); this.branchColorsBO.push(80 / 255); this.branchColorsBO.push(1.0); this.branchNum++; diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index 62e9e73..f2b8cc7 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -13,6 +13,11 @@ class Turtle { moveForward: () => void; rotateRightX: () => void; rotateLeftX: () => void; + // TODO: IMPLEMENT THESE TO MATCH NEW ROTATION AXES + rotatePosY: () => void; + rotateNegY: () => void; + rotatePosZ: () => void; + rotateNegZ: () => void; rotate: (axis: vec3, angle: number) => void; constructor(pos: vec3, orient: mat3) { From bd3e27d6a46abe0e899e08a8af80053151d06c0b Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sat, 6 Nov 2021 23:46:15 -0400 Subject: [PATCH 12/34] Tree grows in 3D --- src/l-system/Turtle.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index f2b8cc7..325fa5b 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -68,6 +68,22 @@ class Turtle { this.rotateLeftX = () => { this.rotate(this.getUp(), 15); } + + this.rotatePosY = () => { + this.rotate(this.getForward(), 15); + } + + this.rotateNegY = () => { + this.rotate(this.getForward(), -15); + } + + this.rotatePosZ = () => { + this.rotate(this.getRight(), 15); + } + + this.rotateNegZ = () => { + this.rotate(this.getRight(), -15); + } } reset() { From 552201573c21b1c8b1f5670add07baa8ed09ca1b Mon Sep 17 00:00:00 2001 From: Serena Gandhi <60444726+gserena01@users.noreply.github.com> Date: Sun, 7 Nov 2021 00:00:47 -0400 Subject: [PATCH 13/34] Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 32109b5..32d739f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,11 @@ ![Screenshot 2021-10-20 200324](https://user-images.githubusercontent.com/60444726/138274074-d694a82b-69f7-44e3-a6fc-c970d17ae49c.png) +# Reference Images: + +![image](https://user-images.githubusercontent.com/60444726/140631834-e2863c3f-1e70-4da8-9daa-1c8201c916e9.png) + + # Homework 4: L-systems For this assignment, you will design a set of formal grammar rules to create From 1f4bf6090b62afbf1d3191da639b756d7a5336fb Mon Sep 17 00:00:00 2001 From: Serena Gandhi <60444726+gserena01@users.noreply.github.com> Date: Sun, 7 Nov 2021 00:01:26 -0400 Subject: [PATCH 14/34] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 32d739f..70daf09 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ ![image](https://user-images.githubusercontent.com/60444726/140631834-e2863c3f-1e70-4da8-9daa-1c8201c916e9.png) +![image](https://user-images.githubusercontent.com/60444726/140631851-8845bd07-5ccd-40ed-b130-9c029304b2e5.png) + +![image](https://user-images.githubusercontent.com/60444726/140631854-348ce9c7-f722-4cbc-8ce8-d105a5965d84.png) + # Homework 4: L-systems From 5799ea4924493982a5b1820b189461273dad6667 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sun, 7 Nov 2021 00:53:35 -0400 Subject: [PATCH 15/34] Render a single sphere --- resources/sphere.mtl | 10 + resources/sphere.obj | 527 +++++++++++++++++++++++++++++++++++++++ src/l-system/L-System.ts | 27 +- src/l-system/Turtle.ts | 29 ++- src/main.ts | 27 +- 5 files changed, 586 insertions(+), 34 deletions(-) create mode 100644 resources/sphere.mtl create mode 100644 resources/sphere.obj diff --git a/resources/sphere.mtl b/resources/sphere.mtl new file mode 100644 index 0000000..f231bdf --- /dev/null +++ b/resources/sphere.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/resources/sphere.obj b/resources/sphere.obj new file mode 100644 index 0000000..23173ba --- /dev/null +++ b/resources/sphere.obj @@ -0,0 +1,527 @@ +# Blender v2.83.0 OBJ File: '' +# www.blender.org +mtllib sphere.mtl +o Sphere +v 0.000000 0.353553 -0.353553 +v 0.000000 0.191342 -0.461940 +v 0.000000 -0.191342 -0.461940 +v 0.000000 -0.461940 -0.191342 +v 0.073223 0.461940 -0.176777 +v 0.135299 0.353553 -0.326641 +v 0.176777 0.191342 -0.426777 +v 0.191342 -0.000000 -0.461940 +v 0.176777 -0.191342 -0.426777 +v 0.135299 -0.353553 -0.326641 +v 0.073223 -0.461940 -0.176777 +v 0.135299 0.461940 -0.135299 +v 0.250000 0.353553 -0.250000 +v 0.326641 0.191342 -0.326641 +v 0.353553 -0.000000 -0.353553 +v 0.326641 -0.191342 -0.326641 +v 0.250000 -0.353553 -0.250000 +v 0.135299 -0.461940 -0.135299 +v 0.176777 0.461940 -0.073223 +v 0.326641 0.353553 -0.135299 +v 0.426777 0.191342 -0.176777 +v 0.461940 -0.000000 -0.191342 +v 0.426777 -0.191342 -0.176777 +v 0.326641 -0.353553 -0.135299 +v 0.176777 -0.461940 -0.073223 +v 0.191342 0.461940 -0.000000 +v 0.353553 0.353553 -0.000000 +v 0.461940 0.191342 -0.000000 +v 0.500000 -0.000000 -0.000000 +v 0.461940 -0.191342 -0.000000 +v 0.353553 -0.353553 -0.000000 +v 0.191342 -0.461940 -0.000000 +v 0.176777 0.461940 0.073223 +v 0.326641 0.353553 0.135299 +v 0.426777 0.191342 0.176777 +v 0.461940 -0.000000 0.191342 +v 0.426777 -0.191342 0.176777 +v 0.326641 -0.353553 0.135299 +v 0.176777 -0.461940 0.073223 +v 0.135299 0.461940 0.135299 +v 0.250000 0.353553 0.250000 +v 0.326641 0.191342 0.326641 +v 0.353553 -0.000000 0.353553 +v 0.326641 -0.191342 0.326641 +v 0.250000 -0.353553 0.250000 +v 0.135299 -0.461940 0.135299 +v 0.073223 0.461940 0.176777 +v 0.135299 0.353553 0.326641 +v 0.176777 0.191342 0.426777 +v 0.191342 -0.000000 0.461940 +v 0.176777 -0.191342 0.426777 +v 0.135299 -0.353553 0.326641 +v 0.073223 -0.461940 0.176777 +v -0.000000 0.461940 0.191342 +v -0.000000 0.353553 0.353553 +v -0.000000 0.191342 0.461940 +v -0.000000 -0.000000 0.500000 +v -0.000000 -0.191342 0.461940 +v -0.000000 -0.353553 0.353553 +v -0.000000 -0.461940 0.191342 +v -0.073223 0.461940 0.176777 +v -0.135299 0.353553 0.326640 +v -0.176777 0.191342 0.426776 +v -0.191342 -0.000000 0.461939 +v -0.176777 -0.191342 0.426776 +v -0.135299 -0.353553 0.326640 +v -0.073223 -0.461940 0.176777 +v -0.135299 0.461940 0.135299 +v -0.250000 0.353553 0.250000 +v -0.326641 0.191342 0.326640 +v -0.353553 -0.000000 0.353553 +v -0.326641 -0.191342 0.326640 +v -0.250000 -0.353553 0.250000 +v -0.135299 -0.461940 0.135299 +v -0.176777 0.461940 0.073223 +v -0.326641 0.353553 0.135299 +v -0.426777 0.191342 0.176776 +v -0.461940 -0.000000 0.191341 +v -0.426777 -0.191342 0.176776 +v -0.326641 -0.353553 0.135299 +v -0.176777 -0.461940 0.073223 +v -0.191342 0.461940 -0.000000 +v -0.353553 0.353553 -0.000000 +v -0.461940 0.191342 -0.000000 +v -0.500000 -0.000000 -0.000000 +v -0.461940 -0.191342 -0.000000 +v -0.353553 -0.353553 -0.000000 +v -0.191342 -0.461940 -0.000000 +v -0.176777 0.461940 -0.073223 +v -0.326641 0.353553 -0.135299 +v -0.426776 0.191342 -0.176777 +v -0.461939 -0.000000 -0.191342 +v -0.426776 -0.191342 -0.176777 +v -0.326641 -0.353553 -0.135299 +v -0.176777 -0.461940 -0.073223 +v -0.135299 0.461940 -0.135299 +v -0.250000 0.353553 -0.250000 +v -0.326640 0.191342 -0.326641 +v -0.353553 -0.000000 -0.353554 +v -0.326640 -0.191342 -0.326641 +v -0.250000 -0.353553 -0.250000 +v -0.135299 -0.461940 -0.135299 +v -0.073223 0.461940 -0.176777 +v -0.135299 0.353553 -0.326641 +v -0.176776 0.191342 -0.426777 +v -0.191341 -0.000000 -0.461940 +v -0.176776 -0.191342 -0.426777 +v -0.135299 -0.353553 -0.326641 +v -0.073223 -0.461940 -0.176777 +v -0.000000 0.500000 -0.000000 +v 0.000000 0.461940 -0.191342 +v 0.000000 -0.000000 -0.500000 +v 0.000000 -0.353553 -0.353553 +v 0.000000 -0.500000 -0.000000 +vt 0.750000 0.375000 +vt 0.750000 0.500000 +vt 0.687500 0.500000 +vt 0.687500 0.375000 +vt 0.750000 0.625000 +vt 0.750000 0.750000 +vt 0.687500 0.750000 +vt 0.687500 0.625000 +vt 0.750000 0.875000 +vt 0.718750 1.000000 +vt 0.687500 0.875000 +vt 0.718750 0.000000 +vt 0.750000 0.125000 +vt 0.687500 0.125000 +vt 0.750000 0.250000 +vt 0.687500 0.250000 +vt 0.656250 0.000000 +vt 0.625000 0.125000 +vt 0.625000 0.375000 +vt 0.625000 0.250000 +vt 0.625000 0.625000 +vt 0.625000 0.500000 +vt 0.625000 0.875000 +vt 0.625000 0.750000 +vt 0.656250 1.000000 +vt 0.562500 0.875000 +vt 0.562500 0.750000 +vt 0.562500 0.250000 +vt 0.562500 0.125000 +vt 0.562500 0.500000 +vt 0.562500 0.375000 +vt 0.562500 0.625000 +vt 0.593750 1.000000 +vt 0.593750 0.000000 +vt 0.500000 0.250000 +vt 0.500000 0.125000 +vt 0.500000 0.500000 +vt 0.500000 0.375000 +vt 0.500000 0.750000 +vt 0.500000 0.625000 +vt 0.531250 1.000000 +vt 0.500000 0.875000 +vt 0.531250 0.000000 +vt 0.468750 1.000000 +vt 0.437500 0.875000 +vt 0.468750 0.000000 +vt 0.437500 0.125000 +vt 0.437500 0.375000 +vt 0.437500 0.250000 +vt 0.437500 0.625000 +vt 0.437500 0.500000 +vt 0.437500 0.750000 +vt 0.375000 0.375000 +vt 0.375000 0.250000 +vt 0.375000 0.625000 +vt 0.375000 0.500000 +vt 0.375000 0.875000 +vt 0.375000 0.750000 +vt 0.375000 0.125000 +vt 0.406250 1.000000 +vt 0.406250 0.000000 +vt 0.312500 0.250000 +vt 0.312500 0.125000 +vt 0.312500 0.500000 +vt 0.312500 0.375000 +vt 0.312500 0.750000 +vt 0.312500 0.625000 +vt 0.343750 1.000000 +vt 0.312500 0.875000 +vt 0.343750 0.000000 +vt 0.250000 0.500000 +vt 0.250000 0.375000 +vt 0.250000 0.750000 +vt 0.250000 0.625000 +vt 0.281250 1.000000 +vt 0.250000 0.875000 +vt 0.281250 0.000000 +vt 0.250000 0.125000 +vt 0.250000 0.250000 +vt 0.218750 0.000000 +vt 0.187500 0.125000 +vt 0.187500 0.375000 +vt 0.187500 0.250000 +vt 0.187500 0.625000 +vt 0.187500 0.500000 +vt 0.187500 0.875000 +vt 0.187500 0.750000 +vt 0.218750 1.000000 +vt 0.125000 0.625000 +vt 0.125000 0.500000 +vt 0.125000 0.875000 +vt 0.125000 0.750000 +vt 0.125000 0.250000 +vt 0.125000 0.125000 +vt 0.125000 0.375000 +vt 0.156250 1.000000 +vt 0.156250 0.000000 +vt 0.062500 0.250000 +vt 0.062500 0.125000 +vt 0.062500 0.500000 +vt 0.062500 0.375000 +vt 0.062500 0.750000 +vt 0.062500 0.625000 +vt 0.093750 1.000000 +vt 0.062500 0.875000 +vt 0.093750 0.000000 +vt 0.000000 0.750000 +vt 0.000000 0.625000 +vt 0.031250 1.000000 +vt 0.000000 0.875000 +vt 0.031250 0.000000 +vt 0.000000 0.125000 +vt 0.000000 0.375000 +vt 0.000000 0.250000 +vt 0.000000 0.500000 +vt 0.968750 0.000000 +vt 1.000000 0.125000 +vt 0.937500 0.125000 +vt 1.000000 0.250000 +vt 1.000000 0.375000 +vt 0.937500 0.375000 +vt 0.937500 0.250000 +vt 1.000000 0.500000 +vt 1.000000 0.625000 +vt 0.937500 0.625000 +vt 0.937500 0.500000 +vt 1.000000 0.750000 +vt 1.000000 0.875000 +vt 0.937500 0.875000 +vt 0.937500 0.750000 +vt 0.968750 1.000000 +vt 0.875000 0.875000 +vt 0.875000 0.750000 +vt 0.875000 0.250000 +vt 0.875000 0.125000 +vt 0.875000 0.500000 +vt 0.875000 0.375000 +vt 0.875000 0.625000 +vt 0.906250 1.000000 +vt 0.906250 0.000000 +vt 0.812500 0.250000 +vt 0.812500 0.125000 +vt 0.812500 0.500000 +vt 0.812500 0.375000 +vt 0.812500 0.750000 +vt 0.812500 0.625000 +vt 0.843750 1.000000 +vt 0.812500 0.875000 +vt 0.843750 0.000000 +vt 0.781250 1.000000 +vt 0.781250 0.000000 +vn 0.1915 -0.1915 -0.9626 +vn 0.1632 0.5481 -0.8203 +vn 0.0388 0.9800 -0.1949 +vn 0.0388 -0.9800 -0.1949 +vn 0.1632 -0.5481 -0.8203 +vn 0.1915 0.1915 -0.9626 +vn 0.1098 0.8264 -0.5522 +vn 0.1098 -0.8264 -0.5522 +vn 0.1104 -0.9800 -0.1653 +vn 0.4647 -0.5481 -0.6954 +vn 0.5453 0.1915 -0.8161 +vn 0.3128 0.8264 -0.4681 +vn 0.3128 -0.8264 -0.4681 +vn 0.5453 -0.1915 -0.8161 +vn 0.4647 0.5481 -0.6954 +vn 0.1104 0.9800 -0.1653 +vn 0.4681 0.8264 -0.3128 +vn 0.4681 -0.8264 -0.3128 +vn 0.8161 -0.1915 -0.5453 +vn 0.6954 0.5481 -0.4647 +vn 0.1653 0.9800 -0.1104 +vn 0.1653 -0.9800 -0.1104 +vn 0.6954 -0.5481 -0.4647 +vn 0.8161 0.1915 -0.5453 +vn 0.5522 -0.8264 -0.1098 +vn 0.9626 -0.1915 -0.1915 +vn 0.8203 0.5481 -0.1632 +vn 0.1949 0.9800 -0.0388 +vn 0.1949 -0.9800 -0.0388 +vn 0.8203 -0.5481 -0.1632 +vn 0.9626 0.1915 -0.1915 +vn 0.5522 0.8264 -0.1098 +vn 0.1949 0.9800 0.0388 +vn 0.1949 -0.9800 0.0388 +vn 0.8203 -0.5481 0.1632 +vn 0.9626 0.1915 0.1915 +vn 0.5522 0.8264 0.1098 +vn 0.5522 -0.8264 0.1098 +vn 0.9626 -0.1915 0.1915 +vn 0.8203 0.5481 0.1632 +vn 0.6954 -0.5481 0.4647 +vn 0.8161 0.1915 0.5453 +vn 0.4681 0.8264 0.3128 +vn 0.4681 -0.8264 0.3128 +vn 0.8161 -0.1915 0.5453 +vn 0.6954 0.5481 0.4647 +vn 0.1653 0.9800 0.1104 +vn 0.1653 -0.9800 0.1104 +vn 0.3128 -0.8264 0.4681 +vn 0.5453 -0.1915 0.8161 +vn 0.4647 0.5481 0.6954 +vn 0.1104 0.9800 0.1653 +vn 0.1104 -0.9800 0.1653 +vn 0.4647 -0.5481 0.6954 +vn 0.5453 0.1915 0.8161 +vn 0.3128 0.8264 0.4681 +vn 0.1915 -0.1915 0.9626 +vn 0.1632 0.5481 0.8203 +vn 0.0388 0.9800 0.1949 +vn 0.0388 -0.9800 0.1949 +vn 0.1632 -0.5481 0.8203 +vn 0.1915 0.1915 0.9626 +vn 0.1098 0.8264 0.5522 +vn 0.1098 -0.8264 0.5522 +vn -0.0388 -0.9800 0.1949 +vn -0.1632 -0.5481 0.8203 +vn -0.1915 0.1915 0.9626 +vn -0.1098 0.8264 0.5522 +vn -0.1098 -0.8264 0.5522 +vn -0.1915 -0.1915 0.9626 +vn -0.1632 0.5481 0.8203 +vn -0.0388 0.9800 0.1949 +vn -0.5453 0.1915 0.8161 +vn -0.3128 0.8264 0.4681 +vn -0.3128 -0.8264 0.4681 +vn -0.5453 -0.1915 0.8161 +vn -0.4647 0.5481 0.6954 +vn -0.1104 0.9800 0.1653 +vn -0.1104 -0.9800 0.1653 +vn -0.4647 -0.5481 0.6954 +vn -0.4681 -0.8264 0.3128 +vn -0.8161 -0.1915 0.5453 +vn -0.6954 0.5481 0.4647 +vn -0.1653 0.9800 0.1104 +vn -0.1653 -0.9800 0.1104 +vn -0.6954 -0.5481 0.4647 +vn -0.8161 0.1915 0.5453 +vn -0.4681 0.8264 0.3128 +vn -0.8203 0.5481 0.1632 +vn -0.1949 0.9800 0.0388 +vn -0.1949 -0.9800 0.0388 +vn -0.8203 -0.5481 0.1632 +vn -0.9626 0.1915 0.1915 +vn -0.5522 0.8264 0.1098 +vn -0.5522 -0.8264 0.1098 +vn -0.9626 -0.1915 0.1915 +vn -0.1949 -0.9800 -0.0388 +vn -0.8203 -0.5481 -0.1632 +vn -0.9626 0.1915 -0.1915 +vn -0.5522 0.8264 -0.1098 +vn -0.5522 -0.8264 -0.1098 +vn -0.9626 -0.1915 -0.1915 +vn -0.8203 0.5481 -0.1632 +vn -0.1949 0.9800 -0.0388 +vn -0.4681 0.8264 -0.3128 +vn -0.4681 -0.8264 -0.3128 +vn -0.8161 -0.1915 -0.5453 +vn -0.6954 0.5481 -0.4647 +vn -0.1653 0.9800 -0.1104 +vn -0.1653 -0.9800 -0.1104 +vn -0.6954 -0.5481 -0.4647 +vn -0.8161 0.1915 -0.5453 +vn -0.3128 -0.8264 -0.4681 +vn -0.5453 -0.1915 -0.8161 +vn -0.4647 0.5481 -0.6954 +vn -0.1104 0.9800 -0.1653 +vn -0.1104 -0.9800 -0.1653 +vn -0.4647 -0.5481 -0.6954 +vn -0.5453 0.1915 -0.8161 +vn -0.3128 0.8264 -0.4681 +vn -0.0388 0.9800 -0.1949 +vn -0.0388 -0.9800 -0.1949 +vn -0.1632 -0.5481 -0.8203 +vn -0.1915 0.1915 -0.9626 +vn -0.1098 0.8264 -0.5522 +vn -0.1098 -0.8264 -0.5522 +vn -0.1915 -0.1915 -0.9626 +vn -0.1632 0.5481 -0.8203 +usemtl None +s off +f 3/1/1 112/2/1 8/3/1 9/4/1 +f 2/5/2 1/6/2 6/7/2 7/8/2 +f 111/9/3 110/10/3 5/11/3 +f 114/12/4 4/13/4 11/14/4 +f 113/15/5 3/1/5 9/4/5 10/16/5 +f 112/2/6 2/5/6 7/8/6 8/3/6 +f 1/6/7 111/9/7 5/11/7 6/7/7 +f 4/13/8 113/15/8 10/16/8 11/14/8 +f 114/17/9 11/14/9 18/18/9 +f 10/16/10 9/4/10 16/19/10 17/20/10 +f 8/3/11 7/8/11 14/21/11 15/22/11 +f 6/7/12 5/11/12 12/23/12 13/24/12 +f 11/14/13 10/16/13 17/20/13 18/18/13 +f 9/4/14 8/3/14 15/22/14 16/19/14 +f 7/8/15 6/7/15 13/24/15 14/21/15 +f 5/11/16 110/25/16 12/23/16 +f 13/24/17 12/23/17 19/26/17 20/27/17 +f 18/18/18 17/20/18 24/28/18 25/29/18 +f 16/19/19 15/22/19 22/30/19 23/31/19 +f 14/21/20 13/24/20 20/27/20 21/32/20 +f 12/23/21 110/33/21 19/26/21 +f 114/34/22 18/18/22 25/29/22 +f 17/20/23 16/19/23 23/31/23 24/28/23 +f 15/22/24 14/21/24 21/32/24 22/30/24 +f 25/29/25 24/28/25 31/35/25 32/36/25 +f 23/31/26 22/30/26 29/37/26 30/38/26 +f 21/32/27 20/27/27 27/39/27 28/40/27 +f 19/26/28 110/41/28 26/42/28 +f 114/43/29 25/29/29 32/36/29 +f 24/28/30 23/31/30 30/38/30 31/35/30 +f 22/30/31 21/32/31 28/40/31 29/37/31 +f 20/27/32 19/26/32 26/42/32 27/39/32 +f 26/42/33 110/44/33 33/45/33 +f 114/46/34 32/36/34 39/47/34 +f 31/35/35 30/38/35 37/48/35 38/49/35 +f 29/37/36 28/40/36 35/50/36 36/51/36 +f 27/39/37 26/42/37 33/45/37 34/52/37 +f 32/36/38 31/35/38 38/49/38 39/47/38 +f 30/38/39 29/37/39 36/51/39 37/48/39 +f 28/40/40 27/39/40 34/52/40 35/50/40 +f 38/49/41 37/48/41 44/53/41 45/54/41 +f 36/51/42 35/50/42 42/55/42 43/56/42 +f 34/52/43 33/45/43 40/57/43 41/58/43 +f 39/47/44 38/49/44 45/54/44 46/59/44 +f 37/48/45 36/51/45 43/56/45 44/53/45 +f 35/50/46 34/52/46 41/58/46 42/55/46 +f 33/45/47 110/60/47 40/57/47 +f 114/61/48 39/47/48 46/59/48 +f 46/59/49 45/54/49 52/62/49 53/63/49 +f 44/53/50 43/56/50 50/64/50 51/65/50 +f 42/55/51 41/58/51 48/66/51 49/67/51 +f 40/57/52 110/68/52 47/69/52 +f 114/70/53 46/59/53 53/63/53 +f 45/54/54 44/53/54 51/65/54 52/62/54 +f 43/56/55 42/55/55 49/67/55 50/64/55 +f 41/58/56 40/57/56 47/69/56 48/66/56 +f 51/65/57 50/64/57 57/71/57 58/72/57 +f 49/67/58 48/66/58 55/73/58 56/74/58 +f 47/69/59 110/75/59 54/76/59 +f 114/77/60 53/63/60 60/78/60 +f 52/62/61 51/65/61 58/72/61 59/79/61 +f 50/64/62 49/67/62 56/74/62 57/71/62 +f 48/66/63 47/69/63 54/76/63 55/73/63 +f 53/63/64 52/62/64 59/79/64 60/78/64 +f 114/80/65 60/78/65 67/81/65 +f 59/79/66 58/72/66 65/82/66 66/83/66 +f 57/71/67 56/74/67 63/84/67 64/85/67 +f 55/73/68 54/76/68 61/86/68 62/87/68 +f 60/78/69 59/79/69 66/83/69 67/81/69 +f 58/72/70 57/71/70 64/85/70 65/82/70 +f 56/74/71 55/73/71 62/87/71 63/84/71 +f 54/76/72 110/88/72 61/86/72 +f 64/85/73 63/84/73 70/89/73 71/90/73 +f 62/87/74 61/86/74 68/91/74 69/92/74 +f 67/81/75 66/83/75 73/93/75 74/94/75 +f 65/82/76 64/85/76 71/90/76 72/95/76 +f 63/84/77 62/87/77 69/92/77 70/89/77 +f 61/86/78 110/96/78 68/91/78 +f 114/97/79 67/81/79 74/94/79 +f 66/83/80 65/82/80 72/95/80 73/93/80 +f 74/94/81 73/93/81 80/98/81 81/99/81 +f 72/95/82 71/90/82 78/100/82 79/101/82 +f 70/89/83 69/92/83 76/102/83 77/103/83 +f 68/91/84 110/104/84 75/105/84 +f 114/106/85 74/94/85 81/99/85 +f 73/93/86 72/95/86 79/101/86 80/98/86 +f 71/90/87 70/89/87 77/103/87 78/100/87 +f 69/92/88 68/91/88 75/105/88 76/102/88 +f 77/103/89 76/102/89 83/107/89 84/108/89 +f 75/105/90 110/109/90 82/110/90 +f 114/111/91 81/99/91 88/112/91 +f 80/98/92 79/101/92 86/113/92 87/114/92 +f 78/100/93 77/103/93 84/108/93 85/115/93 +f 76/102/94 75/105/94 82/110/94 83/107/94 +f 81/99/95 80/98/95 87/114/95 88/112/95 +f 79/101/96 78/100/96 85/115/96 86/113/96 +f 114/116/97 88/117/97 95/118/97 +f 87/119/98 86/120/98 93/121/98 94/122/98 +f 85/123/99 84/124/99 91/125/99 92/126/99 +f 83/127/100 82/128/100 89/129/100 90/130/100 +f 88/117/101 87/119/101 94/122/101 95/118/101 +f 86/120/102 85/123/102 92/126/102 93/121/102 +f 84/124/103 83/127/103 90/130/103 91/125/103 +f 82/128/104 110/131/104 89/129/104 +f 90/130/105 89/129/105 96/132/105 97/133/105 +f 95/118/106 94/122/106 101/134/106 102/135/106 +f 93/121/107 92/126/107 99/136/107 100/137/107 +f 91/125/108 90/130/108 97/133/108 98/138/108 +f 89/129/109 110/139/109 96/132/109 +f 114/140/110 95/118/110 102/135/110 +f 94/122/111 93/121/111 100/137/111 101/134/111 +f 92/126/112 91/125/112 98/138/112 99/136/112 +f 102/135/113 101/134/113 108/141/113 109/142/113 +f 100/137/114 99/136/114 106/143/114 107/144/114 +f 98/138/115 97/133/115 104/145/115 105/146/115 +f 96/132/116 110/147/116 103/148/116 +f 114/149/117 102/135/117 109/142/117 +f 101/134/118 100/137/118 107/144/118 108/141/118 +f 99/136/119 98/138/119 105/146/119 106/143/119 +f 97/133/120 96/132/120 103/148/120 104/145/120 +f 103/148/121 110/150/121 111/9/121 +f 114/151/122 109/142/122 4/13/122 +f 108/141/123 107/144/123 3/1/123 113/15/123 +f 106/143/124 105/146/124 2/5/124 112/2/124 +f 104/145/125 103/148/125 111/9/125 1/6/125 +f 109/142/126 108/141/126 113/15/126 4/13/126 +f 107/144/127 106/143/127 112/2/127 3/1/127 +f 105/146/128 104/145/128 1/6/128 2/5/128 diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index 328706e..b658ef0 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -14,14 +14,20 @@ class LSystem { seed: string; axioms: Array = []; iterations: number = 2; + // Set up instanced rendering data arrays. branchCols1: Array = []; branchCols2: Array = []; branchCols3: Array = []; branchCols4: Array = []; branchColorsBO: Array = []; - branchNum: number = 0; + + leafCols1: Array = []; + leafCols2: Array = []; + leafCols3: Array = []; + leafCols4: Array = []; + leafColorsBO: Array = []; leafNum: number = 0; // import objs: @@ -30,6 +36,11 @@ class LSystem { vec3.fromValues(0, 0, 0) ); + leaf: Mesh = new Mesh( + readTextFile("resources/sphere.obj"), + vec3.fromValues(0, 0, 0) + ); + drawBranch: () => void; setSeed: (s: string) => void; pushTurtle: () => void; @@ -53,13 +64,13 @@ class LSystem { }; this.pushTurtle = () => { - let newPos : vec3 = vec3.create(); - let newOrient : mat3 = mat3.create(); + let newPos: vec3 = vec3.create(); + let newOrient: mat3 = mat3.create(); let newTurtle: Turtle = new Turtle( vec3.copy(newPos, this.turtle.position), mat3.copy(newOrient, this.turtle.orientation) ); - let newDepth : number = this.turtle.depth; + let newDepth: number = this.turtle.depth; newTurtle.depth = newDepth; this.turtleStack.push(newTurtle); this.turtle.depth += 1; @@ -68,7 +79,10 @@ class LSystem { this.popTurtle = () => { if (this.turtle.depth > 0) { let newTurtle: Turtle = this.turtleStack.pop(); - this.turtle.orientation = mat3.copy(mat3.create(), newTurtle.orientation); + this.turtle.orientation = mat3.copy( + mat3.create(), + newTurtle.orientation + ); this.turtle.position = vec3.copy(vec3.create(), newTurtle.position); this.turtle.depth -= 1; } @@ -84,7 +98,7 @@ class LSystem { this.expansionRules.set("X", rule2); }; - this.populateDrawingRules = () => { + this.populateDrawingRules = () => { let pushRule: DrawingRule = new DrawingRule(); pushRule.addOutput(this.pushTurtle, 1.0); this.drawingRules.set("[", pushRule); @@ -120,7 +134,6 @@ class LSystem { let forwardRule: DrawingRule = new DrawingRule(); forwardRule.addOutput(this.drawBranch, 1.0); this.drawingRules.set("F", forwardRule); - }; this.putBranch = (scale: vec3) => { diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index 325fa5b..ebdc86d 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -13,7 +13,6 @@ class Turtle { moveForward: () => void; rotateRightX: () => void; rotateLeftX: () => void; - // TODO: IMPLEMENT THESE TO MATCH NEW ROTATION AXES rotatePosY: () => void; rotateNegY: () => void; rotatePosZ: () => void; @@ -34,11 +33,19 @@ class Turtle { }; this.getRight = () => { - return vec3.fromValues(this.orientation[6], this.orientation[7], this.orientation[8]); - } + return vec3.fromValues( + this.orientation[6], + this.orientation[7], + this.orientation[8] + ); + }; this.getUp = () => { - return vec3.fromValues(this.orientation[0], this.orientation[1], this.orientation[2]); - } + return vec3.fromValues( + this.orientation[0], + this.orientation[1], + this.orientation[2] + ); + }; this.moveForward = () => { vec3.add( @@ -63,27 +70,27 @@ class Turtle { this.rotateRightX = () => { this.rotate(this.getUp(), -15); - } + }; this.rotateLeftX = () => { this.rotate(this.getUp(), 15); - } + }; this.rotatePosY = () => { this.rotate(this.getForward(), 15); - } + }; this.rotateNegY = () => { this.rotate(this.getForward(), -15); - } + }; this.rotatePosZ = () => { this.rotate(this.getRight(), 15); - } + }; this.rotateNegZ = () => { this.rotate(this.getRight(), -15); - } + }; } reset() { diff --git a/src/main.ts b/src/main.ts index f0820ee..973d50e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -24,7 +24,8 @@ let coral : LSystem = new LSystem(); function loadScene() { coral.makeTree(); - console.log("DEBUG CORAL BRANCHES: " + coral.branchCols1); +coral.leaf.create(); + square = new Square(); square.create(); @@ -66,20 +67,13 @@ function loadScene() { colorsArrayBranch.push(1.0); colorsArrayBranch.push(1.0); - // let t1: Float32Array = new Float32Array(cols1ArrayBranch); - // let t2: Float32Array = new Float32Array(cols2ArrayBranch); - // let t3: Float32Array = new Float32Array(cols3ArrayBranch); - // let t4: Float32Array = new Float32Array(cols4ArrayBranch); - // let branchColors: Float32Array = new Float32Array(colorsArrayBranch); - // branch.setInstanceVBOs(t1, t2, t3, t4, branchColors); - // branch.setNumInstances(1); - let t1: Float32Array = new Float32Array(coral.branchCols1); - let t2: Float32Array = new Float32Array(coral.branchCols2); - let t3: Float32Array = new Float32Array(coral.branchCols3); - let t4: Float32Array = new Float32Array(coral.branchCols4); - let branchColors: Float32Array = new Float32Array(coral.branchColorsBO); - // coral.branch.setInstanceVBOs(t1, t2, t3, t4, branchColors); - //coral.branch.setNumInstances(3); + let t1: Float32Array = new Float32Array(cols1ArrayBranch); + let t2: Float32Array = new Float32Array(cols2ArrayBranch); + let t3: Float32Array = new Float32Array(cols3ArrayBranch); + let t4: Float32Array = new Float32Array(cols4ArrayBranch); + let branchColors: Float32Array = new Float32Array(colorsArrayBranch); + coral.leaf.setInstanceVBOs(t1, t2, t3, t4, branchColors); + coral.leaf.setNumInstances(1); // Set up instanced rendering data arrays here. // This example creates a set of positional @@ -186,7 +180,8 @@ function main() { renderer.render(camera, instancedShader, [ // square, // branch, - coral.branch + coral.branch, + coral.leaf ]); stats.end(); From 912f0efccb30b79495e22cd30674c5eca7ae84e8 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sun, 7 Nov 2021 08:44:31 -0500 Subject: [PATCH 16/34] Added Leaves to Grammar, Random Rotation Offsets --- src/l-system/L-System.ts | 53 ++++++++++++++++++++++++++++++++++++++-- src/l-system/Turtle.ts | 22 ++++++++++++++++- src/main.ts | 6 ++--- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index b658ef0..5e0f826 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -14,7 +14,7 @@ class LSystem { seed: string; axioms: Array = []; iterations: number = 2; - + // Set up instanced rendering data arrays. branchCols1: Array = []; branchCols2: Array = []; @@ -48,6 +48,7 @@ class LSystem { populateExpansionRules: () => void; populateDrawingRules: () => void; putBranch: (scale: vec3) => void; + putLeaf: () => void; createMeshes: () => void; drawTree: () => void; expandGrammar: () => void; @@ -90,7 +91,7 @@ class LSystem { this.populateExpansionRules = () => { let rule1: ExpansionRule = new ExpansionRule(); - rule1.addOutput("FF-[-/-/FF+*+*F^F]+[+/+F/^F]", 1.0); // * is the same as \ in houdini here + rule1.addOutput("FF#-[-/-/FF#+*+*F^F#]+[+/+F/^F#]#", 1.0); // * is the same as \ in houdini here this.expansionRules.set("F", rule1); let rule2: ExpansionRule = new ExpansionRule(); @@ -134,6 +135,10 @@ class LSystem { let forwardRule: DrawingRule = new DrawingRule(); forwardRule.addOutput(this.drawBranch, 1.0); this.drawingRules.set("F", forwardRule); + + let leafRule: DrawingRule = new DrawingRule(); + leafRule.addOutput(this.putLeaf, 1.0); + this.drawingRules.set("#", leafRule); }; this.putBranch = (scale: vec3) => { @@ -161,6 +166,33 @@ class LSystem { this.branchNum++; }; + this.putLeaf = () => { + this.turtle.smallMoveForward(); + + // Calculate transformation + let transform: mat4 = mat4.create(); + let q: quat = quat.create(); + quat.fromMat3(q, this.turtle.orientation); + mat4.fromRotationTranslationScale( + transform, + q, + this.turtle.position, + vec3.fromValues(2.5, 2.5, 2.5) + ); + for (let i = 0; i < 4; i++) { + this.leafCols1.push(transform[i]); + this.leafCols2.push(transform[4 + i]); + this.leafCols3.push(transform[8 + i]); + this.leafCols4.push(transform[12 + i]); + } + + this.leafColorsBO.push(57 / 255); + this.leafColorsBO.push(217 / 255); + this.leafColorsBO.push(222 / 255); + this.leafColorsBO.push(1.0); + this.leafNum++; + }; + this.createMeshes = () => { this.branch.create(); }; @@ -177,6 +209,15 @@ class LSystem { this.branch.destroy(); this.branch.create(); + this.leafNum = 0; + this.leafCols1 = []; + this.leafCols2 = []; + this.leafCols3 = []; + this.leafCols4 = []; + this.leafColorsBO = []; + this.leaf.destroy(); + this.leaf.create(); + // Draw based on grammar let count = 0; for (let i = 0; i < this.axioms[this.iterations].length; i++) { @@ -196,6 +237,14 @@ class LSystem { let bcolors: Float32Array = new Float32Array(this.branchColorsBO); this.branch.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); this.branch.setNumInstances(this.branchNum); + + let lCol1: Float32Array = new Float32Array(this.leafCols1); + let lCol2: Float32Array = new Float32Array(this.leafCols2); + let lCol3: Float32Array = new Float32Array(this.leafCols3); + let lCol4: Float32Array = new Float32Array(this.leafCols4); + let lcolors: Float32Array = new Float32Array(this.leafColorsBO); + this.leaf.setInstanceVBOs(lCol1, lCol2, lCol3, lCol4, lcolors); + this.leaf.setNumInstances(this.leafNum); }; this.expandGrammar = () => { diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index ebdc86d..24ca5fe 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -1,6 +1,7 @@ import { mat3, vec3, quat } from "gl-matrix"; // vec3 operations from: https://glmatrix.net/docs/module-vec3.html +const PI = 3.1415926535; class Turtle { position: vec3 = vec3.fromValues(0.0, 0.0, 0.0); @@ -11,6 +12,7 @@ class Turtle { getRight: () => vec3; getUp: () => vec3; moveForward: () => void; + smallMoveForward: () => void; rotateRightX: () => void; rotateLeftX: () => void; rotatePosY: () => void; @@ -55,9 +57,27 @@ class Turtle { ); }; + this.smallMoveForward = () => { + vec3.add( + this.position, + this.position, + vec3.scale(vec3.create(), this.getForward(), 5.0) + ); + }; + this.rotate = (axis: vec3, angle: number) => { + // pick random # + let rand = Math.random(); + // scale it to between -PI/2 and PI/2 + rand = (rand * PI) - (PI / 2); + // sample it on the sin curve + let offset = Math.sin(2.0 * rand); + // multiply value by 10 + offset = offset * 10.0; + console.log(offset); + vec3.normalize(axis, axis); - let radians = (3.14159 * angle) / 180.0; + let radians = (PI * (angle + offset)) / 180.0; let q: quat = quat.create(); quat.setAxisAngle(q, axis, radians); diff --git a/src/main.ts b/src/main.ts index 973d50e..8d96d21 100644 --- a/src/main.ts +++ b/src/main.ts @@ -24,7 +24,7 @@ let coral : LSystem = new LSystem(); function loadScene() { coral.makeTree(); -coral.leaf.create(); +// coral.leaf.create(); square = new Square(); @@ -72,8 +72,8 @@ coral.leaf.create(); let t3: Float32Array = new Float32Array(cols3ArrayBranch); let t4: Float32Array = new Float32Array(cols4ArrayBranch); let branchColors: Float32Array = new Float32Array(colorsArrayBranch); - coral.leaf.setInstanceVBOs(t1, t2, t3, t4, branchColors); - coral.leaf.setNumInstances(1); + //coral.leaf.setInstanceVBOs(t1, t2, t3, t4, branchColors); + //coral.leaf.setNumInstances(1); // Set up instanced rendering data arrays here. // This example creates a set of positional From 06b6cb8d22c293a7ca40a94531f3182a95965f65 Mon Sep 17 00:00:00 2001 From: Serena Gandhi <60444726+gserena01@users.noreply.github.com> Date: Sun, 7 Nov 2021 08:46:05 -0500 Subject: [PATCH 17/34] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 70daf09..adac4d0 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ ![image](https://user-images.githubusercontent.com/60444726/140631854-348ce9c7-f722-4cbc-8ce8-d105a5965d84.png) +# External Resources: + +https://stackoverflow.com/questions/14471975/how-can-i-preserve-lexical-scope-in-typescript-with-a-callback-function + # Homework 4: L-systems From 5dc4abcb3d6b75698d6346b3329d9db59ab12eb9 Mon Sep 17 00:00:00 2001 From: Serena Gandhi <60444726+gserena01@users.noreply.github.com> Date: Sun, 7 Nov 2021 08:46:52 -0500 Subject: [PATCH 18/34] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index adac4d0..1c009a6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,9 @@ # External Resources: -https://stackoverflow.com/questions/14471975/how-can-i-preserve-lexical-scope-in-typescript-with-a-callback-function +Using Callback Functions: https://stackoverflow.com/questions/14471975/how-can-i-preserve-lexical-scope-in-typescript-with-a-callback-function + +L-System Visualizer: https://www.kevs3d.co.uk/dev/lsystems/ # Homework 4: L-systems From 28b29fdb6477082d587f30b068a3a92d2c0a0160 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Sun, 7 Nov 2021 10:52:38 -0500 Subject: [PATCH 19/34] cleanup --- src/l-system/L-System.ts | 1 + src/main.ts | 100 +------------------------------- src/shaders/flat-frag.glsl | 1 + src/shaders/instanced-frag.glsl | 2 +- src/shaders/instanced-vert.glsl | 4 -- 5 files changed, 5 insertions(+), 103 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index 5e0f826..4212a74 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -99,6 +99,7 @@ class LSystem { this.expansionRules.set("X", rule2); }; + // ADD variation in expansion rules and drawing rules this.populateDrawingRules = () => { let pushRule: DrawingRule = new DrawingRule(); pushRule.addOutput(this.pushTurtle, 1.0); diff --git a/src/main.ts b/src/main.ts index 8d96d21..b5c58f0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -24,103 +24,9 @@ let coral : LSystem = new LSystem(); function loadScene() { coral.makeTree(); -// coral.leaf.create(); - - square = new Square(); - square.create(); screenQuad = new ScreenQuad(); screenQuad.create(); - branch = new Mesh( - readTextFile("resources/cylinder.obj"), - vec3.fromValues(0, 0, 0) - ); - branch.create(); - - let colorsArrayBranch = []; - let cols1ArrayBranch = []; - cols1ArrayBranch.push(5.0); - cols1ArrayBranch.push(0.0); - cols1ArrayBranch.push(0.0); - cols1ArrayBranch.push(0.0); - - let cols2ArrayBranch = []; - cols2ArrayBranch.push(0.0); - cols2ArrayBranch.push(5.0); - cols2ArrayBranch.push(0.0); - cols2ArrayBranch.push(0.0); - - let cols3ArrayBranch = []; - cols3ArrayBranch.push(0.0); - cols3ArrayBranch.push(0.0); - cols3ArrayBranch.push(5.0); - cols3ArrayBranch.push(0.0); - - let cols4ArrayBranch = []; - cols4ArrayBranch.push(50.0); - cols4ArrayBranch.push(50.0); - cols4ArrayBranch.push(0.0); - cols4ArrayBranch.push(1.0); - - colorsArrayBranch.push(1.0); - colorsArrayBranch.push(0.0); - colorsArrayBranch.push(1.0); - colorsArrayBranch.push(1.0); - - let t1: Float32Array = new Float32Array(cols1ArrayBranch); - let t2: Float32Array = new Float32Array(cols2ArrayBranch); - let t3: Float32Array = new Float32Array(cols3ArrayBranch); - let t4: Float32Array = new Float32Array(cols4ArrayBranch); - let branchColors: Float32Array = new Float32Array(colorsArrayBranch); - //coral.leaf.setInstanceVBOs(t1, t2, t3, t4, branchColors); - //coral.leaf.setNumInstances(1); - - // Set up instanced rendering data arrays here. - // This example creates a set of positional - // offsets and gradiated colors for a 100x100 grid - // of squares, even though the VBO data for just - // one square is actually passed to the GPU - let offsetsArray = []; - let colorsArray = []; - let n: number = 100.0; - let sCol1 = []; - let sCol2 = []; - let sCol3 = []; - let sCol4 = []; - - for (let i = 0; i < n; i++) { - for (let j = 0; j < n; j++) { - mat4.translate(matrix, matrix, vec3.fromValues(i, j, 0)); - //mat4.scale(matrix, matrix, vec3.fromValues(5.0, 5.0, 5.0)); - for (let k: number = 0; k < 4; k++) { - sCol1.push(matrix[k]); - sCol2.push(matrix[k + 4]); - sCol3.push(matrix[k + 8]); - sCol4.push(matrix[k + 12]); - } - - colorsArray.push(j / i); - colorsArray.push(j / i); - colorsArray.push(1.0); - colorsArray.push(1.0); // Alpha channel - mat4.identity(matrix); - } - } - - let offsetsCol1: Float32Array = new Float32Array(sCol1); - let offsetsCol2: Float32Array = new Float32Array(sCol2); - let offsetsCol3: Float32Array = new Float32Array(sCol3); - let offsetsCol4: Float32Array = new Float32Array(sCol4); - - let colors: Float32Array = new Float32Array(colorsArray); - square.setInstanceTransformVBOs( - offsetsCol1, - offsetsCol2, - offsetsCol3, - offsetsCol4, - colors - ); - square.setNumInstances(n * n); // grid of "particles" } function main() { @@ -149,8 +55,8 @@ function main() { loadScene(); const camera = new Camera( - vec3.fromValues(5, 5, 10), - vec3.fromValues(50, 50, 0) + vec3.fromValues(-60, 90, 15), + vec3.fromValues(50, 100, 0) ); const renderer = new OpenGLRenderer(canvas); @@ -178,8 +84,6 @@ function main() { renderer.clear(); renderer.render(camera, flat, [screenQuad]); renderer.render(camera, instancedShader, [ - // square, - // branch, coral.branch, coral.leaf ]); diff --git a/src/shaders/flat-frag.glsl b/src/shaders/flat-frag.glsl index 99362d2..d3f05db 100644 --- a/src/shaders/flat-frag.glsl +++ b/src/shaders/flat-frag.glsl @@ -10,4 +10,5 @@ out vec4 out_Col; void main() { out_Col = vec4(0.5 * (fs_Pos + vec2(1.0)), 0.0, 1.0); + out_Col = vec4(0.0, 0.0, 0.0, 1.0); } diff --git a/src/shaders/instanced-frag.glsl b/src/shaders/instanced-frag.glsl index 049e9d3..0b9308a 100644 --- a/src/shaders/instanced-frag.glsl +++ b/src/shaders/instanced-frag.glsl @@ -11,5 +11,5 @@ void main() // for falloff: // float dist = 1.0 - (length(fs_Pos.xyz) * 2.0); // out_Col = vec4(dist) * fs_Col; - out_Col = fs_Col; + out_Col = vec4(vec3(fs_Col) , 1.0); } diff --git a/src/shaders/instanced-vert.glsl b/src/shaders/instanced-vert.glsl index 1b77b54..19e3851 100644 --- a/src/shaders/instanced-vert.glsl +++ b/src/shaders/instanced-vert.glsl @@ -26,14 +26,10 @@ void main() fs_Col = vs_Col; fs_Pos = vs_Pos; - mat4 TransformMatrix = mat4(vs_Transform1, vs_Transform2, vs_Transform3, vs_Transform4); fs_Nor = TransformMatrix * vs_Nor; vec4 newPos = TransformMatrix * vs_Pos; - vec3 offset = vs_Translate; - vec3 billboardPos = offset + vs_Pos.x * u_CameraAxes[0] + vs_Pos.y * u_CameraAxes[1]; - gl_Position = u_ViewProj * vec4(vec3(newPos), 1.0); } From fe482f7d6a12c6e8cf10b7c8cce83a14a9386bb5 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Mon, 8 Nov 2021 10:22:25 -0500 Subject: [PATCH 20/34] Added variation to expansion and drawing rules --- src/l-system/L-System.ts | 26 +++++++++++++++++--------- src/l-system/Turtle.ts | 29 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index 4212a74..0592fdb 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -91,15 +91,17 @@ class LSystem { this.populateExpansionRules = () => { let rule1: ExpansionRule = new ExpansionRule(); - rule1.addOutput("FF#-[-/-/FF#+*+*F^F#]+[+/+F/^F#]#", 1.0); // * is the same as \ in houdini here + rule1.addOutput("FF#-[-/-/FF#+*+*F^F#]+[+/+F/^F#]#", 0.9); // * is the same as \ in houdini here + rule1.addOutput("[-*^F]#", 0.1); this.expansionRules.set("F", rule1); let rule2: ExpansionRule = new ExpansionRule(); - rule2.addOutput("++//&&[F]", 1.0); + rule2.addOutput("++//&&[F]", 0.9); + rule2.addOutput("--**^^X#", 0.1) this.expansionRules.set("X", rule2); }; - // ADD variation in expansion rules and drawing rules + // TODO: ADD variation in drawing rules this.populateDrawingRules = () => { let pushRule: DrawingRule = new DrawingRule(); pushRule.addOutput(this.pushTurtle, 1.0); @@ -110,27 +112,33 @@ class LSystem { this.drawingRules.set("]", popRule); let rotateLeftXRule: DrawingRule = new DrawingRule(); - rotateLeftXRule.addOutput(this.turtle.rotateLeftX, 1.0); + rotateLeftXRule.addOutput(this.turtle.rotateLeftX, 0.9); + rotateLeftXRule.addOutput(this.turtle.rotateBigLeftX, 0.1); this.drawingRules.set("+", rotateLeftXRule); let rotateRightXRule: DrawingRule = new DrawingRule(); - rotateRightXRule.addOutput(this.turtle.rotateRightX, 1.0); + rotateRightXRule.addOutput(this.turtle.rotateRightX, 0.9); + rotateRightXRule.addOutput(this.turtle.rotateBigRightX, 0.1); this.drawingRules.set("-", rotateRightXRule); let rotatePosYRule: DrawingRule = new DrawingRule(); - rotatePosYRule.addOutput(this.turtle.rotatePosY, 1.0); + rotatePosYRule.addOutput(this.turtle.rotatePosY, 0.9); + rotatePosYRule.addOutput(this.turtle.rotateBigPosY, 0.1); this.drawingRules.set("*", rotatePosYRule); let rotateNegYRule: DrawingRule = new DrawingRule(); - rotateNegYRule.addOutput(this.turtle.rotateNegY, 1.0); + rotateNegYRule.addOutput(this.turtle.rotateNegY, 0.9); + rotateNegYRule.addOutput(this.turtle.rotateBigNegY, 0.1); this.drawingRules.set("/", rotateNegYRule); let rotatePosZRule: DrawingRule = new DrawingRule(); - rotatePosZRule.addOutput(this.turtle.rotatePosZ, 1.0); + rotatePosZRule.addOutput(this.turtle.rotatePosZ, 0.9); + rotatePosZRule.addOutput(this.turtle.rotateBigPosZ, 0.1); this.drawingRules.set("&", rotatePosZRule); let rotateNegZRule: DrawingRule = new DrawingRule(); - rotateNegZRule.addOutput(this.turtle.rotateNegZ, 1.0); + rotateNegZRule.addOutput(this.turtle.rotateNegZ, 0.9); + rotateNegZRule.addOutput(this.turtle.rotateBigNegZ, 0.1); this.drawingRules.set("^", rotateNegZRule); let forwardRule: DrawingRule = new DrawingRule(); diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index 24ca5fe..1459cb3 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -19,6 +19,12 @@ class Turtle { rotateNegY: () => void; rotatePosZ: () => void; rotateNegZ: () => void; + rotateBigRightX: () => void; + rotateBigLeftX: () => void; + rotateBigPosY: () => void; + rotateBigNegY: () => void; + rotateBigPosZ: () => void; + rotateBigNegZ: () => void; rotate: (axis: vec3, angle: number) => void; constructor(pos: vec3, orient: mat3) { @@ -111,6 +117,29 @@ class Turtle { this.rotateNegZ = () => { this.rotate(this.getRight(), -15); }; + this.rotateBigRightX = () => { + this.rotate(this.getUp(), -30); + }; + + this.rotateBigLeftX = () => { + this.rotate(this.getUp(), 30); + } + + this.rotateBigPosY = () => { + this.rotate(this.getForward(), 30); + } + + this.rotateBigNegY = () => { + this.rotate(this.getForward(), -30); + } + + this.rotateBigPosZ = () => { + this.rotate(this.getRight(), 30); + } + + this.rotateBigNegZ = () => { + this.rotate(this.getRight(), -30); + } } reset() { From 57cedb74c3e15fae972d94f8e7d922b7b893f90f Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Mon, 8 Nov 2021 22:22:29 -0500 Subject: [PATCH 21/34] procedural background --- src/shaders/flat-frag.glsl | 41 +++++++++++++++++++++++++++++++-- src/shaders/instanced-frag.glsl | 5 +++- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/shaders/flat-frag.glsl b/src/shaders/flat-frag.glsl index d3f05db..13a2412 100644 --- a/src/shaders/flat-frag.glsl +++ b/src/shaders/flat-frag.glsl @@ -8,7 +8,44 @@ uniform float u_Time; in vec2 fs_Pos; out vec4 out_Col; +vec3 rgb(vec3 color) { + return vec3(color.x / 255.0, color.y / 255.0, color.z / 255.0); +} + void main() { - out_Col = vec4(0.5 * (fs_Pos + vec2(1.0)), 0.0, 1.0); - out_Col = vec4(0.0, 0.0, 0.0, 1.0); + float yVal = fs_Pos.y; + float sinVal = sin(fs_Pos.x * 20.0 + u_Time / 75.0); + float dist = .2; + float start = .8; + + + // backdrop just in case of leaks + out_Col = vec4(rgb(vec3(242, 252, 255)), 1.0); + if(yVal < .05 * sinVal - start) { + out_Col = vec4(rgb(vec3(193, 242, 254)), 1.0); + } + if(yVal < .05 * sinVal + start) { + out_Col = vec4(rgb(vec3(144, 233, 255)), 1.0); + } + if(yVal < .05 * sinVal + (start - dist)) { + out_Col = vec4(rgb(vec3(95, 223, 255)), 1.0); + } + if(yVal < .05 * sinVal + (start - 2.0 * dist)) { + out_Col = vec4(rgb(vec3(46, 213, 255)), 1.0); + } + if(yVal < .05 * sinVal + (start - 3.0 * dist)) { + out_Col = vec4(rgb(vec3(0, 202, 252)), 1.0); + } + if(yVal < .05 * sinVal + (start - 4.0 * dist)) { + out_Col = vec4(rgb(vec3(0, 163, 204)), 1.0); + } + if(yVal < .05 * sinVal + (start - 5.0 * dist)) { + out_Col = vec4(rgb(vec3(0.0, 124.0, 155.0)), 1.0); + } + if(yVal < .05 * sinVal + (start - 6.0 * dist)) { + out_Col = vec4(rgb(vec3(0.0, 84.0, 106.0)), 1.0); + } + if(yVal < .05 * sinVal + (start - 7.0 * dist)) { + out_Col = vec4(rgb(vec3(0.0, 45.0, 57.0)), 1.0); + } } diff --git a/src/shaders/instanced-frag.glsl b/src/shaders/instanced-frag.glsl index 0b9308a..003040c 100644 --- a/src/shaders/instanced-frag.glsl +++ b/src/shaders/instanced-frag.glsl @@ -11,5 +11,8 @@ void main() // for falloff: // float dist = 1.0 - (length(fs_Pos.xyz) * 2.0); // out_Col = vec4(dist) * fs_Col; - out_Col = vec4(vec3(fs_Col) , 1.0); + // sample y position on a sine curve + vec4 inverse = vec4(1.0) - fs_Col; + float mixVal = sin(fs_Pos.y * 20.0); + out_Col = mix(inverse, fs_Col, 1.0 - mixVal); } From 691eded500bb9181ea8cd295efcb31da87531d7b Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Mon, 8 Nov 2021 22:45:35 -0500 Subject: [PATCH 22/34] adding some gui controls --- src/l-system/L-System.ts | 11 +++++++---- src/l-system/Turtle.ts | 29 +++++++++++++++-------------- src/main.ts | 22 ++++++++++++++++++++-- src/shaders/flat-frag.glsl | 2 ++ 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index 0592fdb..3e6e547 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -8,12 +8,13 @@ import OpenGLRenderer from "../rendering/gl/OpenGLRenderer"; class LSystem { turtleStack: Array = []; - turtle: Turtle = new Turtle(vec3.fromValues(50.0, 50.0, 0.0), mat3.create()); + turtle: Turtle = new Turtle(15, vec3.fromValues(50.0, 50.0, 0.0), mat3.create()); drawingRules: Map = new Map(); expansionRules: Map = new Map(); seed: string; axioms: Array = []; iterations: number = 2; + defaultAngle = 15; // Set up instanced rendering data arrays. branchCols1: Array = []; @@ -54,9 +55,11 @@ class LSystem { expandGrammar: () => void; makeTree: () => void; - constructor() { + constructor(iters : number, angle : number) { this.turtleStack = []; - this.turtle = new Turtle(vec3.fromValues(50.0, 50.0, 0.0), mat3.create()); + this.turtle = new Turtle(angle, vec3.fromValues(50.0, 50.0, 0.0), mat3.create()); + this.iterations = iters; + this.defaultAngle = angle; // define functions below to maintain context of "this" @@ -67,7 +70,7 @@ class LSystem { this.pushTurtle = () => { let newPos: vec3 = vec3.create(); let newOrient: mat3 = mat3.create(); - let newTurtle: Turtle = new Turtle( + let newTurtle: Turtle = new Turtle(angle, vec3.copy(newPos, this.turtle.position), mat3.copy(newOrient, this.turtle.orientation) ); diff --git a/src/l-system/Turtle.ts b/src/l-system/Turtle.ts index 1459cb3..c8c5f20 100644 --- a/src/l-system/Turtle.ts +++ b/src/l-system/Turtle.ts @@ -7,6 +7,7 @@ class Turtle { position: vec3 = vec3.fromValues(0.0, 0.0, 0.0); orientation: mat3 = mat3.create(); depth: number = 0; + angle : number = 15; getForward: () => vec3; getRight: () => vec3; @@ -27,10 +28,11 @@ class Turtle { rotateBigNegZ: () => void; rotate: (axis: vec3, angle: number) => void; - constructor(pos: vec3, orient: mat3) { + constructor(a : number, pos: vec3, orient: mat3) { this.position = pos; this.orientation = orient; this.depth = 0; + this.angle = a; this.getForward = () => { return vec3.fromValues( @@ -80,7 +82,6 @@ class Turtle { let offset = Math.sin(2.0 * rand); // multiply value by 10 offset = offset * 10.0; - console.log(offset); vec3.normalize(axis, axis); let radians = (PI * (angle + offset)) / 180.0; @@ -95,50 +96,50 @@ class Turtle { }; this.rotateRightX = () => { - this.rotate(this.getUp(), -15); + this.rotate(this.getUp(), -this.angle); }; this.rotateLeftX = () => { - this.rotate(this.getUp(), 15); + this.rotate(this.getUp(), this.angle); }; this.rotatePosY = () => { - this.rotate(this.getForward(), 15); + this.rotate(this.getForward(), this.angle); }; this.rotateNegY = () => { - this.rotate(this.getForward(), -15); + this.rotate(this.getForward(), -this.angle); }; this.rotatePosZ = () => { - this.rotate(this.getRight(), 15); + this.rotate(this.getRight(), this.angle); }; this.rotateNegZ = () => { - this.rotate(this.getRight(), -15); + this.rotate(this.getRight(), -this.angle); }; this.rotateBigRightX = () => { - this.rotate(this.getUp(), -30); + this.rotate(this.getUp(), -this.angle * 2.0); }; this.rotateBigLeftX = () => { - this.rotate(this.getUp(), 30); + this.rotate(this.getUp(), this.angle * 2.0); } this.rotateBigPosY = () => { - this.rotate(this.getForward(), 30); + this.rotate(this.getForward(), this.angle * 2.0); } this.rotateBigNegY = () => { - this.rotate(this.getForward(), -30); + this.rotate(this.getForward(), -this.angle * 2.0); } this.rotateBigPosZ = () => { - this.rotate(this.getRight(), 30); + this.rotate(this.getRight(), this.angle * 2.0); } this.rotateBigNegZ = () => { - this.rotate(this.getRight(), -30); + this.rotate(this.getRight(), -this.angle * 2.0); } } diff --git a/src/main.ts b/src/main.ts index b5c58f0..5d9b56a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,14 +13,21 @@ import { readTextFile } from "../src/globals"; // 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 = {}; +const controls = { + iterations: 3, + angle: 15 +}; let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; let branch: Mesh; let matrix: mat4 = mat4.create(); -let coral : LSystem = new LSystem(); +let coral : LSystem = new LSystem(4, 15); + +// controls: +let prevIters = 3; +let prevAngle = 15; function loadScene() { coral.makeTree(); @@ -40,6 +47,9 @@ function main() { // Add controls to the gui const gui = new DAT.GUI(); + gui.add(controls, 'iterations', 1, 5).step(1); + gui.add(controls, 'angle', 1, 20).step(1); + // get canvas and webgl context const canvas = document.getElementById("canvas"); @@ -76,6 +86,14 @@ function main() { // This function will be called every frame function tick() { + if (controls.iterations != prevIters || controls.angle != prevAngle) { + prevIters = controls.iterations; + prevAngle = controls.angle; + coral = new LSystem(controls.iterations, controls.angle); + coral.makeTree(); + + + } camera.update(); stats.begin(); instancedShader.setTime(time); diff --git a/src/shaders/flat-frag.glsl b/src/shaders/flat-frag.glsl index 13a2412..b45e593 100644 --- a/src/shaders/flat-frag.glsl +++ b/src/shaders/flat-frag.glsl @@ -48,4 +48,6 @@ void main() { if(yVal < .05 * sinVal + (start - 7.0 * dist)) { out_Col = vec4(rgb(vec3(0.0, 45.0, 57.0)), 1.0); } + // muten by some factor + out_Col = vec4(vec3(out_Col / 1.5), 1.0); } From 65e733925f7f1868fd031d79358dc203d1d6190f Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Tue, 9 Nov 2021 08:59:59 -0500 Subject: [PATCH 23/34] added gui, tweaked style --- src/l-system/L-System.ts | 31 +++++++++++++++++++---------- src/main.ts | 42 ++++++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 20 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index 3e6e547..0dc9118 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -8,13 +8,18 @@ import OpenGLRenderer from "../rendering/gl/OpenGLRenderer"; class LSystem { turtleStack: Array = []; - turtle: Turtle = new Turtle(15, vec3.fromValues(50.0, 50.0, 0.0), mat3.create()); + turtle: Turtle = new Turtle( + 15, + vec3.fromValues(50.0, 50.0, 0.0), + mat3.create() + ); drawingRules: Map = new Map(); expansionRules: Map = new Map(); seed: string; axioms: Array = []; iterations: number = 2; defaultAngle = 15; + scale = 1; // Set up instanced rendering data arrays. branchCols1: Array = []; @@ -55,11 +60,16 @@ class LSystem { expandGrammar: () => void; makeTree: () => void; - constructor(iters : number, angle : number) { + constructor(iters: number, angle: number, s: number) { this.turtleStack = []; - this.turtle = new Turtle(angle, vec3.fromValues(50.0, 50.0, 0.0), mat3.create()); + this.turtle = new Turtle( + angle, + vec3.fromValues(50.0, 50.0, 0.0), + mat3.create() + ); this.iterations = iters; this.defaultAngle = angle; + this.scale = s; // define functions below to maintain context of "this" @@ -70,7 +80,8 @@ class LSystem { this.pushTurtle = () => { let newPos: vec3 = vec3.create(); let newOrient: mat3 = mat3.create(); - let newTurtle: Turtle = new Turtle(angle, + let newTurtle: Turtle = new Turtle( + angle, vec3.copy(newPos, this.turtle.position), mat3.copy(newOrient, this.turtle.orientation) ); @@ -100,11 +111,10 @@ class LSystem { let rule2: ExpansionRule = new ExpansionRule(); rule2.addOutput("++//&&[F]", 0.9); - rule2.addOutput("--**^^X#", 0.1) + rule2.addOutput("--**^^X#", 0.1); this.expansionRules.set("X", rule2); }; - // TODO: ADD variation in drawing rules this.populateDrawingRules = () => { let pushRule: DrawingRule = new DrawingRule(); pushRule.addOutput(this.pushTurtle, 1.0); @@ -184,12 +194,13 @@ class LSystem { // Calculate transformation let transform: mat4 = mat4.create(); let q: quat = quat.create(); + let s : vec3 = vec3.scale(vec3.create(), vec3.fromValues(6.5, 6.5, 6.5), this.scale); quat.fromMat3(q, this.turtle.orientation); mat4.fromRotationTranslationScale( transform, q, this.turtle.position, - vec3.fromValues(2.5, 2.5, 2.5) + s ); for (let i = 0; i < 4; i++) { this.leafCols1.push(transform[i]); @@ -293,9 +304,9 @@ class LSystem { this.turtle.moveForward(); this.putBranch( vec3.fromValues( - 1.5 - this.turtle.depth * 0.05, - 3.5, - 1.5 - this.turtle.depth * 0.05 + 6.5 - this.turtle.depth * 0.85, + 8.0, + 6.5 - this.turtle.depth * 0.85 ) ); }; diff --git a/src/main.ts b/src/main.ts index 5d9b56a..d99df30 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { vec3, mat4 } from "gl-matrix"; +import { vec3, mat4, vec4 } from "gl-matrix"; import * as Stats from "stats-js"; import * as DAT from "dat-gui"; import Square from "./geometry/Square"; @@ -11,25 +11,39 @@ import Mesh from "./geometry/Mesh"; import LSystem from './l-system/L-System' import { readTextFile } from "../src/globals"; -// 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 = { - iterations: 3, - angle: 15 -}; let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; let branch: Mesh; let matrix: mat4 = mat4.create(); -let coral : LSystem = new LSystem(4, 15); +let coral : LSystem = new LSystem(4, 15, 1); + + +// 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 = { + iterations: 3, + angle: 15, + decoration_scale: 1, + 'Generate' : loadScene +}; + +var palette = { + color1: [0.0, 0.122 * 255.0, 0.58 * 255.0], // ocean + color2: [255.0 * 0.761, 255.0 * 0.698, 255.0 * 0.502], // sand +}; + // controls: let prevIters = 3; let prevAngle = 15; +let prevScale = 1; +let prevColor1 : vec4 = vec4.fromValues(palette.color1[0], palette.color1[1], palette.color1[2], 1.0); +let prevColor2 : vec4 = vec4.fromValues(palette.color2[0], palette.color2[1], palette.color2[2], 1.0); function loadScene() { + coral = new LSystem(controls.iterations, controls.angle, controls.decoration_scale); coral.makeTree(); screenQuad = new ScreenQuad(); @@ -49,6 +63,12 @@ function main() { const gui = new DAT.GUI(); gui.add(controls, 'iterations', 1, 5).step(1); gui.add(controls, 'angle', 1, 20).step(1); + gui.add(controls, 'decoration_scale', 0, 3).step(.1); + gui.addColor(palette, 'color1'); + gui.addColor(palette, 'color2'); + gui.add(controls, 'Generate'); + + // get canvas and webgl context @@ -86,10 +106,12 @@ function main() { // This function will be called every frame function tick() { - if (controls.iterations != prevIters || controls.angle != prevAngle) { + if (controls.iterations != prevIters || controls.angle != prevAngle + || controls.decoration_scale != prevScale) { prevIters = controls.iterations; prevAngle = controls.angle; - coral = new LSystem(controls.iterations, controls.angle); + prevScale = controls.decoration_scale; + coral = new LSystem(controls.iterations, controls.angle, controls.decoration_scale); coral.makeTree(); From cb9833f5b91a15a2bae8b5c3c280739fa84aa707 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Tue, 9 Nov 2021 09:55:09 -0500 Subject: [PATCH 24/34] added color change in gui --- src/l-system/L-System.ts | 20 ++++++++++++-------- src/main.ts | 37 +++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/l-system/L-System.ts b/src/l-system/L-System.ts index 0dc9118..b0b540e 100644 --- a/src/l-system/L-System.ts +++ b/src/l-system/L-System.ts @@ -3,7 +3,7 @@ import ExpansionRule from "./ExpansionRule"; import Turtle from "./Turtle"; import Mesh from "../geometry/Mesh"; import { readTextFile } from "../globals"; -import { vec3, mat4, quat, mat3 } from "gl-matrix"; +import { vec3, mat4, quat, mat3, vec4 } from "gl-matrix"; import OpenGLRenderer from "../rendering/gl/OpenGLRenderer"; class LSystem { @@ -20,6 +20,8 @@ class LSystem { iterations: number = 2; defaultAngle = 15; scale = 1; + color1 = vec4.fromValues(255 / 255, 127.0 / 255.0, 80.0 / 255.0, 1.0); + color2 = vec4.fromValues(57 / 255.0, 217 /255.0, 222 / 255.0, 1.0); // Set up instanced rendering data arrays. branchCols1: Array = []; @@ -60,7 +62,7 @@ class LSystem { expandGrammar: () => void; makeTree: () => void; - constructor(iters: number, angle: number, s: number) { + constructor(iters: number, angle: number, s: number, col1 : vec4, col2 : vec4) { this.turtleStack = []; this.turtle = new Turtle( angle, @@ -70,6 +72,8 @@ class LSystem { this.iterations = iters; this.defaultAngle = angle; this.scale = s; + this.color1 = col1; + this.color2 = col2; // define functions below to maintain context of "this" @@ -181,9 +185,9 @@ class LSystem { this.branchCols4.push(transform[12 + i]); } - this.branchColorsBO.push(255 / 255); - this.branchColorsBO.push(127 / 255); - this.branchColorsBO.push(80 / 255); + this.branchColorsBO.push(this.color1[0] / 255.0); + this.branchColorsBO.push(this.color1[1] / 255.0); + this.branchColorsBO.push(this.color1[2] / 255.0); this.branchColorsBO.push(1.0); this.branchNum++; }; @@ -209,9 +213,9 @@ class LSystem { this.leafCols4.push(transform[12 + i]); } - this.leafColorsBO.push(57 / 255); - this.leafColorsBO.push(217 / 255); - this.leafColorsBO.push(222 / 255); + this.leafColorsBO.push(this.color2[0] / 255.0); + this.leafColorsBO.push(this.color2[1] / 255.0); + this.leafColorsBO.push(this.color2[2] / 255.0); this.leafColorsBO.push(1.0); this.leafNum++; }; diff --git a/src/main.ts b/src/main.ts index d99df30..a9749ec 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,12 +12,24 @@ import LSystem from './l-system/L-System' import { readTextFile } from "../src/globals"; +var palette = { + color1: [255, 127.0, 80.0, 1.0], // branch + color2: [57, 217, 222, 1.0], // leaf +}; + +// controls: +let prevIters = 3; +let prevAngle = 15; +let prevScale = 1; +let prevColor1 : vec4 = vec4.fromValues(palette.color1[0], palette.color1[1], palette.color1[2], 1.0); +let prevColor2 : vec4 = vec4.fromValues(palette.color2[0], palette.color2[1], palette.color2[2], 1.0); + let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; let branch: Mesh; let matrix: mat4 = mat4.create(); -let coral : LSystem = new LSystem(4, 15, 1); +let coral : LSystem = new LSystem(4, 15, 1, prevColor1, prevColor2); // Define an object with application parameters and button callbacks @@ -29,21 +41,11 @@ const controls = { 'Generate' : loadScene }; -var palette = { - color1: [0.0, 0.122 * 255.0, 0.58 * 255.0], // ocean - color2: [255.0 * 0.761, 255.0 * 0.698, 255.0 * 0.502], // sand -}; -// controls: -let prevIters = 3; -let prevAngle = 15; -let prevScale = 1; -let prevColor1 : vec4 = vec4.fromValues(palette.color1[0], palette.color1[1], palette.color1[2], 1.0); -let prevColor2 : vec4 = vec4.fromValues(palette.color2[0], palette.color2[1], palette.color2[2], 1.0); function loadScene() { - coral = new LSystem(controls.iterations, controls.angle, controls.decoration_scale); + coral = new LSystem(controls.iterations, controls.angle, controls.decoration_scale, prevColor1, prevColor2); coral.makeTree(); screenQuad = new ScreenQuad(); @@ -104,14 +106,21 @@ function main() { new Shader(gl.FRAGMENT_SHADER, require("./shaders/flat-frag.glsl")), ]); + function vec4Equals(a : vec4, b : vec4) { + return vec4.len(vec4.subtract(vec4.create(), a, b)) < .1; + } + // This function will be called every frame function tick() { if (controls.iterations != prevIters || controls.angle != prevAngle - || controls.decoration_scale != prevScale) { + || controls.decoration_scale != prevScale || !vec4Equals(prevColor1, vec4.fromValues(palette.color1[0], palette.color1[1], palette.color1[2], 1.0)) + || !vec4Equals(prevColor2, vec4.fromValues(palette.color2[0], palette.color2[1], palette.color2[2], 1.0))) { prevIters = controls.iterations; prevAngle = controls.angle; prevScale = controls.decoration_scale; - coral = new LSystem(controls.iterations, controls.angle, controls.decoration_scale); + prevColor1 = vec4.fromValues(palette.color1[0], palette.color1[1], palette.color1[2], 1.0); + prevColor2 = vec4.fromValues(palette.color2[0], palette.color2[1], palette.color2[2], 1.0); + coral = new LSystem(controls.iterations, controls.angle, controls.decoration_scale, prevColor1, prevColor2); coral.makeTree(); From 045754c15e4aefcc79a496074e590991e7e49279 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Tue, 9 Nov 2021 18:57:26 -0500 Subject: [PATCH 25/34] fixed transparency and colors --- src/main.ts | 1 - src/shaders/instanced-frag.glsl | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main.ts b/src/main.ts index a9749ec..15794ea 100644 --- a/src/main.ts +++ b/src/main.ts @@ -93,7 +93,6 @@ function main() { const renderer = new OpenGLRenderer(canvas); renderer.setClearColor(0.2, 0.2, 0.2, 1); - gl.enable(gl.BLEND); gl.blendFunc(gl.ONE, gl.ONE); // Additive blending const instancedShader = new ShaderProgram([ diff --git a/src/shaders/instanced-frag.glsl b/src/shaders/instanced-frag.glsl index 003040c..fa7b4a1 100644 --- a/src/shaders/instanced-frag.glsl +++ b/src/shaders/instanced-frag.glsl @@ -12,7 +12,7 @@ void main() // float dist = 1.0 - (length(fs_Pos.xyz) * 2.0); // out_Col = vec4(dist) * fs_Col; // sample y position on a sine curve - vec4 inverse = vec4(1.0) - fs_Col; + vec4 inverse = vec4(vec3(vec4(1.0) - fs_Col), 1.0); float mixVal = sin(fs_Pos.y * 20.0); out_Col = mix(inverse, fs_Col, 1.0 - mixVal); } From b3f5635ed1f3333e825c738dc33449220363f7b3 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Tue, 9 Nov 2021 19:45:05 -0500 Subject: [PATCH 26/34] base added --- resources/base.mtl | 10 ++ resources/base.obj | 285 +++++++++++++++++++++++++++++++++++++++++++++ src/main.ts | 137 ++++++++++++++++------ 3 files changed, 398 insertions(+), 34 deletions(-) create mode 100644 resources/base.mtl create mode 100644 resources/base.obj diff --git a/resources/base.mtl b/resources/base.mtl new file mode 100644 index 0000000..f231bdf --- /dev/null +++ b/resources/base.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/resources/base.obj b/resources/base.obj new file mode 100644 index 0000000..a66ab5b --- /dev/null +++ b/resources/base.obj @@ -0,0 +1,285 @@ +# Blender v2.83.0 OBJ File: '' +# www.blender.org +mtllib base.mtl +o Sphere +v 0.000000 0.707107 -1.580931 +v 0.000000 0.382683 -2.065585 +v 0.327421 0.923880 -0.790465 +v 0.604996 0.707107 -1.460589 +v 0.790465 0.382683 -1.908352 +v 0.855593 -0.000000 -2.065585 +v 0.604996 0.923880 -0.604996 +v 1.117887 0.707107 -1.117887 +v 1.460589 0.382683 -1.460589 +v 1.580930 -0.000000 -1.580931 +v 0.790465 0.923880 -0.327422 +v 1.460589 0.707107 -0.604996 +v 1.908352 0.382683 -0.790465 +v 2.065585 -0.000000 -0.855593 +v 0.855593 0.923880 -0.000000 +v 1.580930 0.707107 -0.000000 +v 2.065585 0.382683 -0.000000 +v 2.235773 -0.000000 -0.000000 +v 0.790465 0.923880 0.327421 +v 1.460589 0.707107 0.604996 +v 1.908352 0.382683 0.790465 +v 2.065585 -0.000000 0.855593 +v 0.604996 0.923880 0.604995 +v 1.117886 0.707107 1.117886 +v 1.460589 0.382683 1.460589 +v 1.580930 -0.000000 1.580930 +v 0.327421 0.923880 0.790465 +v 0.604995 0.707107 1.460589 +v 0.790465 0.382683 1.908352 +v 0.855593 -0.000000 2.065585 +v -0.000000 0.923880 0.855593 +v -0.000001 0.707107 1.580930 +v -0.000001 0.382683 2.065585 +v -0.000001 -0.000000 2.235773 +v -0.327422 0.923880 0.790465 +v -0.604996 0.707107 1.460588 +v -0.790466 0.382683 1.908351 +v -0.855594 -0.000000 2.065584 +v -0.604996 0.923880 0.604995 +v -1.117887 0.707107 1.117885 +v -1.460590 0.382683 1.460588 +v -1.580931 -0.000000 1.580929 +v -0.790465 0.923880 0.327421 +v -1.460589 0.707107 0.604995 +v -1.908352 0.382683 0.790464 +v -2.065585 -0.000000 0.855592 +v -0.855593 0.923880 -0.000001 +v -1.580930 0.707107 -0.000001 +v -2.065585 0.382683 -0.000001 +v -2.235773 -0.000000 -0.000001 +v -0.790465 0.923880 -0.327422 +v -1.460588 0.707107 -0.604997 +v -1.908351 0.382683 -0.790466 +v -2.065584 -0.000000 -0.855595 +v -0.604995 0.923880 -0.604996 +v -1.117886 0.707107 -1.117887 +v -1.460588 0.382683 -1.460590 +v -1.580929 -0.000000 -1.580931 +v -0.327421 0.923880 -0.790465 +v -0.604995 0.707107 -1.460589 +v -0.790464 0.382683 -1.908352 +v -0.855592 -0.000000 -2.065585 +v -0.000000 1.000000 -0.000000 +v 0.000000 0.923880 -0.855593 +v 0.000001 -0.000000 -2.235773 +vt 0.750000 0.500000 +vt 0.750000 0.625000 +vt 0.687500 0.625000 +vt 0.687500 0.500000 +vt 0.750000 0.750000 +vt 0.750000 0.875000 +vt 0.687500 0.875000 +vt 0.687500 0.750000 +vt 0.718750 1.000000 +vt 0.625000 0.750000 +vt 0.625000 0.625000 +vt 0.656250 1.000000 +vt 0.625000 0.875000 +vt 0.625000 0.500000 +vt 0.562500 0.750000 +vt 0.562500 0.625000 +vt 0.593750 1.000000 +vt 0.562500 0.875000 +vt 0.562500 0.500000 +vt 0.500000 0.625000 +vt 0.500000 0.500000 +vt 0.500000 0.875000 +vt 0.500000 0.750000 +vt 0.531250 1.000000 +vt 0.437500 0.875000 +vt 0.437500 0.750000 +vt 0.437500 0.625000 +vt 0.468750 1.000000 +vt 0.437500 0.500000 +vt 0.375000 0.750000 +vt 0.375000 0.625000 +vt 0.406250 1.000000 +vt 0.375000 0.875000 +vt 0.375000 0.500000 +vt 0.343750 1.000000 +vt 0.312500 0.875000 +vt 0.312500 0.625000 +vt 0.312500 0.500000 +vt 0.312500 0.750000 +vt 0.250000 0.625000 +vt 0.250000 0.500000 +vt 0.250000 0.875000 +vt 0.250000 0.750000 +vt 0.281250 1.000000 +vt 0.187500 0.750000 +vt 0.187500 0.625000 +vt 0.218750 1.000000 +vt 0.187500 0.875000 +vt 0.187500 0.500000 +vt 0.125000 0.750000 +vt 0.125000 0.625000 +vt 0.156250 1.000000 +vt 0.125000 0.875000 +vt 0.125000 0.500000 +vt 0.062500 0.625000 +vt 0.062500 0.500000 +vt 0.062500 0.875000 +vt 0.062500 0.750000 +vt 0.093750 1.000000 +vt 0.000000 0.625000 +vt 0.000000 0.500000 +vt 0.000000 0.875000 +vt 0.000000 0.750000 +vt 0.031250 1.000000 +vt 1.000000 0.625000 +vt 1.000000 0.750000 +vt 0.937500 0.750000 +vt 0.937500 0.625000 +vt 1.000000 0.875000 +vt 0.968750 1.000000 +vt 0.937500 0.875000 +vt 1.000000 0.500000 +vt 0.937500 0.500000 +vt 0.875000 0.750000 +vt 0.875000 0.625000 +vt 0.906250 1.000000 +vt 0.875000 0.875000 +vt 0.875000 0.500000 +vt 0.812500 0.625000 +vt 0.812500 0.500000 +vt 0.812500 0.875000 +vt 0.812500 0.750000 +vt 0.843750 1.000000 +vt 0.781250 1.000000 +vn 0.1788 0.3998 -0.8990 +vn 0.0569 0.9566 -0.2859 +vn 0.1100 0.8260 -0.5529 +vn 0.0176 0.9959 -0.0886 +vn 0.3132 0.8260 -0.4687 +vn 0.0502 0.9959 -0.0751 +vn 0.5092 0.3998 -0.7621 +vn 0.1619 0.9566 -0.2424 +vn 0.4687 0.8260 -0.3132 +vn 0.0751 0.9959 -0.0502 +vn 0.7621 0.3998 -0.5092 +vn 0.2424 0.9566 -0.1619 +vn 0.8990 0.3998 -0.1788 +vn 0.2859 0.9566 -0.0569 +vn 0.5529 0.8260 -0.1100 +vn 0.0886 0.9959 -0.0176 +vn 0.2859 0.9566 0.0569 +vn 0.5529 0.8260 0.1100 +vn 0.0886 0.9959 0.0176 +vn 0.8990 0.3998 0.1788 +vn 0.4687 0.8260 0.3132 +vn 0.0751 0.9959 0.0502 +vn 0.7621 0.3998 0.5092 +vn 0.2424 0.9566 0.1619 +vn 0.0502 0.9959 0.0751 +vn 0.5092 0.3998 0.7621 +vn 0.1619 0.9566 0.2424 +vn 0.3132 0.8260 0.4687 +vn 0.1788 0.3998 0.8990 +vn 0.0569 0.9566 0.2859 +vn 0.1100 0.8260 0.5529 +vn 0.0176 0.9959 0.0886 +vn -0.1100 0.8260 0.5529 +vn -0.0176 0.9959 0.0886 +vn -0.1788 0.3998 0.8990 +vn -0.0569 0.9566 0.2859 +vn -0.3132 0.8260 0.4687 +vn -0.0502 0.9959 0.0751 +vn -0.5092 0.3998 0.7621 +vn -0.1619 0.9566 0.2424 +vn -0.7621 0.3998 0.5092 +vn -0.2424 0.9566 0.1619 +vn -0.4687 0.8260 0.3132 +vn -0.0751 0.9959 0.0502 +vn -0.8990 0.3998 0.1788 +vn -0.2859 0.9566 0.0569 +vn -0.5529 0.8260 0.1100 +vn -0.0886 0.9959 0.0176 +vn -0.5529 0.8260 -0.1100 +vn -0.0886 0.9959 -0.0176 +vn -0.8990 0.3998 -0.1788 +vn -0.2859 0.9566 -0.0569 +vn -0.4687 0.8260 -0.3132 +vn -0.0751 0.9959 -0.0502 +vn -0.7621 0.3998 -0.5092 +vn -0.2424 0.9566 -0.1619 +vn -0.5092 0.3998 -0.7621 +vn -0.1619 0.9566 -0.2424 +vn 0.0000 -1.0000 0.0000 +vn -0.3132 0.8260 -0.4687 +vn -0.0502 0.9959 -0.0751 +vn -0.0569 0.9566 -0.2859 +vn -0.1100 0.8260 -0.5529 +vn -0.0176 0.9959 -0.0886 +vn -0.1788 0.3998 -0.8990 +usemtl None +s off +f 65/1/1 2/2/1 5/3/1 6/4/1 +f 1/5/2 64/6/2 3/7/2 4/8/2 +f 2/2/3 1/5/3 4/8/3 5/3/3 +f 64/6/4 63/9/4 3/7/4 +f 5/3/5 4/8/5 8/10/5 9/11/5 +f 3/7/6 63/12/6 7/13/6 +f 6/4/7 5/3/7 9/11/7 10/14/7 +f 4/8/8 3/7/8 7/13/8 8/10/8 +f 9/11/9 8/10/9 12/15/9 13/16/9 +f 7/13/10 63/17/10 11/18/10 +f 10/14/11 9/11/11 13/16/11 14/19/11 +f 8/10/12 7/13/12 11/18/12 12/15/12 +f 14/19/13 13/16/13 17/20/13 18/21/13 +f 12/15/14 11/18/14 15/22/14 16/23/14 +f 13/16/15 12/15/15 16/23/15 17/20/15 +f 11/18/16 63/24/16 15/22/16 +f 16/23/17 15/22/17 19/25/17 20/26/17 +f 17/20/18 16/23/18 20/26/18 21/27/18 +f 15/22/19 63/28/19 19/25/19 +f 18/21/20 17/20/20 21/27/20 22/29/20 +f 21/27/21 20/26/21 24/30/21 25/31/21 +f 19/25/22 63/32/22 23/33/22 +f 22/29/23 21/27/23 25/31/23 26/34/23 +f 20/26/24 19/25/24 23/33/24 24/30/24 +f 23/33/25 63/35/25 27/36/25 +f 26/34/26 25/31/26 29/37/26 30/38/26 +f 24/30/27 23/33/27 27/36/27 28/39/27 +f 25/31/28 24/30/28 28/39/28 29/37/28 +f 30/38/29 29/37/29 33/40/29 34/41/29 +f 28/39/30 27/36/30 31/42/30 32/43/30 +f 29/37/31 28/39/31 32/43/31 33/40/31 +f 27/36/32 63/44/32 31/42/32 +f 33/40/33 32/43/33 36/45/33 37/46/33 +f 31/42/34 63/47/34 35/48/34 +f 34/41/35 33/40/35 37/46/35 38/49/35 +f 32/43/36 31/42/36 35/48/36 36/45/36 +f 37/46/37 36/45/37 40/50/37 41/51/37 +f 35/48/38 63/52/38 39/53/38 +f 38/49/39 37/46/39 41/51/39 42/54/39 +f 36/45/40 35/48/40 39/53/40 40/50/40 +f 42/54/41 41/51/41 45/55/41 46/56/41 +f 40/50/42 39/53/42 43/57/42 44/58/42 +f 41/51/43 40/50/43 44/58/43 45/55/43 +f 39/53/44 63/59/44 43/57/44 +f 46/56/45 45/55/45 49/60/45 50/61/45 +f 44/58/46 43/57/46 47/62/46 48/63/46 +f 45/55/47 44/58/47 48/63/47 49/60/47 +f 43/57/48 63/64/48 47/62/48 +f 49/65/49 48/66/49 52/67/49 53/68/49 +f 47/69/50 63/70/50 51/71/50 +f 50/72/51 49/65/51 53/68/51 54/73/51 +f 48/66/52 47/69/52 51/71/52 52/67/52 +f 53/68/53 52/67/53 56/74/53 57/75/53 +f 51/71/54 63/76/54 55/77/54 +f 54/73/55 53/68/55 57/75/55 58/78/55 +f 52/67/56 51/71/56 55/77/56 56/74/56 +f 58/78/57 57/75/57 61/79/57 62/80/57 +f 56/74/58 55/77/58 59/81/58 60/82/58 +f 6/4/59 10/14/59 14/19/59 18/21/59 22/29/59 26/34/59 30/38/59 34/41/59 38/49/59 42/54/59 46/56/59 50/72/59 54/73/59 58/78/59 62/80/59 65/1/59 +f 57/75/60 56/74/60 60/82/60 61/79/60 +f 55/77/61 63/83/61 59/81/61 +f 60/82/62 59/81/62 64/6/62 1/5/62 +f 61/79/63 60/82/63 1/5/63 2/2/63 +f 59/81/64 63/84/64 64/6/64 +f 62/80/65 61/79/65 2/2/65 65/1/65 diff --git a/src/main.ts b/src/main.ts index 15794ea..b66d9e7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,29 +8,61 @@ import Camera from "./Camera"; import { setGL } from "./globals"; import ShaderProgram, { Shader } from "./rendering/gl/ShaderProgram"; import Mesh from "./geometry/Mesh"; -import LSystem from './l-system/L-System' +import LSystem from "./l-system/L-System"; import { readTextFile } from "../src/globals"; - var palette = { color1: [255, 127.0, 80.0, 1.0], // branch color2: [57, 217, 222, 1.0], // leaf }; -// controls: +// controls: let prevIters = 3; let prevAngle = 15; let prevScale = 1; -let prevColor1 : vec4 = vec4.fromValues(palette.color1[0], palette.color1[1], palette.color1[2], 1.0); -let prevColor2 : vec4 = vec4.fromValues(palette.color2[0], palette.color2[1], palette.color2[2], 1.0); +let prevColor1: vec4 = vec4.fromValues( + palette.color1[0], + palette.color1[1], + palette.color1[2], + 1.0 +); +let prevColor2: vec4 = vec4.fromValues( + palette.color2[0], + palette.color2[1], + palette.color2[2], + 1.0 +); let square: Square; let screenQuad: ScreenQuad; let time: number = 0.0; let branch: Mesh; let matrix: mat4 = mat4.create(); -let coral : LSystem = new LSystem(4, 15, 1, prevColor1, prevColor2); +let coral: LSystem = new LSystem(4, 15, 1, prevColor1, prevColor2); +let base: Mesh = new Mesh( + readTextFile("resources/base.obj"), + vec3.fromValues(50, 50, 0) +); + +function putBase() { + base.create(); + + let base1 = [10, 0, 0, 0]; + let base2 = [0, 10, 0, 0]; + let base3 = [0, 0, 10, 0]; + let base4 = [50, 43, 0, 1]; + + let cols = [0.761, 0.698, 0.502, 1.0]; + + let bCol1: Float32Array = new Float32Array(base1); + let bCol2: Float32Array = new Float32Array(base2); + let bCol3: Float32Array = new Float32Array(base3); + let bCol4: Float32Array = new Float32Array(base4); + let bcolors: Float32Array = new Float32Array(cols); + base.setInstanceVBOs(bCol1, bCol2, bCol3, bCol4, bcolors); + base.setNumInstances(1); +} // Define an object with application parameters and button callbacks // This will be referred to by dat.GUI's functions that add GUI elements. @@ -38,16 +70,25 @@ const controls = { iterations: 3, angle: 15, decoration_scale: 1, - 'Generate' : loadScene + Generate: loadScene, }; - - - function loadScene() { - coral = new LSystem(controls.iterations, controls.angle, controls.decoration_scale, prevColor1, prevColor2); + coral = new LSystem( + controls.iterations, + controls.angle, + controls.decoration_scale, + prevColor1, + prevColor2 + ); coral.makeTree(); + base = new Mesh( + readTextFile("resources/base.obj"), + vec3.fromValues(50, 50, 0) + ); + putBase(); + screenQuad = new ScreenQuad(); screenQuad.create(); } @@ -63,15 +104,12 @@ function main() { // Add controls to the gui const gui = new DAT.GUI(); - gui.add(controls, 'iterations', 1, 5).step(1); - gui.add(controls, 'angle', 1, 20).step(1); - gui.add(controls, 'decoration_scale', 0, 3).step(.1); - gui.addColor(palette, 'color1'); - gui.addColor(palette, 'color2'); - gui.add(controls, 'Generate'); - - - + gui.add(controls, "iterations", 1, 5).step(1); + gui.add(controls, "angle", 1, 20).step(1); + gui.add(controls, "decoration_scale", 0, 3).step(0.1); + gui.addColor(palette, "color1"); + gui.addColor(palette, "color2"); + gui.add(controls, "Generate"); // get canvas and webgl context const canvas = document.getElementById("canvas"); @@ -105,24 +143,58 @@ function main() { new Shader(gl.FRAGMENT_SHADER, require("./shaders/flat-frag.glsl")), ]); - function vec4Equals(a : vec4, b : vec4) { - return vec4.len(vec4.subtract(vec4.create(), a, b)) < .1; + function vec4Equals(a: vec4, b: vec4) { + return vec4.len(vec4.subtract(vec4.create(), a, b)) < 0.1; } // This function will be called every frame function tick() { - if (controls.iterations != prevIters || controls.angle != prevAngle - || controls.decoration_scale != prevScale || !vec4Equals(prevColor1, vec4.fromValues(palette.color1[0], palette.color1[1], palette.color1[2], 1.0)) - || !vec4Equals(prevColor2, vec4.fromValues(palette.color2[0], palette.color2[1], palette.color2[2], 1.0))) { + if ( + controls.iterations != prevIters || + controls.angle != prevAngle || + controls.decoration_scale != prevScale || + !vec4Equals( + prevColor1, + vec4.fromValues( + palette.color1[0], + palette.color1[1], + palette.color1[2], + 1.0 + ) + ) || + !vec4Equals( + prevColor2, + vec4.fromValues( + palette.color2[0], + palette.color2[1], + palette.color2[2], + 1.0 + ) + ) + ) { prevIters = controls.iterations; prevAngle = controls.angle; prevScale = controls.decoration_scale; - prevColor1 = vec4.fromValues(palette.color1[0], palette.color1[1], palette.color1[2], 1.0); - prevColor2 = vec4.fromValues(palette.color2[0], palette.color2[1], palette.color2[2], 1.0); - coral = new LSystem(controls.iterations, controls.angle, controls.decoration_scale, prevColor1, prevColor2); + prevColor1 = vec4.fromValues( + palette.color1[0], + palette.color1[1], + palette.color1[2], + 1.0 + ); + prevColor2 = vec4.fromValues( + palette.color2[0], + palette.color2[1], + palette.color2[2], + 1.0 + ); + coral = new LSystem( + controls.iterations, + controls.angle, + controls.decoration_scale, + prevColor1, + prevColor2 + ); coral.makeTree(); - - } camera.update(); stats.begin(); @@ -131,10 +203,7 @@ function main() { gl.viewport(0, 0, window.innerWidth, window.innerHeight); renderer.clear(); renderer.render(camera, flat, [screenQuad]); - renderer.render(camera, instancedShader, [ - coral.branch, - coral.leaf - ]); + renderer.render(camera, instancedShader, [coral.branch, coral.leaf, base]); stats.end(); // Tell the browser to call `tick` again whenever it renders a new frame From aa4b18b619ce1c6b50265a7c34653ad2db675786 Mon Sep 17 00:00:00 2001 From: Serena Gandhi Date: Tue, 9 Nov 2021 19:47:24 -0500 Subject: [PATCH 27/34] lil adjustments --- src/main.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main.ts b/src/main.ts index b66d9e7..dde3a9b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -47,10 +47,10 @@ let base: Mesh = new Mesh( function putBase() { base.create(); - let base1 = [10, 0, 0, 0]; + let base1 = [15, 0, 0, 0]; let base2 = [0, 10, 0, 0]; - let base3 = [0, 0, 10, 0]; - let base4 = [50, 43, 0, 1]; + let base3 = [0, 0, 15, 0]; + let base4 = [50, 42, 0, 1]; let cols = [0.761, 0.698, 0.502, 1.0]; From 4adb7f514c943859cb67b8c9d10efa4951d0507e Mon Sep 17 00:00:00 2001 From: serenag01 <70620606+serenag01@users.noreply.github.com> Date: Wed, 10 Nov 2021 07:33:34 -0500 Subject: [PATCH 28/34] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 1c009a6..9ba1356 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,14 @@ +# L-systems Coral + +## Serena Gandhi (gserena) +## Link: https://gserena01.github.io/hw04-l-systems/ + +# Samples of L-System Using Tools: + +2D L-System Visualizer: ![image](https://user-images.githubusercontent.com/60444726/138163560-f8537878-23f3-4a77-aae0-31b7e6201581.png) +Houdini: ![Screenshot 2021-10-20 200324](https://user-images.githubusercontent.com/60444726/138274074-d694a82b-69f7-44e3-a6fc-c970d17ae49c.png) # Reference Images: From bafc74bf35d91cbd6704e3d0a560fe891ccd55f8 Mon Sep 17 00:00:00 2001 From: serenag01 <70620606+serenag01@users.noreply.github.com> Date: Wed, 10 Nov 2021 07:48:24 -0500 Subject: [PATCH 29/34] Update README.md --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 9ba1356..397c819 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,29 @@ ## Serena Gandhi (gserena) ## Link: https://gserena01.github.io/hw04-l-systems/ +# Sample Images: + +Using Defaults: + +![image](https://user-images.githubusercontent.com/70620606/141114197-943c1a9b-8b4b-4fd5-955d-5a7ab70e2690.png) + +With Color and Decoration Size Change: + +![image](https://user-images.githubusercontent.com/70620606/141115420-030dba2a-7b8e-4824-b2ab-2fa850b5f5ec.png) + +With Iterations and Angle Change: + +![image](https://user-images.githubusercontent.com/70620606/141115687-21989520-a6ba-420d-b907-5d93a2c7465a.png) + + # Samples of L-System Using Tools: 2D L-System Visualizer: + ![image](https://user-images.githubusercontent.com/60444726/138163560-f8537878-23f3-4a77-aae0-31b7e6201581.png) Houdini: + ![Screenshot 2021-10-20 200324](https://user-images.githubusercontent.com/60444726/138274074-d694a82b-69f7-44e3-a6fc-c970d17ae49c.png) # Reference Images: @@ -25,6 +42,8 @@ Using Callback Functions: https://stackoverflow.com/questions/14471975/how-can-i L-System Visualizer: https://www.kevs3d.co.uk/dev/lsystems/ +Color Palette: https://icolorpalette.com/color/ocean-blue + # Homework 4: L-systems From bf072e84a08f8b8c533c973cebd2d864316b303d Mon Sep 17 00:00:00 2001 From: serenag01 <70620606+serenag01@users.noreply.github.com> Date: Wed, 10 Nov 2021 08:05:01 -0500 Subject: [PATCH 30/34] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 397c819..a8c2162 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ With Iterations and Angle Change: ![image](https://user-images.githubusercontent.com/70620606/141115687-21989520-a6ba-420d-b907-5d93a2c7465a.png) +The Tool in Action: + +https://user-images.githubusercontent.com/70620606/141118237-24d21cf8-ae9f-4f39-bc3b-92cce27468b0.mp4 + # Samples of L-System Using Tools: From d8fa22a35d7390f0cbb3e19df2b1263bcca71820 Mon Sep 17 00:00:00 2001 From: serenag01 <70620606+serenag01@users.noreply.github.com> Date: Wed, 10 Nov 2021 08:05:53 -0500 Subject: [PATCH 31/34] Create INSTRUCTIONS.md --- INSTRUCTIONS.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 INSTRUCTIONS.md diff --git a/INSTRUCTIONS.md b/INSTRUCTIONS.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/INSTRUCTIONS.md @@ -0,0 +1 @@ + From 612530071fe8b9218a200967ebf8cee1e3447129 Mon Sep 17 00:00:00 2001 From: serenag01 <70620606+serenag01@users.noreply.github.com> Date: Wed, 10 Nov 2021 08:06:16 -0500 Subject: [PATCH 32/34] Update README.md --- README.md | 132 ------------------------------------------------------ 1 file changed, 132 deletions(-) diff --git a/README.md b/README.md index a8c2162..cd40bd0 100644 --- a/README.md +++ b/README.md @@ -47,135 +47,3 @@ Using Callback Functions: https://stackoverflow.com/questions/14471975/how-can-i L-System Visualizer: https://www.kevs3d.co.uk/dev/lsystems/ Color Palette: https://icolorpalette.com/color/ocean-blue - - -# Homework 4: L-systems - -For this assignment, you will design a set of formal grammar rules to create -a plant life using an L-system program. Once again, you will work from a -TypeScript / WebGL 2.0 base code like the one you used in homework 0. You will -implement your own set of classes to handle the L-system grammar expansion and -drawing. You will rasterize your L-system using faceted geometry. Feel free -to use ray marching to generate an interesting background, but trying to -raymarch an entire L-system will take too long to render! - -## Base Code -The provided code is very similar to that of homework 1, with the same camera and GUI layout. Additionally, we have provided you with a `Mesh` class that, given a filepath, will construct VBOs describing the vertex positions, normals, colors, uvs, and indices for any `.obj` file. The provided code also uses instanced rendering to draw a single square 10,000 times at different locations and with different colors; refer to the Assignment Requirements section for more details on instanced rendering. Farther down this README, we have also provided some example code snippets for setting up hash map structures in TypeScript. - -## Assignment Requirements -- __(15 points)__ Create a collection of classes to represent an L-system. You should have at least the following components to make your L-system functional: - - A `Turtle` class to represent the current drawing state of your L-System. It should at least keep track of its current position, current orientation, and recursion depth (how many `[` characters have been found while drawing before `]`s) - - A stack of `Turtle`s to represent your `Turtle` history. Push a copy of your current `Turtle` onto this when you reach a `[` while drawing, and pop the top `Turtle` from the stack and make it your current `Turtle` when you encounter a `]`. Note that in TypeScript, `push()` and `pop()` operations can be done on regular arrays. - - An expandable string of characters to represent your grammar as you iterate on it. - - An `ExpansionRule` class to represent the result of mapping a particular character to a new set of characters during the grammar expansion phase of the L-System. By making a class to represent the expansion, you can have a single character expand to multiple possible strings depending on some probability by querying a `Map`. - - A `DrawingRule` class to represent the result of mapping a character to an L-System drawing operation (possibly with multiple outcomes depending on a probability). - -- __(10 points)__ Set up the code in `main.ts` and `ShaderProgram.ts` to pass a collection of transformation data to the GPU to draw your L-System geometric components using __instanced rendering__. We will be using instanced rendering to draw our L-Systems because it is much more efficient to pass a single transformation for each object to be drawn rather than an entire collection of vertices. The provided base code has examples of passing a set of `vec3`s to offset the position of each instanced object, and a set of `vec4`s to change the color of each object. You should at least alter the following via instanced rendering (note that these can be accomplished with a single `mat4`): - - Position - - Orientation - - Scaling - -- __(55 points)__ Your L-System scene must have the following attributes: - - Your plant must grow in 3D (branches must not just exist in one plane) - - Your plant must have flowers, leaves, or some other branch decoration in addition to basic branch geometry - - Organic variation (i.e. noise or randomness in grammar expansion and/or drawing operations) - - The background should be a colorful backdrop to complement your plant, incorporating some procedural elements. - - A flavorful twist. Don't just make a basic variation of the example F[+FX]-FX from the slides! Create a plant that is unique to you. Make an alien tentacle monster plant if you want to! Play around with drawing operations; don't feel compelled to always make your branches straight lines. Curved forms can look quite visually appealing too. - -- __(10 points)__ Using dat.GUI, make at least three aspects of your L-System interactive, such as: - - The probability thresholds in your grammar expansions - - The angle of rotation in various drawing aspects - - The size or color or material of the plant components - - Anything else in your L-System expansion or drawing you'd like to make modifiable; it doesn't have to be these particular elements - -- __(10 points)__ Following the specifications listed -[here](https://github.com/pjcozzi/Articles/blob/master/CIS565/GitHubRepo/README.md), -create your own README.md, renaming the file you are presently reading to -INSTRUCTIONS.md. Don't worry about discussing runtime optimization for this -project. Make sure your README contains the following information: - - Your name and PennKey - - Citation of any external resources you found helpful when implementing this - assignment. - - A link to your live github.io demo (refer to the pinned Piazza post on - how to make a live demo through github.io) - - An explanation of the techniques you used to generate your L-System features. - Please be as detailed as you can; not only will this help you explain your work - to recruiters, but it helps us understand your project when we grade it! - -## Writing classes and functions in TypeScript -Example of a basic Turtle class in TypeScript (Turtle.ts) -``` -import {vec3} from 'gl-matrix'; - -export default class Turtle { - constructor(pos: vec3, orient: vec3) { - this.position = pos; - this.orientation = orient; - } - - moveForward() { - add(this.position, this.position, this.orientation * 10.0); - } -} -``` -Example of a hash map in TypeScript: -``` -let expansionRules : Map = new Map(); -expansionRules.set('A', 'AB'); -expansionRules.set('B', 'A'); - -console.log(expansionRules.get('A')); // Will print out 'AB' -console.log(expansionRules.get('C')); // Will print out 'undefined' -``` -Using functions as map values in TypeScript: -``` -function moveForward() {...} -function rotateLeft() {...} -let drawRules : Map = new Map(); -drawRules.set('F', moveForward); -drawRules.set('+', rotateLeft); - -let func = drawRules.get('F'); -if(func) { // Check that the map contains a value for this key - func(); -} -``` -Note that in the above case, the code assumes that all functions stored in the `drawRules` map take in no arguments. If you want to store a class's functions as values in a map, you'll have to refer to a specific instance of a class, e.g. -``` -let myTurtle: Turtle = new Turtle(); -let drawRules: Map = new Map(); -drawRules.set('F', myTurtle.moveForward.bind(myTurtle)); -let func = drawRules.get('F'); -if(func) { // Check that the map contains a value for this key - func(); -} -``` -TypeScript's `bind` operation sets the `this` variable inside the bound function to refer to the object inside `bind`. This ensures that the `Turtle` in question is the one on which `moveForward` is invoked when `func()` is called with no object. - -## Examples from previous years (Click to go to live demo) - -Andrea Lin: - -[![](andreaLin.png)](http://andrea-lin.com/Project3-LSystems/) - -Ishan Ranade: - -[![](ishanRanade.png)](https://ishanranade.github.io/homework-4-l-systems-IshanRanade/) - -Joe Klinger: - -[![](joeKlinger.png)](https://klingerj.github.io/Project3-LSystems/) - -Linshen Xiao: - -[![](linshenXiao.png)](https://githublsx.github.io/homework-4-l-systems-githublsx/) - -## Useful Resources -- [The Algorithmic Beauty of Plants](http://algorithmicbotany.org/papers/abop/abop-ch1.pdf) -- [OpenGL Instanced Rendering (Learn OpenGL)](https://learnopengl.com/Advanced-OpenGL/Instancing) -- [OpenGL Instanced Rendering (OpenGL-Tutorial)](http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/) - -## Extra Credit (Up to 20 points) -- For bonus points, add functionality to your L-system drawing that ensures geometry will never overlap. In other words, make your plant behave like a real-life plant so that its branches and other components don't compete for the same space. The more complex you make your L-system self-interaction, the more -points you'll earn. -- Any additional visual polish you add to your L-System will count towards extra credit, at your grader's discretion. For example, you could add animation of the leaves or branches in your vertex shader, or add falling leaves or flower petals. From 8eda9c16d35d8fc0e16a1e7453ce7dd9e09db9c3 Mon Sep 17 00:00:00 2001 From: serenag01 <70620606+serenag01@users.noreply.github.com> Date: Wed, 10 Nov 2021 08:06:36 -0500 Subject: [PATCH 33/34] Update INSTRUCTIONS.md --- INSTRUCTIONS.md | 129 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/INSTRUCTIONS.md b/INSTRUCTIONS.md index 8b13789..c1cda32 100644 --- a/INSTRUCTIONS.md +++ b/INSTRUCTIONS.md @@ -1 +1,130 @@ +# Homework 4: L-systems +For this assignment, you will design a set of formal grammar rules to create +a plant life using an L-system program. Once again, you will work from a +TypeScript / WebGL 2.0 base code like the one you used in homework 0. You will +implement your own set of classes to handle the L-system grammar expansion and +drawing. You will rasterize your L-system using faceted geometry. Feel free +to use ray marching to generate an interesting background, but trying to +raymarch an entire L-system will take too long to render! + +## Base Code +The provided code is very similar to that of homework 1, with the same camera and GUI layout. Additionally, we have provided you with a `Mesh` class that, given a filepath, will construct VBOs describing the vertex positions, normals, colors, uvs, and indices for any `.obj` file. The provided code also uses instanced rendering to draw a single square 10,000 times at different locations and with different colors; refer to the Assignment Requirements section for more details on instanced rendering. Farther down this README, we have also provided some example code snippets for setting up hash map structures in TypeScript. + +## Assignment Requirements +- __(15 points)__ Create a collection of classes to represent an L-system. You should have at least the following components to make your L-system functional: + - A `Turtle` class to represent the current drawing state of your L-System. It should at least keep track of its current position, current orientation, and recursion depth (how many `[` characters have been found while drawing before `]`s) + - A stack of `Turtle`s to represent your `Turtle` history. Push a copy of your current `Turtle` onto this when you reach a `[` while drawing, and pop the top `Turtle` from the stack and make it your current `Turtle` when you encounter a `]`. Note that in TypeScript, `push()` and `pop()` operations can be done on regular arrays. + - An expandable string of characters to represent your grammar as you iterate on it. + - An `ExpansionRule` class to represent the result of mapping a particular character to a new set of characters during the grammar expansion phase of the L-System. By making a class to represent the expansion, you can have a single character expand to multiple possible strings depending on some probability by querying a `Map`. + - A `DrawingRule` class to represent the result of mapping a character to an L-System drawing operation (possibly with multiple outcomes depending on a probability). + +- __(10 points)__ Set up the code in `main.ts` and `ShaderProgram.ts` to pass a collection of transformation data to the GPU to draw your L-System geometric components using __instanced rendering__. We will be using instanced rendering to draw our L-Systems because it is much more efficient to pass a single transformation for each object to be drawn rather than an entire collection of vertices. The provided base code has examples of passing a set of `vec3`s to offset the position of each instanced object, and a set of `vec4`s to change the color of each object. You should at least alter the following via instanced rendering (note that these can be accomplished with a single `mat4`): + - Position + - Orientation + - Scaling + +- __(55 points)__ Your L-System scene must have the following attributes: + - Your plant must grow in 3D (branches must not just exist in one plane) + - Your plant must have flowers, leaves, or some other branch decoration in addition to basic branch geometry + - Organic variation (i.e. noise or randomness in grammar expansion and/or drawing operations) + - The background should be a colorful backdrop to complement your plant, incorporating some procedural elements. + - A flavorful twist. Don't just make a basic variation of the example F[+FX]-FX from the slides! Create a plant that is unique to you. Make an alien tentacle monster plant if you want to! Play around with drawing operations; don't feel compelled to always make your branches straight lines. Curved forms can look quite visually appealing too. + +- __(10 points)__ Using dat.GUI, make at least three aspects of your L-System interactive, such as: + - The probability thresholds in your grammar expansions + - The angle of rotation in various drawing aspects + - The size or color or material of the plant components + - Anything else in your L-System expansion or drawing you'd like to make modifiable; it doesn't have to be these particular elements + +- __(10 points)__ Following the specifications listed +[here](https://github.com/pjcozzi/Articles/blob/master/CIS565/GitHubRepo/README.md), +create your own README.md, renaming the file you are presently reading to +INSTRUCTIONS.md. Don't worry about discussing runtime optimization for this +project. Make sure your README contains the following information: + - Your name and PennKey + - Citation of any external resources you found helpful when implementing this + assignment. + - A link to your live github.io demo (refer to the pinned Piazza post on + how to make a live demo through github.io) + - An explanation of the techniques you used to generate your L-System features. + Please be as detailed as you can; not only will this help you explain your work + to recruiters, but it helps us understand your project when we grade it! + +## Writing classes and functions in TypeScript +Example of a basic Turtle class in TypeScript (Turtle.ts) +``` +import {vec3} from 'gl-matrix'; + +export default class Turtle { + constructor(pos: vec3, orient: vec3) { + this.position = pos; + this.orientation = orient; + } + + moveForward() { + add(this.position, this.position, this.orientation * 10.0); + } +} +``` +Example of a hash map in TypeScript: +``` +let expansionRules : Map = new Map(); +expansionRules.set('A', 'AB'); +expansionRules.set('B', 'A'); + +console.log(expansionRules.get('A')); // Will print out 'AB' +console.log(expansionRules.get('C')); // Will print out 'undefined' +``` +Using functions as map values in TypeScript: +``` +function moveForward() {...} +function rotateLeft() {...} +let drawRules : Map = new Map(); +drawRules.set('F', moveForward); +drawRules.set('+', rotateLeft); + +let func = drawRules.get('F'); +if(func) { // Check that the map contains a value for this key + func(); +} +``` +Note that in the above case, the code assumes that all functions stored in the `drawRules` map take in no arguments. If you want to store a class's functions as values in a map, you'll have to refer to a specific instance of a class, e.g. +``` +let myTurtle: Turtle = new Turtle(); +let drawRules: Map = new Map(); +drawRules.set('F', myTurtle.moveForward.bind(myTurtle)); +let func = drawRules.get('F'); +if(func) { // Check that the map contains a value for this key + func(); +} +``` +TypeScript's `bind` operation sets the `this` variable inside the bound function to refer to the object inside `bind`. This ensures that the `Turtle` in question is the one on which `moveForward` is invoked when `func()` is called with no object. + +## Examples from previous years (Click to go to live demo) + +Andrea Lin: + +[![](andreaLin.png)](http://andrea-lin.com/Project3-LSystems/) + +Ishan Ranade: + +[![](ishanRanade.png)](https://ishanranade.github.io/homework-4-l-systems-IshanRanade/) + +Joe Klinger: + +[![](joeKlinger.png)](https://klingerj.github.io/Project3-LSystems/) + +Linshen Xiao: + +[![](linshenXiao.png)](https://githublsx.github.io/homework-4-l-systems-githublsx/) + +## Useful Resources +- [The Algorithmic Beauty of Plants](http://algorithmicbotany.org/papers/abop/abop-ch1.pdf) +- [OpenGL Instanced Rendering (Learn OpenGL)](https://learnopengl.com/Advanced-OpenGL/Instancing) +- [OpenGL Instanced Rendering (OpenGL-Tutorial)](http://www.opengl-tutorial.org/intermediate-tutorials/billboards-particles/particles-instancing/) + +## Extra Credit (Up to 20 points) +- For bonus points, add functionality to your L-system drawing that ensures geometry will never overlap. In other words, make your plant behave like a real-life plant so that its branches and other components don't compete for the same space. The more complex you make your L-system self-interaction, the more +points you'll earn. +- Any additional visual polish you add to your L-System will count towards extra credit, at your grader's discretion. For example, you could add animation of the leaves or branches in your vertex shader, or add falling leaves or flower petals. From 216ab6cfe1f51139beea4bd74d111e5fd9d967cd Mon Sep 17 00:00:00 2001 From: serenag01 <70620606+serenag01@users.noreply.github.com> Date: Wed, 10 Nov 2021 08:24:08 -0500 Subject: [PATCH 34/34] Update README.md --- README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README.md b/README.md index cd40bd0..12a909c 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,26 @@ The Tool in Action: https://user-images.githubusercontent.com/70620606/141118237-24d21cf8-ae9f-4f39-bc3b-92cce27468b0.mp4 +# How It All Went Down: + +This project started with my inspiration, the coral. From here, I generated samples of my L-System grammar in the 2D L-System Visualizer (linked below) and in Houdini. Once my grammar was finalized, I moved on to coding. + +Admittedly, I had to start and re-start this project, but my final version used the following pipeline: + +First, I rendered out a single branch using the instanced shader. This helped me familiarize myself with instanced rendering, as well as ensure that, if my L-System is working properly, something will show up in my viewport. + +Then, I started working on my L-System. I created Turtle, Expansion Rule, and Drawing Rule classes, which were all used in conjunction in the L-System Class. The Turtle class recorded and altered the current position and orientation of the "turtle." The expansion rule classes expanded the grammar I described, using some randomness. The Drawing Rule class selected drawing rules based on the provided grammar, using some randomness. + +To start, I set my grammar to be two iterations of a simple "FF". This way, I could easily test whether my rules were working. Also, to start, I only included rotation in 2D. + +Once my grammar was properly working, I added 3D rotation and expanded the grammar to the current version. + +From here, I added the branch decoration and incorporated randomness in my grammar by adjusting each angle drawn by no more than 10 degrees in either direction (sampled on a curve, not uniformly, to ensure that larger angle changes are less common). I also added additional rules that could terminate the grammar with a branch decoration. + +Next, I worked on the background, adding the various colors and animating them on a sine curve. I also added stripes to my tree shader for a little extra fun! The stripes are made using the current color's inverse, for a little extra POP! + +Finally, I added the sand base and the gui elements to make my project a tool to make many corals! + # Samples of L-System Using Tools: 2D L-System Visualizer: