├── .gitignore
├── .gitmodules
├── .haxerc
├── LICENSE
├── README.md
├── bin
└── index.html
├── build.hxml
├── haxe_libraries
├── asynctools.hxml
├── haxe-loader.hxml
└── vector-math.hxml
├── package-lock.json
├── package.json
├── src
├── Main.hx
├── ch02
│ ├── ColorTriangle.hx
│ ├── FirstUniform.hx
│ └── RedTriangle.hx
├── ch03
│ ├── Brightness.hx
│ ├── ColorMath.hx
│ ├── Parrot.hx
│ ├── Quad.hx
│ ├── ScrollingUV.hx
│ └── shaders
│ │ ├── brightness.frag.glsl
│ │ ├── brightness.vert.glsl
│ │ ├── color-math.frag.glsl
│ │ ├── color-math.vert.glsl
│ │ ├── parrot.frag.glsl
│ │ ├── parrot.vert.glsl
│ │ ├── quad.frag.glsl
│ │ ├── quad.vert.glsl
│ │ ├── scrolling-uv.frag.glsl
│ │ └── scrolling-uv.vert.glsl
├── ch04
│ ├── AlphaBlending.hx
│ ├── DepthTest.hx
│ ├── GreenMan.hx
│ ├── SpriteSheet.hx
│ └── shaders
│ │ ├── bg.frag.glsl
│ │ ├── bg.vert.glsl
│ │ ├── cloud.frag.glsl
│ │ ├── cloud.vert.glsl
│ │ ├── green-man.frag.glsl
│ │ ├── green-man.vert.glsl
│ │ ├── spriteSheet.vert.glsl
│ │ ├── sun.frag.glsl
│ │ └── sun.vert.glsl
├── ch05
│ ├── WalkingMan.hx
│ └── shaders
│ │ ├── bg.frag.glsl
│ │ ├── bg.vert.glsl
│ │ ├── cloud.frag.glsl
│ │ ├── cloud.vert.glsl
│ │ ├── green-man.frag.glsl
│ │ ├── spriteSheet.vert.glsl
│ │ ├── sun.frag.glsl
│ │ └── sun.vert.glsl
├── ch06
│ ├── Cameras.hx
│ └── shaders
│ │ ├── bg.frag.glsl
│ │ ├── bg.vert.glsl
│ │ ├── cloud.frag.glsl
│ │ ├── cloud.vert.glsl
│ │ ├── green-man.frag.glsl
│ │ ├── spriteSheet.vert.glsl
│ │ ├── sun.frag.glsl
│ │ └── sun.vert.glsl
├── ch07
│ ├── PerspectiveTorus.hx
│ └── shaders
│ │ ├── passthrough.vert.glsl
│ │ └── uv_vis.frag.glsl
├── ch08
│ ├── DiffuseLighting.hx
│ ├── RimLight.hx
│ └── shaders
│ │ ├── diffuse_light.frag.glsl
│ │ ├── diffuse_light.vert.glsl
│ │ ├── rim_light.frag.glsl
│ │ └── rim_light.vert.glsl
├── ch09
│ ├── BlinnPhongTorus.hx
│ ├── BlinnShield.hx
│ ├── DiffuseSpecularTorus.hx
│ ├── LightModelBase.hx
│ ├── PhongTorus.hx
│ ├── SpecularTorus.hx
│ └── shaders
│ │ ├── blinnPhong.frag.glsl
│ │ ├── blinnPhong.vert.glsl
│ │ ├── blinnShield.frag.glsl
│ │ ├── blinnShield.vert.glsl
│ │ ├── diffuseSpecular.frag.glsl
│ │ ├── diffuseSpecular.vert.glsl
│ │ ├── phong.frag.glsl
│ │ ├── phong.vert.glsl
│ │ ├── specular.frag.glsl
│ │ └── specular.vert.glsl
├── ch10
│ ├── NormalMapping.hx
│ ├── NormalMappingBase.hx
│ ├── Water.hx
│ └── shaders
│ │ ├── normalMapping.frag.glsl
│ │ ├── normalMapping.vert.glsl
│ │ ├── water.frag.glsl
│ │ └── water.vert.glsl
├── ch11
│ ├── CubeMap.hx
│ ├── CubeMapBase.hx
│ ├── SkyBox.hx
│ └── shaders
│ │ ├── cubeMap.frag.glsl
│ │ ├── cubeMap.vert.glsl
│ │ ├── skyBox.vert.glsl
│ │ ├── water.frag.glsl
│ │ └── water.vert.glsl
├── ch12
│ ├── LightBase.hx
│ ├── MultiPass.hx
│ ├── MultipleLights.hx
│ ├── PointLightExample.hx
│ ├── SpotLights.hx
│ ├── lights
│ │ ├── PointLight.hx
│ │ └── SpotLight.hx
│ ├── multipass
│ │ ├── DirectionalLight.hx
│ │ ├── Light.hx
│ │ └── PointLight.hx
│ └── shaders
│ │ ├── light.glsl
│ │ ├── light.vert.glsl
│ │ ├── multiplLights.frag.glsl
│ │ ├── pointLight.frag.glsl
│ │ └── spotLight.frag.glsl
├── externs
│ ├── Ogl.hx
│ └── Ply.hx
├── types
│ └── Types.hx
└── utils
│ ├── BaseOfApp.hx
│ ├── BuildMatrix.hx
│ ├── CalculateTangents.hx
│ ├── Camera.hx
│ ├── CreatePLYGeometry.hx
│ ├── Degree.hx
│ ├── DirectionalLight.hx
│ ├── LoadImage.hx
│ ├── LoadTexture.hx
│ ├── Material.hx
│ ├── Matrix.hx
│ ├── Mesh3D.hx
│ ├── OglBase.hx
│ ├── Texture.hx
│ ├── Transformation.hx
│ └── ViewMatrix.hx
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | main.js
3 | main.js.map
4 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "original"]
2 | path = original
3 | url = https://github.com/Apress/practical-shader-dev
4 |
--------------------------------------------------------------------------------
/.haxerc:
--------------------------------------------------------------------------------
1 | {
2 | "version": "6dc7876",
3 | "resolveLibs": "scoped"
4 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Uldis Baurovskis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Practical Shader Development HX
2 | Haxe implementation of book: [Practical Shader Development](https://www.apress.com/gp/book/9781484244562)
3 |
--------------------------------------------------------------------------------
/bin/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Practical shader development
6 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/build.hxml:
--------------------------------------------------------------------------------
1 | -cp src
2 | -lib vector-math
3 | -lib haxe-loader
4 | --main Main
5 | --js bin/main.js
6 | --debug
--------------------------------------------------------------------------------
/haxe_libraries/asynctools.hxml:
--------------------------------------------------------------------------------
1 | # @install: lix --silent download "haxelib:/asynctools#0.1.0" into asynctools/0.1.0/haxelib
2 | -cp ${HAXE_LIBCACHE}/asynctools/0.1.0/haxelib/
3 | -D asynctools=0.1.0
--------------------------------------------------------------------------------
/haxe_libraries/haxe-loader.hxml:
--------------------------------------------------------------------------------
1 | # @install: lix --silent download "haxelib:/haxe-loader#0.9.0" into haxe-loader/0.9.0/haxelib
2 | -cp ${HAXE_LIBCACHE}/haxe-loader/0.9.0/haxelib/haxelib/
3 | -D haxe-loader=0.9.0
--------------------------------------------------------------------------------
/haxe_libraries/vector-math.hxml:
--------------------------------------------------------------------------------
1 | # @install: lix --silent download "gh://github.com/haxiomic/vector-math#1eb3a944d25cb08a637ef9ecb310eb7fae3a7750" into vector-math/1.4.0/github/1eb3a944d25cb08a637ef9ecb310eb7fae3a7750
2 | -cp ${HAXE_LIBCACHE}/vector-math/1.4.0/github/1eb3a944d25cb08a637ef9ecb310eb7fae3a7750/
3 | -D vector-math=1.4.0
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "devDependencies": {
3 | "@webpack-cli/serve": "^1.1.0",
4 | "dts2hx": "^0.15.3",
5 | "file-loader": "^6.2.0",
6 | "haxe-loader": "^0.10.0",
7 | "html-webpack-plugin": "^4.5.0",
8 | "lix": "^15.10.1",
9 | "webpack": "^5.4.0",
10 | "webpack-cli": "^4.2.0",
11 | "webpack-dev-server": "^3.11.0",
12 | "webpack-glsl-loader": "^1.0.1"
13 | },
14 | "scripts": {
15 | "postinstall": "lix download",
16 | "start": "webpack serve"
17 | },
18 | "name": "practical-shader-dev-hx",
19 | "dependencies": {
20 | "@loaders.gl/core": "^2.3.6",
21 | "@loaders.gl/ply": "^2.3.6",
22 | "ogl": "^0.0.60"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/Main.hx:
--------------------------------------------------------------------------------
1 | package;
2 |
3 | import ch02.RedTriangle;
4 | import ch02.ColorTriangle;
5 | import ch02.FirstUniform;
6 | import ch03.Quad;
7 | import ch03.Parrot;
8 | import ch03.ScrollingUV;
9 | import ch03.Brightness;
10 | import ch03.ColorMath;
11 | import ch04.GreenMan;
12 | import ch04.DepthTest;
13 | import ch04.AlphaBlending;
14 | import ch04.SpriteSheet;
15 | import ch05.WalkingMan;
16 | import ch06.Cameras;
17 | import ch07.PerspectiveTorus;
18 | import ch08.DiffuseLighting;
19 | import ch08.RimLight;
20 | import ch09.SpecularTorus;
21 | import ch09.DiffuseSpecularTorus;
22 | import ch09.PhongTorus;
23 | import ch09.BlinnPhongTorus;
24 | import ch09.BlinnShield;
25 | import ch10.NormalMapping;
26 | import ch10.Water;
27 | import ch11.CubeMap;
28 | import ch11.SkyBox;
29 | import ch12.PointLightExample;
30 | import ch12.SpotLights;
31 | import ch12.MultipleLights;
32 |
33 | class Main {
34 | public function new() {
35 | // new RedTriangle();
36 | // new ColorTriangle();
37 | // new FirstUniform();
38 | // new Quad();
39 | // new Parrot();
40 | // new ScrollingUV();
41 | // new Brightness();
42 | // new ColorMath();
43 | // new GreenMan();
44 | // new DepthTest();
45 | // new AlphaBlending();
46 | // new SpriteSheet();
47 | // new WalkingMan();
48 | // new Cameras();
49 | // new PerspectiveTorus();
50 | // new DiffuseLighting();
51 | // new RimLight();
52 | // new SpecularTorus();
53 | // new DiffuseSpecularTorus();
54 | // new PhongTorus();
55 | // new BlinnPhongTorus();
56 | // new BlinnShield();
57 | // new NormalMapping();
58 | // new Water();
59 | // new CubeMap();
60 | // new SkyBox();
61 | // new PointLightExample();
62 | // new SpotLights();
63 | new MultipleLights();
64 | }
65 |
66 | static function main() {
67 | new Main();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/ch02/ColorTriangle.hx:
--------------------------------------------------------------------------------
1 | package ch02;
2 |
3 | import VectorMath.Vec3;
4 | import VectorMath.Vec4;
5 | import js.Browser;
6 | import js.html.KeyboardEvent;
7 | import types.Types.IShader;
8 | import utils.Mesh3D;
9 | import utils.BaseOfApp;
10 | import utils.Material;
11 | import types.Types.Mesh;
12 |
13 | final fragment = '#version 300 es
14 | precision highp float;
15 |
16 | out vec4 outColor;
17 | in vec4 fragColor;
18 |
19 | void main()
20 | {
21 | outColor = fragColor;
22 | }';
23 | final vertex = '#version 300 es
24 | precision highp float;
25 |
26 | layout (location = 0) in vec3 position;
27 | layout (location = 1) in vec4 color;
28 |
29 | out vec4 fragColor;
30 |
31 | void main()
32 | {
33 | fragColor = color;
34 | gl_Position = vec4(position, 1.0);
35 | }';
36 |
37 | class ColorTriangle extends BaseOfApp {
38 | private var triangle:Mesh;
39 | private var shader:IShader;
40 |
41 | public function new() {
42 | super();
43 | }
44 |
45 | override private function setup():Void {
46 | super.setup();
47 | final width = 2;
48 | final height = 2;
49 | shader = new Material(ctx);
50 | shader.load(vertex, fragment);
51 | triangle = new Mesh3D(ctx, shader.program);
52 | triangle.addVertex(new Vec3(-width * 0.5, height * 0.5, 0));
53 | triangle.addVertex(new Vec3(height * 0.5, width * 0.5, 0));
54 | triangle.addVertex(new Vec3(width * 0.5, -height * 0.5, 0));
55 |
56 | triangle.addColor(new Vec4(1, 0, 0, 1));
57 | triangle.addColor(new Vec4(0, 1, 0, 1));
58 | triangle.addColor(new Vec4 (0, 0, 1, 1));
59 | triangle.build();
60 | }
61 |
62 | override public function draw(delta:Float):Void {
63 | super.draw(delta);
64 | shader.begin();
65 | triangle.draw();
66 | shader.end();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/ch02/FirstUniform.hx:
--------------------------------------------------------------------------------
1 | package ch02;
2 |
3 | import VectorMath.Vec4;
4 | import VectorMath.Vec3;
5 | import js.Browser;
6 | import js.html.KeyboardEvent;
7 | import types.Types.IShader;
8 | import utils.Mesh3D;
9 | import utils.BaseOfApp;
10 | import utils.Material;
11 | import types.Types.Mesh;
12 |
13 | final fragment = '#version 300 es
14 | precision highp float;
15 |
16 | out vec4 outColor;
17 | uniform vec4 fragColor;
18 |
19 | void main()
20 | {
21 | outColor = fragColor;
22 | }';
23 | final vertex = '#version 300 es
24 | precision highp float;
25 |
26 | layout (location = 0) in vec3 position;
27 |
28 | void main()
29 | {
30 | gl_Position = vec4(position, 1.0);
31 | }';
32 |
33 | class FirstUniform extends BaseOfApp {
34 | private var triangle:Mesh;
35 | private var shader:IShader;
36 |
37 | public function new() {
38 | super();
39 | }
40 |
41 | override private function setup():Void {
42 | super.setup();
43 | final width = 2;
44 | final height = 2;
45 | shader = new Material(ctx);
46 | shader.load(vertex, fragment);
47 | triangle = new Mesh3D(ctx, shader.program);
48 | triangle.addVertex(new Vec3(-width * 0.5, height * 0.5, 0));
49 | triangle.addVertex(new Vec3(height * 0.5, width * 0.5, 0));
50 | triangle.addVertex(new Vec3(width * 0.5, -height * 0.5, 0));
51 | triangle.build();
52 | }
53 |
54 | override public function draw(delta:Float):Void {
55 | super.draw(delta);
56 | shader.begin();
57 | shader.setUniform4f("fragColor", new Vec4(1,0,1,1));
58 | triangle.draw();
59 | shader.end();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/ch02/RedTriangle.hx:
--------------------------------------------------------------------------------
1 | package ch02;
2 |
3 | import VectorMath.Vec3;
4 | import js.Browser;
5 | import js.html.KeyboardEvent;
6 | import types.Types.IShader;
7 | import utils.Mesh3D;
8 | import utils.BaseOfApp;
9 | import utils.Material;
10 | import types.Types.Mesh;
11 |
12 | final fragment = '#version 300 es
13 | precision highp float;
14 |
15 | out vec4 outColor;
16 |
17 | void main()
18 | {
19 | outColor = vec4(1.0,0.0,0.0,1.0);
20 | }';
21 | final vertex = '#version 300 es
22 | precision highp float;
23 |
24 | in vec3 position;
25 |
26 | void main()
27 | {
28 | gl_Position = vec4(position, 1.0);
29 | }';
30 |
31 | class RedTriangle extends BaseOfApp {
32 | private var triangle:Mesh;
33 | private var shader:IShader;
34 |
35 | public function new() {
36 | super();
37 | Browser.window.addEventListener("keydown", this.onKeyPressed);
38 | }
39 |
40 | override private function setup():Void {
41 | super.setup();
42 | final width = 2;
43 | final height = 2;
44 | shader = new Material(ctx);
45 | shader.load(vertex, fragment);
46 | triangle = new Mesh3D(ctx, shader.program);
47 | triangle.addVertex(new Vec3(-width * 0.5, height * 0.5, 0));
48 | triangle.addVertex(new Vec3(height * 0.5, width * 0.5, 0));
49 | triangle.addVertex(new Vec3(width * 0.5, -height * 0.5, 0));
50 | triangle.build();
51 | }
52 |
53 | override public function draw(delta:Float):Void {
54 | super.draw(delta);
55 | shader.begin();
56 | triangle.draw();
57 | shader.end();
58 | }
59 | private function onKeyPressed(e: KeyboardEvent): Void {
60 | final curPos = triangle.getVertex(0);
61 | triangle.setVertex(0, curPos + new Vec3(0, 1, 0));
62 | triangle.build();
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/ch03/Brightness.hx:
--------------------------------------------------------------------------------
1 | package ch03;
2 |
3 | import VectorMath.log;
4 | import VectorMath.Vec2;
5 | import VectorMath.Vec4;
6 | import VectorMath.Vec3;
7 | import types.Types.IShader;
8 | import utils.Mesh3D;
9 | import utils.BaseOfApp;
10 | import utils.Material;
11 | import types.Types.Mesh;
12 |
13 |
14 | class Brightness extends BaseOfApp {
15 | private var quad:Mesh;
16 | private var shader:IShader;
17 | public function new() {
18 | super();
19 | }
20 |
21 | override private function setup():Void {
22 | super.setup();
23 | shader = new Material(ctx);
24 | shader.load(
25 | Webpack.require("./shaders/brightness.vert.glsl"),
26 | Webpack.require("./shaders/brightness.frag.glsl")
27 | );
28 | shader.setUniformTexture("parrotTex", Webpack.require("../../original/ch3/Assets/parrot.png"), 0);
29 | quad = new Mesh3D(ctx, shader.program);
30 | quad.addVertex(new Vec3(-1, -1, 0));
31 | quad.addVertex(new Vec3(-1, 1, 0));
32 | quad.addVertex(new Vec3(1, 1, 0));
33 | quad.addVertex(new Vec3(1, -1, 0));
34 |
35 | quad.addColor(new Vec4(1, 0, 0, 1));
36 | quad.addColor(new Vec4(0, 1, 0, 1));
37 | quad.addColor(new Vec4(0, 0, 1, 1));
38 | quad.addColor(new Vec4(1, 1, 1, 1));
39 |
40 | quad.addTexCoord(new Vec2(0, 0));
41 | quad.addTexCoord(new Vec2(0, 1));
42 | quad.addTexCoord(new Vec2(1, 1));
43 | quad.addTexCoord(new Vec2(1, 0));
44 |
45 | quad.addIndicies([0, 1, 2, 2, 3, 0]);
46 | quad.build();
47 | }
48 |
49 | override public function draw(delta:Float):Void {
50 | super.draw(delta);
51 | shader.begin();
52 | shader.setUniform1f("brightness", 0.1);
53 | quad.draw();
54 | shader.end();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/ch03/ColorMath.hx:
--------------------------------------------------------------------------------
1 | package ch03;
2 |
3 | import VectorMath.log;
4 | import VectorMath.Vec2;
5 | import VectorMath.Vec4;
6 | import VectorMath.Vec3;
7 | import types.Types.IShader;
8 | import utils.Mesh3D;
9 | import utils.BaseOfApp;
10 | import utils.Material;
11 | import types.Types.Mesh;
12 |
13 |
14 | class ColorMath extends BaseOfApp {
15 | private var quad:Mesh;
16 | private var shader:IShader;
17 | public function new() {
18 | super();
19 | }
20 |
21 | override private function setup():Void {
22 | super.setup();
23 | shader = new Material(ctx);
24 | shader.load(
25 | Webpack.require("./shaders/color-math.vert.glsl"),
26 | Webpack.require("./shaders/color-math.frag.glsl")
27 | );
28 | shader.setUniformTexture("parrotTex", Webpack.require("../../original/ch3/Assets/parrot.png"), 0);
29 | quad = new Mesh3D(ctx, shader.program);
30 | quad.addVertex(new Vec3(-1, -1, 0));
31 | quad.addVertex(new Vec3(-1, 1, 0));
32 | quad.addVertex(new Vec3(1, 1, 0));
33 | quad.addVertex(new Vec3(1, -1, 0));
34 |
35 | quad.addColor(new Vec4(1, 0, 0, 1));
36 | quad.addColor(new Vec4(0, 1, 0, 1));
37 | quad.addColor(new Vec4(0, 0, 1, 1));
38 | quad.addColor(new Vec4(1, 1, 1, 1));
39 |
40 | quad.addTexCoord(new Vec2(0, 0));
41 | quad.addTexCoord(new Vec2(0, 1));
42 | quad.addTexCoord(new Vec2(1, 1));
43 | quad.addTexCoord(new Vec2(1, 0));
44 |
45 | quad.addIndicies([0, 1, 2, 2, 3, 0]);
46 | quad.build();
47 | }
48 |
49 | override public function draw(delta:Float):Void {
50 | super.draw(delta);
51 | shader.begin();
52 | shader.setUniform4f("multiplay", new Vec4(0.5, 0.5, 0.1, 1.0));
53 | shader.setUniform4f("add", new Vec4(0.1, 0.1, 0.1, 0.0));
54 | quad.draw();
55 | shader.end();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/ch03/Parrot.hx:
--------------------------------------------------------------------------------
1 | package ch03;
2 |
3 | import VectorMath.Vec2;
4 | import VectorMath.Vec4;
5 | import VectorMath.Vec3;
6 | import types.Types.IShader;
7 | import utils.Mesh3D;
8 | import utils.BaseOfApp;
9 | import utils.Material;
10 | import types.Types.Mesh;
11 |
12 |
13 | class Parrot extends BaseOfApp {
14 | private var quad:Mesh;
15 | private var shader:IShader;
16 |
17 | public function new() {
18 | super();
19 | }
20 |
21 | override private function setup():Void {
22 | super.setup();
23 | shader = new Material(ctx);
24 | shader.load(
25 | Webpack.require("./shaders/parrot.vert.glsl"),
26 | Webpack.require("./shaders/parrot.frag.glsl")
27 | );
28 | shader.setUniformTexture("parrotTex", Webpack.require("../../original/ch3/Assets/parrot.png"), 0);
29 | quad = new Mesh3D(ctx, shader.program);
30 | quad.addVertex(new Vec3(-1, -1, 0));
31 | quad.addVertex(new Vec3(-1, 1, 0));
32 | quad.addVertex(new Vec3(1, 1, 0));
33 | quad.addVertex(new Vec3(1, -1, 0));
34 |
35 | quad.addColor(new Vec4(1, 0, 0, 1));
36 | quad.addColor(new Vec4(0, 1, 0, 1));
37 | quad.addColor(new Vec4(0, 0, 1, 1));
38 | quad.addColor(new Vec4(1, 1, 1, 1));
39 |
40 | quad.addTexCoord(new Vec2(0, 0));
41 | quad.addTexCoord(new Vec2(0, 1));
42 | quad.addTexCoord(new Vec2(1, 1));
43 | quad.addTexCoord(new Vec2(1, 0));
44 |
45 | quad.addIndicies([0, 1, 2, 2, 3, 0]);
46 |
47 | quad.build();
48 | }
49 |
50 | override public function draw(delta:Float):Void {
51 | super.draw(delta);
52 | shader.begin();
53 | quad.draw();
54 | shader.end();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/ch03/Quad.hx:
--------------------------------------------------------------------------------
1 | package ch03;
2 |
3 | import VectorMath.Vec2;
4 | import VectorMath.Vec4;
5 | import VectorMath.Vec3;
6 | import types.Types.IShader;
7 | import utils.Mesh3D;
8 | import utils.BaseOfApp;
9 | import utils.Material;
10 | import types.Types.Mesh;
11 |
12 |
13 | class Quad extends BaseOfApp {
14 | private var quad:Mesh;
15 | private var shader:IShader;
16 |
17 | public function new() {
18 | super();
19 | }
20 |
21 | override private function setup():Void {
22 | super.setup();
23 | shader = new Material(ctx);
24 | shader.load(
25 | Webpack.require("./shaders/quad.vert.glsl"),
26 | Webpack.require("./shaders/quad.frag.glsl")
27 | );
28 | quad = new Mesh3D(ctx, shader.program);
29 | quad.addVertex(new Vec3(-1, -1, 0));
30 | quad.addVertex(new Vec3(-1, 1, 0));
31 | quad.addVertex(new Vec3(1, 1, 0));
32 | quad.addVertex(new Vec3(1, -1, 0));
33 |
34 | quad.addColor(new Vec4(1, 0, 0, 1));
35 | quad.addColor(new Vec4(0, 1, 0, 1));
36 | quad.addColor(new Vec4(0, 0, 1, 1));
37 | quad.addColor(new Vec4(1, 1, 1, 1));
38 |
39 | quad.addTexCoord(new Vec2(0, 0));
40 | quad.addTexCoord(new Vec2(0, 1));
41 | quad.addTexCoord(new Vec2(1, 1));
42 | quad.addTexCoord(new Vec2(1, 0));
43 |
44 | quad.addIndicies([0, 1, 2, 2, 3, 0]);
45 |
46 | quad.build();
47 | }
48 |
49 | override public function draw(delta:Float):Void {
50 | super.draw(delta);
51 | shader.begin();
52 | quad.draw();
53 | shader.end();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/ch03/ScrollingUV.hx:
--------------------------------------------------------------------------------
1 | package ch03;
2 |
3 | import VectorMath.log;
4 | import VectorMath.Vec2;
5 | import VectorMath.Vec4;
6 | import VectorMath.Vec3;
7 | import types.Types.IShader;
8 | import utils.Mesh3D;
9 | import utils.BaseOfApp;
10 | import utils.Material;
11 | import types.Types.Mesh;
12 |
13 |
14 | class ScrollingUV extends BaseOfApp {
15 | private var quad:Mesh;
16 | private var shader:IShader;
17 | private var startTime: Float;
18 | public function new() {
19 | super();
20 | this.startTime = 0;
21 | }
22 |
23 | override private function setup():Void {
24 | super.setup();
25 | shader = new Material(ctx);
26 | shader.load(
27 | Webpack.require("./shaders/scrolling-uv.vert.glsl"),
28 | Webpack.require("./shaders/scrolling-uv.frag.glsl")
29 | );
30 | shader.setUniformTexture("parrotTex", Webpack.require("../../original/ch3/Assets/parrot.png"), 0);
31 | quad = new Mesh3D(ctx, shader.program);
32 | quad.addVertex(new Vec3(-1, -1, 0));
33 | quad.addVertex(new Vec3(-1, 1, 0));
34 | quad.addVertex(new Vec3(1, 1, 0));
35 | quad.addVertex(new Vec3(1, -1, 0));
36 |
37 | quad.addColor(new Vec4(1, 0, 0, 1));
38 | quad.addColor(new Vec4(0, 1, 0, 1));
39 | quad.addColor(new Vec4(0, 0, 1, 1));
40 | quad.addColor(new Vec4(1, 1, 1, 1));
41 |
42 | quad.addTexCoord(new Vec2(0, 0));
43 | quad.addTexCoord(new Vec2(0, 1));
44 | quad.addTexCoord(new Vec2(1, 1));
45 | quad.addTexCoord(new Vec2(1, 0));
46 |
47 | quad.addIndicies([0, 1, 2, 2, 3, 0]);
48 |
49 | quad.build();
50 | }
51 |
52 | override public function draw(delta:Float):Void {
53 | startTime += 0.01;
54 | trace(startTime);
55 | super.draw(delta);
56 | shader.begin();
57 | shader.setUniform1f("time", startTime);
58 | quad.draw();
59 | shader.end();
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/ch03/shaders/brightness.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D parrotTex;
8 | uniform float brightness;
9 |
10 | void main() {
11 | vec4 tex = texture(parrotTex, fragUV);
12 | tex.rgb *= brightness;
13 | outColor = tex;
14 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/brightness.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/color-math.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D parrotTex;
8 | uniform vec4 multiplay;
9 | uniform vec4 add;
10 |
11 | void main() {
12 | outColor = texture(parrotTex, fragUV) * multiplay + add;
13 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/color-math.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/parrot.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D parrotTex;
8 |
9 | void main()
10 | {
11 | outColor = texture(parrotTex, fragUV);
12 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/parrot.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/quad.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec4 fragColor;
6 | in vec2 fragUV;
7 |
8 | void main()
9 | {
10 | outColor = vec4(fragUV, 0.0, 1.0);
11 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/quad.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 1) in vec4 color;
6 | layout (location = 3) in vec2 uv;
7 |
8 | out vec4 fragColor;
9 | out vec2 fragUV;
10 |
11 | void main()
12 | {
13 | fragColor = color;
14 | fragUV = uv;
15 | gl_Position = vec4(position, 1.0);
16 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/scrolling-uv.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D parrotTex;
8 |
9 | void main()
10 | {
11 | outColor = texture(parrotTex, fragUV);
12 | }
--------------------------------------------------------------------------------
/src/ch03/shaders/scrolling-uv.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | uniform float time;
8 |
9 | out vec2 fragUV;
10 |
11 | void main()
12 | {
13 | fragUV = vec2(uv.x, uv.y) + vec2(1.0, 0.0) * time;
14 | gl_Position = vec4(position, 1.0);
15 | }
--------------------------------------------------------------------------------
/src/ch04/AlphaBlending.hx:
--------------------------------------------------------------------------------
1 | package ch04;
2 |
3 | import js.html.webgl.RenderingContext;
4 | import VectorMath.Vec2;
5 | import VectorMath.Vec4;
6 | import VectorMath.Vec3;
7 | import types.Types.IShader;
8 | import utils.Mesh3D;
9 | import utils.BaseOfApp;
10 | import utils.Material;
11 | import types.Types.Mesh;
12 |
13 |
14 | class AlphaBlending extends BaseOfApp {
15 | private var charMesh:Mesh;
16 | private var charShader:IShader;
17 | private var bgMesh:Mesh;
18 | private var bgShader:IShader;
19 | private var cloudMesh:Mesh;
20 | private var cloudShader:IShader;
21 | private var sunMesh:Mesh;
22 | private var sunShader:IShader;
23 | public function new() {
24 | super();
25 | }
26 |
27 | override private function setup():Void {
28 | super.setup();
29 | bgShader = new Material(ctx);
30 | bgShader.load(
31 | Webpack.require("./shaders/bg.vert.glsl"),
32 | Webpack.require("./shaders/bg.frag.glsl")
33 | );
34 | bgShader.setUniformTexture("bg", Webpack.require("../../original/ch4/Assets/forest.png"), 1);
35 | charShader = new Material(ctx);
36 | charShader.load(
37 | Webpack.require("./shaders/green-man.vert.glsl"),
38 | Webpack.require("./shaders/green-man.frag.glsl")
39 | );
40 | charShader.setUniformTexture("greenMan", Webpack.require("../../original/ch4/Assets/alien.png"), 0);
41 | cloudShader = new Material(ctx);
42 | cloudShader.load(
43 | Webpack.require("./shaders/cloud.vert.glsl"),
44 | Webpack.require("./shaders/cloud.frag.glsl")
45 | );
46 | cloudShader.setUniformTexture("cloud", Webpack.require("../../original/ch4/Assets/cloud.png"), 2);
47 | sunShader = new Material(ctx);
48 | sunShader.load(
49 | Webpack.require("./shaders/sun.vert.glsl"),
50 | Webpack.require("./shaders/sun.frag.glsl")
51 | );
52 | sunShader.setUniformTexture("sun", Webpack.require("../../original/ch4/Assets/sun.png"), 3);
53 | charMesh = new Mesh3D(ctx, charShader.program);
54 | buildMesh(charMesh, 0.05, 0.1, new Vec3(0, -0.345, 0));
55 | charMesh.build();
56 | bgMesh = new Mesh3D(ctx, bgShader.program);
57 | buildMesh(bgMesh, 1, 1, new Vec3(0, 0, 0.5));
58 | bgMesh.build();
59 | cloudMesh = new Mesh3D(ctx, cloudShader.program);
60 | buildMesh(cloudMesh, 0.2, 0.1, new Vec3(-0.55, 0, 0));
61 | cloudMesh.build();
62 | sunMesh = new Mesh3D(ctx, sunShader.program);
63 | buildMesh(sunMesh, 1, 1, new Vec3(0, 0, 0.4));
64 | sunMesh.build();
65 | }
66 | override public function draw(delta:Float):Void {
67 | super.draw(delta);
68 | enableDepthTest();
69 | setBlendingMode(RenderingContext.SRC_ALPHA, RenderingContext.ONE_MINUS_SRC_ALPHA);
70 | charShader.begin();
71 | charMesh.draw();
72 | charShader.end();
73 | bgShader.begin();
74 | bgMesh.draw();
75 | bgShader.end();
76 | setBlendingMode(RenderingContext.ONE, RenderingContext.ONE);
77 | sunShader.begin();
78 | sunMesh.draw();
79 | sunShader.end();
80 | setBlendingMode(RenderingContext.SRC_ALPHA, RenderingContext.ONE_MINUS_SRC_ALPHA);
81 | disableDepthTest();
82 | cloudShader.begin();
83 | cloudMesh.draw();
84 | cloudShader.end();
85 | }
86 | private function buildMesh(mesh: Mesh, width: Float, height: Float, position: Vec3): Void {
87 | final verts: Array = [
88 | -width + position.x, -height + position.y, position.z,
89 | -width + position.x, height + position.y, position.z,
90 | width + position.x, height + position.y, position.z,
91 | width + position.x, -height + position.y, position.z
92 | ];
93 | final uv: Array = [
94 | 0, 0,
95 | 0, 1,
96 | 1, 1,
97 | 1, 0
98 | ];
99 |
100 | for(i in 0...4) {
101 | final idx = i * 3;
102 | final uvIdx = i * 2;
103 |
104 | mesh.addVertex(new Vec3(verts[idx], verts[idx + 1], verts[idx + 2]));
105 | mesh.addTexCoord(new Vec2(uv[uvIdx], uv[uvIdx + 1]));
106 | }
107 | mesh.addIndicies([
108 | 0, 1, 2, 2, 3, 0
109 | ]);
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/ch04/DepthTest.hx:
--------------------------------------------------------------------------------
1 | package ch04;
2 |
3 | import VectorMath.Vec2;
4 | import VectorMath.Vec4;
5 | import VectorMath.Vec3;
6 | import types.Types.IShader;
7 | import utils.Mesh3D;
8 | import utils.BaseOfApp;
9 | import utils.Material;
10 | import types.Types.Mesh;
11 |
12 |
13 | class DepthTest extends BaseOfApp {
14 | private var charMesh:Mesh;
15 | private var charShader:IShader;
16 | private var bgMesh:Mesh;
17 | private var bgShader:IShader;
18 | public function new() {
19 | super();
20 | }
21 |
22 | override private function setup():Void {
23 | super.setup();
24 | bgShader = new Material(ctx);
25 | bgShader.load(
26 | Webpack.require("./shaders/bg.vert.glsl"),
27 | Webpack.require("./shaders/bg.frag.glsl")
28 | );
29 | bgShader.setUniformTexture("bg", Webpack.require("../../original/ch4/Assets/forest.png"), 1);
30 | charShader = new Material(ctx);
31 | charShader.load(
32 | Webpack.require("./shaders/green-man.vert.glsl"),
33 | Webpack.require("./shaders/green-man.frag.glsl")
34 | );
35 | charShader.setUniformTexture("greenMan", Webpack.require("../../original/ch4/Assets/alien.png"), 0);
36 | charMesh = new Mesh3D(ctx, charShader.program);
37 | buildMesh(charMesh, 0.05, 0.1, new Vec3(0, 0.15, 0));
38 | charMesh.build();
39 | bgMesh = new Mesh3D(ctx, bgShader.program);
40 | buildMesh(bgMesh, 1, 1, new Vec3(0, 0, 0.5));
41 | bgMesh.build();
42 | }
43 | override public function draw(delta:Float):Void {
44 | super.draw(delta);
45 | charShader.begin();
46 | charMesh.draw();
47 | charShader.end();
48 | bgShader.begin();
49 | bgMesh.draw();
50 | bgShader.end();
51 | }
52 | private function buildMesh(mesh: Mesh, width: Float, height: Float, position: Vec3): Void {
53 | final verts: Array = [
54 | -width + position.x, -height + position.y, position.z,
55 | -width + position.x, height + position.y, position.z,
56 | width + position.x, height + position.y, position.z,
57 | width + position.x, -height + position.y, position.z
58 | ];
59 | final uv: Array = [
60 | 0, 0,
61 | 0, 1,
62 | 1, 1,
63 | 1, 0
64 | ];
65 |
66 | for(i in 0...4) {
67 | final idx = i * 3;
68 | final uvIdx = i * 2;
69 |
70 | mesh.addVertex(new Vec3(verts[idx], verts[idx + 1], verts[idx + 2]));
71 | mesh.addTexCoord(new Vec2(uv[uvIdx], uv[uvIdx + 1]));
72 | }
73 | mesh.addIndicies([
74 | 0, 1, 2, 2, 3, 0
75 | ]);
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/ch04/GreenMan.hx:
--------------------------------------------------------------------------------
1 | package ch04;
2 |
3 | import VectorMath.Vec2;
4 | import VectorMath.Vec4;
5 | import VectorMath.Vec3;
6 | import types.Types.IShader;
7 | import utils.Mesh3D;
8 | import utils.BaseOfApp;
9 | import utils.Material;
10 | import types.Types.Mesh;
11 |
12 |
13 | class GreenMan extends BaseOfApp {
14 | private var charMesh:Mesh;
15 | private var shader:IShader;
16 |
17 | public function new() {
18 | super();
19 | }
20 |
21 | override private function setup():Void {
22 | super.setup();
23 | shader = new Material(ctx);
24 | shader.load(
25 | Webpack.require("./shaders/green-man.vert.glsl"),
26 | Webpack.require("./shaders/green-man.frag.glsl")
27 | );
28 | shader.setUniformTexture("greenMan", Webpack.require("../../original/ch4/Assets/alien.png"), 0);
29 | charMesh = new Mesh3D(ctx, shader.program);
30 | buildMesh(charMesh, 0.25, 0.5, new Vec3(0, 0.15, 0));
31 | charMesh.build();
32 | }
33 | override public function draw(delta:Float):Void {
34 | super.draw(delta);
35 | shader.begin();
36 | charMesh.draw();
37 | shader.end();
38 | }
39 | private function buildMesh(mesh: Mesh, width: Float, heigh: Float, position: Vec3): Void {
40 | final verts: Array = [
41 | -width + position.x, -heigh + position.y, position.z,
42 | -width + position.x, heigh + position.y, position.z,
43 | width + position.x, heigh + position.y, position.z,
44 | width + position.x, -heigh + position.y, position.z
45 | ];
46 | final uv: Array = [
47 | 0, 0, 0,
48 | 1, 1, 1,
49 | 1, 1, 0
50 | ];
51 |
52 | final inidicies: Array = [
53 | 0, 1, 2, 2, 3, 0
54 | ];
55 |
56 | for(i in 0...4) {
57 | final idx = i * 3;
58 | final uvIdx = i * 2;
59 |
60 | mesh.addVertex(new Vec3(verts[idx], verts[idx + 1], verts[idx +2]));
61 | mesh.addTexCoord(new Vec2(uv[uvIdx], uv[uvIdx + 2]));
62 | }
63 | mesh.addIndicies(inidicies);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/ch04/SpriteSheet.hx:
--------------------------------------------------------------------------------
1 | package ch04;
2 |
3 | import js.html.webgl.RenderingContext;
4 | import VectorMath.Vec2;
5 | import VectorMath.Vec4;
6 | import VectorMath.Vec3;
7 | import types.Types.IShader;
8 | import utils.Mesh3D;
9 | import utils.BaseOfApp;
10 | import utils.Material;
11 | import types.Types.Mesh;
12 |
13 |
14 | class SpriteSheet extends BaseOfApp {
15 | private var charMesh:Mesh;
16 | private var charShader:IShader;
17 | private var bgMesh:Mesh;
18 | private var bgShader:IShader;
19 | private var cloudMesh:Mesh;
20 | private var cloudShader:IShader;
21 | private var sunMesh:Mesh;
22 | private var sunShader:IShader;
23 | private var frame: Float = 0.0;
24 | public function new() {
25 | super();
26 | }
27 |
28 | override private function setup():Void {
29 | super.setup();
30 | bgShader = new Material(ctx);
31 | bgShader.load(
32 | Webpack.require("./shaders/bg.vert.glsl"),
33 | Webpack.require("./shaders/bg.frag.glsl")
34 | );
35 | bgShader.setUniformTexture("bg", Webpack.require("../../original/ch4/Assets/forest.png"), 1);
36 | charShader = new Material(ctx);
37 | charShader.load(
38 | Webpack.require("./shaders/spriteSheet.vert.glsl"),
39 | Webpack.require("./shaders/green-man.frag.glsl")
40 | );
41 | charShader.setUniformTexture("greenMan", Webpack.require("../../original/ch4/5_SpritesheetAnimation/bin/data/walk_sheet.png"), 0, 0);
42 | cloudShader = new Material(ctx);
43 | cloudShader.load(
44 | Webpack.require("./shaders/cloud.vert.glsl"),
45 | Webpack.require("./shaders/cloud.frag.glsl")
46 | );
47 | cloudShader.setUniformTexture("cloud", Webpack.require("../../original/ch4/Assets/cloud.png"), 2);
48 | sunShader = new Material(ctx);
49 | sunShader.load(
50 | Webpack.require("./shaders/sun.vert.glsl"),
51 | Webpack.require("./shaders/sun.frag.glsl")
52 | );
53 | sunShader.setUniformTexture("sun", Webpack.require("../../original/ch4/Assets/sun.png"), 3);
54 | charMesh = new Mesh3D(ctx, charShader.program);
55 | buildMesh(charMesh, 0.05, 0.1, new Vec3(0, -0.345, 0));
56 | charMesh.build();
57 | bgMesh = new Mesh3D(ctx, bgShader.program);
58 | buildMesh(bgMesh, 1, 1, new Vec3(0, 0, 0.5));
59 | bgMesh.build();
60 | cloudMesh = new Mesh3D(ctx, cloudShader.program);
61 | buildMesh(cloudMesh, 0.2, 0.1, new Vec3(-0.55, 0, 0));
62 | cloudMesh.build();
63 | sunMesh = new Mesh3D(ctx, sunShader.program);
64 | buildMesh(sunMesh, 1, 1, new Vec3(0, 0, 0.4));
65 | sunMesh.build();
66 | }
67 | override public function draw(delta:Float):Void {
68 | frame = (frame > 10) ? 0.0 : frame += 0.2;
69 | super.draw(delta);
70 | enableDepthTest();
71 | setBlendingMode(RenderingContext.SRC_ALPHA, RenderingContext.ONE_MINUS_SRC_ALPHA);
72 | charShader.begin();
73 | charShader.setUniform2f("size", new Vec2(0.28, 0.19));
74 | charShader.setUniform2f("frame", new Vec2(Std.int(frame % 3), Std.int(frame / 3)));
75 | charMesh.draw();
76 | charShader.end();
77 | bgShader.begin();
78 | bgMesh.draw();
79 | bgShader.end();
80 | setBlendingMode(RenderingContext.ONE, RenderingContext.ONE);
81 | sunShader.begin();
82 | sunMesh.draw();
83 | sunShader.end();
84 | setBlendingMode(RenderingContext.SRC_ALPHA, RenderingContext.ONE_MINUS_SRC_ALPHA);
85 | disableDepthTest();
86 | cloudShader.begin();
87 | cloudMesh.draw();
88 | cloudShader.end();
89 | }
90 | private function buildMesh(mesh: Mesh, width: Float, height: Float, position: Vec3): Void {
91 | final verts: Array = [
92 | -width + position.x, -height + position.y, position.z,
93 | -width + position.x, height + position.y, position.z,
94 | width + position.x, height + position.y, position.z,
95 | width + position.x, -height + position.y, position.z
96 | ];
97 | final uv: Array = [
98 | 0, 0,
99 | 0, 1,
100 | 1, 1,
101 | 1, 0
102 | ];
103 |
104 | for(i in 0...4) {
105 | final idx = i * 3;
106 | final uvIdx = i * 2;
107 |
108 | mesh.addVertex(new Vec3(verts[idx], verts[idx + 1], verts[idx + 2]));
109 | mesh.addTexCoord(new Vec2(uv[uvIdx], uv[uvIdx + 1]));
110 | }
111 | mesh.addIndicies([
112 | 0, 1, 2, 2, 3, 0
113 | ]);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/ch04/shaders/bg.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D bg;
8 |
9 | void main() {
10 | vec4 tex = texture(bg, fragUV);
11 | outColor = tex;
12 | }
--------------------------------------------------------------------------------
/src/ch04/shaders/bg.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch04/shaders/cloud.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D cloud;
8 |
9 | void main() {
10 | outColor = texture(cloud, fragUV);
11 | outColor.a = min(outColor.a, 0.8);
12 | }
--------------------------------------------------------------------------------
/src/ch04/shaders/cloud.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch04/shaders/green-man.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D greenMan;
8 |
9 | void main() {
10 | vec4 tex = texture(greenMan, fragUV);
11 | outColor = tex;
12 |
13 | if (outColor.a < 1.0) {
14 | discard;
15 | }
16 | }
--------------------------------------------------------------------------------
/src/ch04/shaders/green-man.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch04/shaders/spriteSheet.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | uniform vec2 size;
10 | uniform vec2 frame;
11 |
12 | void main()
13 | {
14 | fragUV = vec2(uv.x, 1.0 - uv.y) * size + (frame * size);
15 | gl_Position = vec4(position, 1.0);
16 | }
--------------------------------------------------------------------------------
/src/ch04/shaders/sun.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D sun;
8 |
9 | void main() {
10 | outColor = texture(sun, fragUV);
11 | outColor.a = min(outColor.a, 0.8);
12 | }
--------------------------------------------------------------------------------
/src/ch04/shaders/sun.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch05/WalkingMan.hx:
--------------------------------------------------------------------------------
1 | package ch05;
2 |
3 | import VectorMath.Mat4;
4 | import js.lib.Float32Array;
5 | import utils.Transformation.scale;
6 | import utils.Transformation.rotate;
7 | import utils.Transformation.translate;
8 | import VectorMath.log;
9 | import js.html.KeyboardEvent;
10 | import js.Browser;
11 | import js.html.webgl.RenderingContext;
12 | import VectorMath.Vec2;
13 | import VectorMath.Vec4;
14 | import VectorMath.Vec3;
15 | import types.Types.IShader;
16 | import utils.Mesh3D;
17 | import utils.BaseOfApp;
18 | import utils.Material;
19 | import types.Types.Mesh;
20 |
21 |
22 | class WalkingMan extends BaseOfApp {
23 | private var charMesh:Mesh;
24 | private var charShader:IShader;
25 | private var bgMesh:Mesh;
26 | private var bgShader:IShader;
27 | private var cloudMesh:Mesh;
28 | private var cloudShader:IShader;
29 | private var sunMesh:Mesh;
30 | private var sunShader:IShader;
31 | private var frame: Float = 0.0;
32 | private var walkRight: Bool;
33 | private var charPos: Vec3;
34 | public function new() {
35 | super();
36 | charPos = new Vec3(0, 0, 0);
37 | Browser.window.addEventListener("keydown", onPress);
38 | Browser.window.addEventListener("keyup", onRelease);
39 | }
40 |
41 | override private function setup():Void {
42 | super.setup();
43 | bgShader = new Material(ctx);
44 | bgShader.load(
45 | Webpack.require("./shaders/bg.vert.glsl"),
46 | Webpack.require("./shaders/bg.frag.glsl")
47 | );
48 | bgShader.setUniformTexture("bg", Webpack.require("../../original/ch5/Assets/forest.png"), 1);
49 | charShader = new Material(ctx);
50 | charShader.load(
51 | Webpack.require("./shaders/spriteSheet.vert.glsl"),
52 | Webpack.require("./shaders/green-man.frag.glsl")
53 | );
54 | charShader.setUniformTexture("greenMan", Webpack.require("../../original/ch5/1_WalkingCharacter/bin/data/walk_sheet.png"), 0, 0);
55 | cloudShader = new Material(ctx);
56 | cloudShader.load(
57 | Webpack.require("./shaders/cloud.vert.glsl"),
58 | Webpack.require("./shaders/cloud.frag.glsl")
59 | );
60 | cloudShader.setUniformTexture("cloud", Webpack.require("../../original/ch5/Assets/cloud.png"), 2);
61 | sunShader = new Material(ctx);
62 | sunShader.load(
63 | Webpack.require("./shaders/sun.vert.glsl"),
64 | Webpack.require("./shaders/sun.frag.glsl")
65 | );
66 | sunShader.setUniformTexture("sun", Webpack.require("../../original/ch5/Assets/sun.png"), 3);
67 | charMesh = new Mesh3D(ctx, charShader.program);
68 | buildMesh(charMesh, 0.05, 0.1, new Vec3(0, -0.345, 0));
69 | charMesh.build();
70 | bgMesh = new Mesh3D(ctx, bgShader.program);
71 | buildMesh(bgMesh, 1, 1, new Vec3(0, 0, 0.5));
72 | bgMesh.build();
73 | cloudMesh = new Mesh3D(ctx, cloudShader.program);
74 | buildMesh(cloudMesh, 0.2, 0.1, new Vec3(0, 0, 0));
75 | cloudMesh.build();
76 | sunMesh = new Mesh3D(ctx, sunShader.program);
77 | buildMesh(sunMesh, 1, 1, new Vec3(0, 0, 0.4));
78 | sunMesh.build();
79 | }
80 | override public function draw(delta:Float):Void {
81 | if (walkRight) {
82 | charPos += new Vec3(0.0004 * delta, 0, 0);
83 | frame = (frame > 10) ? 0.0 : frame += 0.2;
84 | } else {
85 | frame = 0.0;
86 | }
87 | super.draw(delta);
88 | enableDepthTest();
89 | setBlendingMode(RenderingContext.SRC_ALPHA, RenderingContext.ONE_MINUS_SRC_ALPHA);
90 | charShader.begin();
91 | charShader.setUniform3f("positionOffset", charPos);
92 | charShader.setUniform2f("size", new Vec2(0.28, 0.19));
93 | charShader.setUniform2f("frame", new Vec2(Std.int(frame % 3), Std.int(frame / 3)));
94 | charMesh.draw();
95 | charShader.end();
96 | bgShader.begin();
97 | bgMesh.draw();
98 | bgShader.end();
99 | setBlendingMode(RenderingContext.ONE, RenderingContext.ONE);
100 | sunShader.begin();
101 | sunMesh.draw();
102 | sunShader.end();
103 | setBlendingMode(RenderingContext.SRC_ALPHA, RenderingContext.ONE_MINUS_SRC_ALPHA);
104 | disableDepthTest();
105 | cloudShader.begin();
106 | cloudShader.setUniformMatrix4f("transform", buildMatrix(new Vec3(-0.55, 0, 0), 0, new Vec3(1, 1, 1)));
107 | cloudMesh.draw();
108 | cloudShader.end();
109 | }
110 | private function buildMesh(mesh: Mesh, width: Float, height: Float, position: Vec3): Void {
111 | final verts: Array = [
112 | -width + position.x, -height + position.y, position.z,
113 | -width + position.x, height + position.y, position.z,
114 | width + position.x, height + position.y, position.z,
115 | width + position.x, -height + position.y, position.z
116 | ];
117 | final uv: Array = [
118 | 0, 0,
119 | 0, 1,
120 | 1, 1,
121 | 1, 0
122 | ];
123 |
124 | for(i in 0...4) {
125 | final idx = i * 3;
126 | final uvIdx = i * 2;
127 |
128 | mesh.addVertex(new Vec3(verts[idx], verts[idx + 1], verts[idx + 2]));
129 | mesh.addTexCoord(new Vec2(uv[uvIdx], uv[uvIdx + 1]));
130 | }
131 | mesh.addIndicies([
132 | 0, 1, 2, 2, 3, 0
133 | ]);
134 | }
135 | private function onPress(e: KeyboardEvent) {
136 | if (e.code == "ArrowRight") {
137 | walkRight = true;
138 | }
139 | }
140 | private function onRelease(e: KeyboardEvent) {
141 | if (e.code == "ArrowRight") {
142 | walkRight = false;
143 | }
144 | }
145 | private function buildMatrix(trans: Vec3, rot: Float, scaling: Vec3): Mat4 {
146 | return translate(trans) * rotate(rot, new Vec3(0, 0, 1)) * scale(scaling);
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/src/ch05/shaders/bg.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D bg;
8 |
9 | void main() {
10 | vec4 tex = texture(bg, fragUV);
11 | outColor = tex;
12 | }
--------------------------------------------------------------------------------
/src/ch05/shaders/bg.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch05/shaders/cloud.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D cloud;
8 |
9 | void main() {
10 | outColor = texture(cloud, fragUV);
11 | outColor.a = min(outColor.a, 0.8);
12 | }
--------------------------------------------------------------------------------
/src/ch05/shaders/cloud.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | uniform mat4 transform;
8 |
9 | out vec2 fragUV;
10 |
11 | void main()
12 | {
13 | fragUV = uv;
14 | gl_Position = transform * vec4(position, 1.0);
15 | }
--------------------------------------------------------------------------------
/src/ch05/shaders/green-man.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D greenMan;
8 |
9 | void main() {
10 | vec4 tex = texture(greenMan, fragUV);
11 | outColor = tex;
12 |
13 | if (outColor.a < 1.0) {
14 | discard;
15 | }
16 | }
--------------------------------------------------------------------------------
/src/ch05/shaders/spriteSheet.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | uniform vec2 size;
10 | uniform vec2 frame;
11 | uniform vec3 positionOffset;
12 |
13 | void main()
14 | {
15 | fragUV = vec2(uv.x, 1.0 - uv.y) * size + (frame * size);
16 | gl_Position = vec4(position + positionOffset, 1.0);
17 | }
--------------------------------------------------------------------------------
/src/ch05/shaders/sun.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D sun;
8 |
9 | void main() {
10 | outColor = texture(sun, fragUV);
11 | outColor.a = min(outColor.a, 0.8);
12 | }
--------------------------------------------------------------------------------
/src/ch05/shaders/sun.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | void main()
10 | {
11 | fragUV = uv;
12 | gl_Position = vec4(position, 1.0);
13 | }
--------------------------------------------------------------------------------
/src/ch06/Cameras.hx:
--------------------------------------------------------------------------------
1 | package ch06;
2 |
3 | import utils.ViewMatrix.buildViewMatrix;
4 | import utils.Camera;
5 | import types.Types.Camera as ICamera;
6 | import js.lib.Float32Array;
7 | import utils.Transformation.scale;
8 | import utils.Transformation.rotate;
9 | import utils.Transformation.translate;
10 | import js.html.KeyboardEvent;
11 | import js.Browser;
12 | import js.html.webgl.RenderingContext;
13 | import VectorMath.Vec2;
14 | import VectorMath.Vec3;
15 | import types.Types.IShader;
16 | import utils.Mesh3D;
17 | import utils.BaseOfApp;
18 | import utils.Material;
19 | import types.Types.Mesh;
20 |
21 |
22 | class Cameras extends BaseOfApp {
23 | private var camera: ICamera;
24 | private var charMesh:Mesh;
25 | private var charShader:IShader;
26 | private var bgMesh:Mesh;
27 | private var bgShader:IShader;
28 | private var cloudMesh:Mesh;
29 | private var cloudShader:IShader;
30 | private var sunMesh:Mesh;
31 | private var sunShader:IShader;
32 | private var frame: Float = 0.0;
33 | private var walkRight: Bool;
34 | private var charPos: Vec3;
35 | public function new() {
36 | super();
37 | charPos = new Vec3(0, 0, 0);
38 | camera = new Camera(new Vec3(1, 1, 1), 0.0);
39 | Browser.window.addEventListener("keydown", onPress);
40 | Browser.window.addEventListener("keyup", onRelease);
41 | }
42 |
43 | override private function setup():Void {
44 | super.setup();
45 | bgShader = new Material(ctx);
46 | bgShader.load(
47 | Webpack.require("./shaders/bg.vert.glsl"),
48 | Webpack.require("./shaders/bg.frag.glsl")
49 | );
50 | bgShader.setUniformTexture("bg", Webpack.require("../../original/ch6/Assets/forest.png"), 1);
51 | charShader = new Material(ctx);
52 | charShader.load(
53 | Webpack.require("./shaders/spriteSheet.vert.glsl"),
54 | Webpack.require("./shaders/green-man.frag.glsl")
55 | );
56 | charShader.setUniformTexture("greenMan", Webpack.require("../../original/ch6/Assets/walk_sheet.png"), 0, 0);
57 | cloudShader = new Material(ctx);
58 | cloudShader.load(
59 | Webpack.require("./shaders/cloud.vert.glsl"),
60 | Webpack.require("./shaders/cloud.frag.glsl")
61 | );
62 | cloudShader.setUniformTexture("cloud", Webpack.require("../../original/ch6/Assets/cloud.png"), 2);
63 | sunShader = new Material(ctx);
64 | sunShader.load(
65 | Webpack.require("./shaders/sun.vert.glsl"),
66 | Webpack.require("./shaders/sun.frag.glsl")
67 | );
68 | sunShader.setUniformTexture("sun", Webpack.require("../../original/ch6/Assets/sun.png"), 3);
69 | charMesh = new Mesh3D(ctx, charShader.program);
70 | buildMesh(charMesh, 0.05, 0.1, new Vec3(0, -0.345, 0));
71 | charMesh.build();
72 | bgMesh = new Mesh3D(ctx, bgShader.program);
73 | buildMesh(bgMesh, 1, 1, new Vec3(0, 0, 0.5));
74 | bgMesh.build();
75 | cloudMesh = new Mesh3D(ctx, cloudShader.program);
76 | buildMesh(cloudMesh, 0.2, 0.1, new Vec3(0, 0, 0));
77 | cloudMesh.build();
78 | sunMesh = new Mesh3D(ctx, sunShader.program);
79 | buildMesh(sunMesh, 1, 1, new Vec3(0, 0, 0.4));
80 | sunMesh.build();
81 | }
82 | override public function draw(delta:Float):Void {
83 | if (walkRight) {
84 | charPos += new Vec3(0.0004 * delta, 0, 0);
85 | frame = (frame > 10) ? 0.0 : frame += 0.2;
86 | } else {
87 | frame = 0.0;
88 | }
89 | super.draw(delta);
90 | final view = buildViewMatrix(camera);
91 | enableDepthTest();
92 | setBlendingMode(RenderingContext.SRC_ALPHA, RenderingContext.ONE_MINUS_SRC_ALPHA);
93 | charShader.begin();
94 | charShader.setUniformMatrix4f("view", view);
95 | charShader.setUniformMatrix4f("model", translate(charPos));
96 | charShader.setUniform2f("size", new Vec2(0.28, 0.19));
97 | charShader.setUniform2f("frame", new Vec2(Std.int(frame % 3), Std.int(frame / 3)));
98 | charMesh.draw();
99 | charShader.end();
100 | bgShader.begin();
101 | bgShader.setUniformMatrix4f("view", view);
102 | bgShader.setUniformMatrix4f("model", translate(new Vec3(0, 0, 0)));
103 | bgMesh.draw();
104 | bgShader.end();
105 | setBlendingMode(RenderingContext.ONE, RenderingContext.ONE);
106 | sunShader.begin();
107 | sunShader.setUniformMatrix4f("view", view);
108 | sunShader.setUniformMatrix4f("model", translate(new Vec3(0, 0, 0)));
109 | sunMesh.draw();
110 | sunShader.end();
111 | setBlendingMode(RenderingContext.SRC_ALPHA, RenderingContext.ONE_MINUS_SRC_ALPHA);
112 | disableDepthTest();
113 | cloudShader.begin();
114 | cloudShader.setUniformMatrix4f("view", view);
115 | cloudShader.setUniformMatrix4f("model", translate(new Vec3(0, 0, 0)));
116 | cloudMesh.draw();
117 | cloudShader.end();
118 | }
119 | private function buildMesh(mesh: Mesh, width: Float, height: Float, position: Vec3): Void {
120 | final verts: Array = [
121 | -width + position.x, -height + position.y, position.z,
122 | -width + position.x, height + position.y, position.z,
123 | width + position.x, height + position.y, position.z,
124 | width + position.x, -height + position.y, position.z
125 | ];
126 | final uv: Array = [
127 | 0, 0,
128 | 0, 1,
129 | 1, 1,
130 | 1, 0
131 | ];
132 |
133 | for(i in 0...4) {
134 | final idx = i * 3;
135 | final uvIdx = i * 2;
136 |
137 | mesh.addVertex(new Vec3(verts[idx], verts[idx + 1], verts[idx + 2]));
138 | mesh.addTexCoord(new Vec2(uv[uvIdx], uv[uvIdx + 1]));
139 | }
140 | mesh.addIndicies([
141 | 0, 1, 2, 2, 3, 0
142 | ]);
143 | }
144 | private function onPress(e: KeyboardEvent) {
145 | if (e.code == "ArrowRight") {
146 | walkRight = true;
147 | }
148 | }
149 | private function onRelease(e: KeyboardEvent) {
150 | if (e.code == "ArrowRight") {
151 | walkRight = false;
152 | }
153 | }
154 | private function buildMatrix(trans: Vec3, rot: Float, scaling: Vec3): Float32Array {
155 | final m = translate(trans) * rotate(rot, new Vec3(0, 0, 1)) * scale(scaling);
156 | final result = new Float32Array(16);
157 | result[0] = m[0].x;
158 | result[1] = m[0].y;
159 | result[2] = m[0].z;
160 | result[3] = m[0].w;
161 |
162 | result[4] = m[1].x;
163 | result[5] = m[1].y;
164 | result[6] = m[1].z;
165 | result[7] = m[1].w;
166 |
167 | result[8] = m[2].x;
168 | result[9] = m[2].y;
169 | result[10] = m[2].z;
170 | result[11] = m[2].w;
171 |
172 | result[12] = m[3].x;
173 | result[13] = m[3].y;
174 | result[14] = m[3].z;
175 | result[15] = m[3].w;
176 | return result;
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/src/ch06/shaders/bg.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D bg;
8 |
9 | void main() {
10 | vec4 tex = texture(bg, fragUV);
11 | outColor = tex;
12 | }
--------------------------------------------------------------------------------
/src/ch06/shaders/bg.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | uniform mat4 model;
8 | uniform mat4 view;
9 |
10 | out vec2 fragUV;
11 |
12 | void main()
13 | {
14 | fragUV = uv;
15 | gl_Position = view * model * vec4(position, 1.0);
16 | }
--------------------------------------------------------------------------------
/src/ch06/shaders/cloud.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D cloud;
8 |
9 | void main() {
10 | outColor = texture(cloud, fragUV);
11 | outColor.a = min(outColor.a, 0.8);
12 | }
--------------------------------------------------------------------------------
/src/ch06/shaders/cloud.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | uniform mat4 model;
8 | uniform mat4 view;
9 |
10 | out vec2 fragUV;
11 |
12 | void main()
13 | {
14 | fragUV = uv;
15 | gl_Position = view * model * vec4(position, 1.0);
16 | }
--------------------------------------------------------------------------------
/src/ch06/shaders/green-man.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D greenMan;
8 |
9 | void main() {
10 | vec4 tex = texture(greenMan, fragUV);
11 | outColor = tex;
12 |
13 | if (outColor.a < 1.0) {
14 | discard;
15 | }
16 | }
--------------------------------------------------------------------------------
/src/ch06/shaders/spriteSheet.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | uniform vec2 size;
10 | uniform vec2 frame;
11 | uniform vec3 positionOffset;
12 |
13 | uniform mat4 model;
14 | uniform mat4 view;
15 |
16 | void main()
17 | {
18 | fragUV = vec2(uv.x, 1.0 - uv.y) * size + (frame * size);
19 | gl_Position = view * model * vec4(position, 1.0);
20 | }
--------------------------------------------------------------------------------
/src/ch06/shaders/sun.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | out vec4 outColor;
5 | in vec2 fragUV;
6 |
7 | uniform sampler2D sun;
8 |
9 | void main() {
10 | outColor = texture(sun, fragUV);
11 | outColor.a = min(outColor.a, 0.8);
12 | }
--------------------------------------------------------------------------------
/src/ch06/shaders/sun.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp float;
3 |
4 | layout (location = 0) in vec3 position;
5 | layout (location = 3) in vec2 uv;
6 |
7 | out vec2 fragUV;
8 |
9 | uniform mat4 model;
10 | uniform mat4 view;
11 |
12 | void main()
13 | {
14 | fragUV = uv;
15 | gl_Position = view * model * vec4(position, 1.0);
16 | }
--------------------------------------------------------------------------------
/src/ch07/PerspectiveTorus.hx:
--------------------------------------------------------------------------------
1 | package ch07;
2 |
3 | import externs.Ogl.Program;
4 | import externs.Ogl.Mesh;
5 | import externs.Ogl.Geometry;
6 | import utils.OglBase;
7 | import externs.Ply.Loader;
8 | import externs.Ply.PLYLoader;
9 | import js.Browser;
10 |
11 | class PerspectiveTorus extends OglBase {
12 | private var program: Program;
13 | private var mesh: Mesh;
14 | public function new() {
15 | super();
16 | }
17 |
18 | override private function setup():Void {
19 | super.setup();
20 | Loader.load(
21 | Webpack.require("../../original/ch7/Assets/torus.ply"),
22 | PLYLoader,
23 | {}
24 | ).then(r -> {
25 | program = new Program(gl, {
26 | vertex: Webpack.require("./shaders/passthrough.vert.glsl"),
27 | fragment: Webpack.require("./shaders/uv_vis.frag.glsl"),
28 | });
29 | final geometry = new Geometry(gl, {
30 | position: { size: r.attributes.POSITION.size, data: r.attributes.POSITION.value },
31 | uv: { size: r.attributes.TEXCOORD_0.size, data: r.attributes.TEXCOORD_0.value },
32 | normal: { size: r.attributes.NORMAL.size, data: r.attributes.NORMAL.value },
33 | index: { size: r.indices.size, data: r.indices.value },
34 | });
35 |
36 | mesh = new Mesh(gl, { geometry: geometry, program: program });
37 |
38 | mesh.setParent(scene);
39 |
40 | Browser.window.requestAnimationFrame(onFrame);
41 | });
42 | }
43 | override public function onFrame(dt: Float): Void {
44 | super.onFrame(dt);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/ch07/shaders/passthrough.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec2 uv;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 |
11 | out vec2 fragUV;
12 |
13 | void main() {
14 | fragUV = uv;
15 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
16 | }
--------------------------------------------------------------------------------
/src/ch07/shaders/uv_vis.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec2 fragUV;
6 |
7 | out vec4 outColor;
8 | void main() {
9 | outColor = vec4(fragUV, 0.0, 1.0);
10 | }
--------------------------------------------------------------------------------
/src/ch08/DiffuseLighting.hx:
--------------------------------------------------------------------------------
1 | package ch08;
2 |
3 | import externs.Ogl.Vec3;
4 | import utils.DirectionalLight;
5 | import externs.Ogl.Program;
6 | import externs.Ogl.Mesh;
7 | import externs.Ogl.Geometry;
8 | import utils.OglBase;
9 | import externs.Ply.Loader;
10 | import externs.Ply.PLYLoader;
11 | import js.Browser;
12 |
13 | class DiffuseLighting extends OglBase {
14 | private var program: Program;
15 | private var mesh: Mesh;
16 | private var light: DirectionalLight;
17 | public function new() {
18 | super();
19 | light = new DirectionalLight();
20 | light.intensity = 1.0;
21 | light.color = new Vec3(1, 1, 1);
22 | light.direction = new Vec3(0, -1, 0);
23 | }
24 |
25 | override private function setup():Void {
26 | super.setup();
27 | Loader.load(
28 | Webpack.require("../../original/ch8/Assets/torus.ply"),
29 | PLYLoader,
30 | {}
31 | ).then(r -> {
32 | program = new Program(gl, {
33 | vertex: Webpack.require("./shaders/diffuse_light.vert.glsl"),
34 | fragment: Webpack.require("./shaders/diffuse_light.frag.glsl"),
35 | uniforms: {
36 | lightCol: { value: getLightColor(light) },
37 | lightDir: { value: getLightDirection(light) },
38 | meshCol: { value: new Vec3(1, 0, 1) }
39 | },
40 | });
41 | final geometry = new Geometry(gl, {
42 | position: { size: r.attributes.POSITION.size, data: r.attributes.POSITION.value },
43 | uv: { size: r.attributes.TEXCOORD_0.size, data: r.attributes.TEXCOORD_0.value },
44 | normal: { size: r.attributes.NORMAL.size, data: r.attributes.NORMAL.value },
45 | index: { size: r.indices.size, data: r.indices.value },
46 | });
47 |
48 | mesh = new Mesh(gl, { geometry: geometry, program: program });
49 | mesh.rotation.x = Math.PI * 0.75;
50 | mesh.setParent(scene);
51 |
52 | Browser.window.requestAnimationFrame(onFrame);
53 | });
54 | }
55 | override public function onFrame(dt: Float): Void {
56 | super.onFrame(dt);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/ch08/RimLight.hx:
--------------------------------------------------------------------------------
1 | package ch08;
2 |
3 | import externs.Ogl.Vec3;
4 | import utils.DirectionalLight;
5 | import externs.Ogl.Program;
6 | import externs.Ogl.Mesh;
7 | import externs.Ogl.Geometry;
8 | import utils.OglBase;
9 | import externs.Ply.Loader;
10 | import externs.Ply.PLYLoader;
11 | import js.Browser;
12 |
13 | class RimLight extends OglBase {
14 | private var program: Program;
15 | private var mesh: Mesh;
16 | private var light: DirectionalLight;
17 | public function new() {
18 | super();
19 | light = new DirectionalLight();
20 | light.intensity = 1.0;
21 | light.color = new Vec3(1, 1, 1);
22 | light.direction = new Vec3(0, -1, 0);
23 | }
24 |
25 | override private function setup():Void {
26 | super.setup();
27 | Loader.load(
28 | Webpack.require("../../original/ch8/Assets/torus.ply"),
29 | PLYLoader,
30 | {}
31 | ).then(r -> {
32 | program = new Program(gl, {
33 | vertex: Webpack.require("./shaders/rim_light.vert.glsl"),
34 | fragment: Webpack.require("./shaders/rim_light.frag.glsl"),
35 | uniforms: {
36 | lightCol: { value: getLightColor(light) },
37 | lightDir: { value: getLightDirection(light) },
38 | meshCol: { value: new Vec3(1, 0, 1) }
39 | },
40 | });
41 | final geometry = new Geometry(gl, {
42 | position: { size: r.attributes.POSITION.size, data: r.attributes.POSITION.value },
43 | uv: { size: r.attributes.TEXCOORD_0.size, data: r.attributes.TEXCOORD_0.value },
44 | normal: { size: r.attributes.NORMAL.size, data: r.attributes.NORMAL.value },
45 | index: { size: r.indices.size, data: r.indices.value },
46 | });
47 |
48 | mesh = new Mesh(gl, { geometry: geometry, program: program });
49 | mesh.rotation.x = Math.PI * 0.75;
50 | mesh.setParent(scene);
51 |
52 | Browser.window.requestAnimationFrame(onFrame);
53 | });
54 | }
55 | override public function onFrame(dt: Float): Void {
56 | super.onFrame(dt);
57 | mesh.rotation.x += 0.01;
58 | mesh.rotation.y += 0.01;
59 | mesh.rotation.z += 0.01;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/ch08/shaders/diffuse_light.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec2 fragUV;
6 | in vec3 fragNormal;
7 |
8 | uniform vec3 lightDir;
9 | uniform vec3 lightCol;
10 | uniform vec3 meshCol;
11 |
12 | out vec4 outColor;
13 | void main() {
14 | vec3 normal = normalize(fragNormal);
15 | float lightAmt = max(0.0, dot(normal, lightDir));
16 | vec3 fragLight = lightCol * lightAmt;
17 | outColor = vec4(meshCol * fragLight, 1.0);
18 | }
--------------------------------------------------------------------------------
/src/ch08/shaders/diffuse_light.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec2 uv;
7 | in vec3 normal;
8 |
9 | uniform mat4 modelViewMatrix;
10 | uniform mat4 projectionMatrix;
11 | uniform mat3 normalMatrix;
12 |
13 | out vec2 fragUV;
14 | out vec3 fragNormal;
15 |
16 | void main() {
17 | fragUV = uv;
18 | fragNormal = normalMatrix * normal;
19 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
20 | }
--------------------------------------------------------------------------------
/src/ch08/shaders/rim_light.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragNormal;
6 | in vec3 fragWorldPos;
7 |
8 | uniform vec3 cameraPosition;
9 | uniform vec3 lightDir;
10 | uniform vec3 lightCol;
11 | uniform vec3 meshCol;
12 |
13 | out vec4 outColor;
14 | void main() {
15 | vec3 normal = normalize(fragNormal);
16 | vec3 toCam = normalize(cameraPosition - fragWorldPos);
17 | float rimAmt = 1.0 - max(0.0, dot(normal, toCam));
18 | rimAmt = pow(rimAmt, 2.0);
19 | float lightAmt = max(0.0, dot(normal, lightDir));
20 | vec3 fragLight = lightCol * lightAmt;
21 | outColor = vec4(meshCol * fragLight + rimAmt, 1.0);
22 | }
--------------------------------------------------------------------------------
/src/ch08/shaders/rim_light.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 | uniform mat3 normalMatrix;
11 |
12 | out vec3 fragNormal;
13 | out vec3 fragWorldPos;
14 |
15 | void main() {
16 | fragNormal = normalMatrix * normal;
17 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
18 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
19 | }
--------------------------------------------------------------------------------
/src/ch09/BlinnPhongTorus.hx:
--------------------------------------------------------------------------------
1 | package ch09;
2 |
3 | import externs.Ogl.Program;
4 | import externs.Ogl.Vec3;
5 | import utils.DirectionalLight;
6 |
7 | class BlinnPhongTorus extends LightModelBase {
8 | public function new() {
9 | super();
10 | }
11 | override private function createShader(): Program {
12 | return new Program(gl, {
13 | vertex: Webpack.require("./shaders/blinnPhong.vert.glsl"),
14 | fragment: Webpack.require("./shaders/blinnPhong.frag.glsl"),
15 | uniforms: {
16 | lightCol: {value: getLightColor(light)},
17 | lightDir: {value: getLightDirection(light)},
18 | meshCol: {value: new Vec3(0.0, 0.5, 1)},
19 | meshSpecCol: {value: new Vec3(1, 1, 1)},
20 | ambientCol: {value: new Vec3(0.0, 0.3, 0.0)},
21 | },
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/ch09/BlinnShield.hx:
--------------------------------------------------------------------------------
1 | package ch09;
2 |
3 | import js.html.Image;
4 | import externs.Ogl.Texture;
5 | import externs.Ogl.Program;
6 | import externs.Ogl.Vec3;
7 | import utils.DirectionalLight;
8 |
9 | class BlinnShield extends LightModelBase {
10 | public function new() {
11 | super();
12 | camera.position.set(0, 0, 3);
13 | }
14 | override private function createShader(): Program {
15 | return new Program(gl, {
16 | vertex: Webpack.require("./shaders/blinnShield.vert.glsl"),
17 | fragment: Webpack.require("./shaders/blinnShield.frag.glsl"),
18 | uniforms: {
19 | lightCol: { value: getLightColor(light) },
20 | lightDir: { value: getLightDirection(light) },
21 | ambientCol: { value: new Vec3(0.0, 0.0, 0.0) },
22 | diffuseTex: { value: loadTexture(Webpack.require("../../original/ch9/Assets/shield_diffuse.png")) },
23 | specTex: { value: loadTexture(Webpack.require("../../original/ch9/Assets/shield_spec.png")) },
24 | },
25 | });
26 | }
27 | override function getModel() {
28 | return Webpack.require("../../original/ch9/Assets/shield.ply");
29 | }
30 | private function loadTexture(path: String): Texture {
31 | final texture = new Texture(gl);
32 | final img = new Image();
33 | img.src = path;
34 | img.onload = () -> texture.image = img;
35 | return texture;
36 | }
37 | override function rotateMesh(dt:Float) {
38 | mesh.rotation.x = -Math.PI * 0.25;
39 | mesh.rotation.y += 0.01;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/ch09/DiffuseSpecularTorus.hx:
--------------------------------------------------------------------------------
1 | package ch09;
2 |
3 | import externs.Ogl.Program;
4 | import externs.Ogl.Vec3;
5 | import utils.DirectionalLight;
6 |
7 | class DiffuseSpecularTorus extends LightModelBase {
8 | public function new() {
9 | super();
10 | }
11 | override private function createShader(): Program {
12 | return new Program(gl, {
13 | vertex: Webpack.require("./shaders/diffuseSpecular.vert.glsl"),
14 | fragment: Webpack.require("./shaders/diffuseSpecular.frag.glsl"),
15 | uniforms: {
16 | lightCol: {value: getLightColor(light)},
17 | lightDir: {value: getLightDirection(light)},
18 | meshCol: {value: new Vec3(1, 0, 1)},
19 | meshSpecCol: {value: new Vec3(1, 1, 1)},
20 | },
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/ch09/LightModelBase.hx:
--------------------------------------------------------------------------------
1 | package ch09;
2 |
3 | import externs.Ply.PLYLoader;
4 | import externs.Ply.Loader;
5 | import externs.Ogl.Geometry;
6 | import externs.Ogl.Program;
7 | import externs.Ogl.Vec3;
8 | import utils.DirectionalLight;
9 | import externs.Ogl.Mesh;
10 | import utils.OglBase;
11 | import js.Browser;
12 |
13 | abstract class LightModelBase extends OglBase {
14 | private var program:Program;
15 | private var mesh:Mesh;
16 | private var light:DirectionalLight;
17 |
18 | public function new() {
19 | super();
20 | light = new DirectionalLight();
21 | light.intensity = 1.0;
22 | light.color = new Vec3(1, 1, 1);
23 | light.direction = new Vec3(0, -1, 0);
24 | }
25 |
26 | override private function setup():Void {
27 | super.setup();
28 | Loader.load(getModel(), PLYLoader, {}).then(r -> {
29 | program = createShader();
30 | final geometry = new Geometry(gl, {
31 | position: {size: r.attributes.POSITION.size, data: r.attributes.POSITION.value},
32 | uv: {size: r.attributes.TEXCOORD_0.size, data: r.attributes.TEXCOORD_0.value},
33 | normal: {size: r.attributes.NORMAL.size, data: r.attributes.NORMAL.value},
34 | index: {size: r.indices.size, data: r.indices.value},
35 | });
36 |
37 | mesh = new Mesh(gl, {geometry: geometry, program: program});
38 | mesh.rotation.x = Math.PI * 0.75;
39 | mesh.setParent(scene);
40 |
41 | Browser.window.requestAnimationFrame(onFrame);
42 | });
43 | }
44 |
45 | override public function onFrame(dt:Float):Void {
46 | super.onFrame(dt);
47 | rotateMesh(dt);
48 | }
49 |
50 | abstract private function createShader(): Program;
51 | private function getModel() {
52 | return Webpack.require("../../original/ch9/Assets/torus.ply");
53 | }
54 | private function rotateMesh(dt:Float) {
55 | mesh.rotation.x += 0.01;
56 | mesh.rotation.y += 0.01;
57 | mesh.rotation.z += 0.01;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/ch09/PhongTorus.hx:
--------------------------------------------------------------------------------
1 | package ch09;
2 |
3 | import externs.Ogl.Program;
4 | import externs.Ogl.Vec3;
5 | import utils.DirectionalLight;
6 |
7 | class PhongTorus extends LightModelBase {
8 | public function new() {
9 | super();
10 | }
11 | override private function createShader(): Program {
12 | return new Program(gl, {
13 | vertex: Webpack.require("./shaders/phong.vert.glsl"),
14 | fragment: Webpack.require("./shaders/phong.frag.glsl"),
15 | uniforms: {
16 | lightCol: {value: getLightColor(light)},
17 | lightDir: {value: getLightDirection(light)},
18 | meshCol: {value: new Vec3(0.0, 0.5, 1)},
19 | meshSpecCol: {value: new Vec3(1, 1, 1)},
20 | ambientCol: {value: new Vec3(0.0, 0.3, 0.0)},
21 | },
22 | });
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/ch09/SpecularTorus.hx:
--------------------------------------------------------------------------------
1 | package ch09;
2 |
3 | import externs.Ogl.Program;
4 | import externs.Ogl.Vec3;
5 | import utils.DirectionalLight;
6 |
7 | class SpecularTorus extends LightModelBase {
8 | public function new() {
9 | super();
10 | }
11 | override private function createShader(): Program {
12 | return new Program(gl, {
13 | vertex: Webpack.require("./shaders/specular.vert.glsl"),
14 | fragment: Webpack.require("./shaders/specular.frag.glsl"),
15 | uniforms: {
16 | lightCol: {value: getLightColor(light)},
17 | lightDir: {value: getLightDirection(light)},
18 | meshCol: {value: new Vec3(1, 0, 1)},
19 | meshSpecCol: {value: new Vec3(1, 1, 1)},
20 | },
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/ch09/shaders/blinnPhong.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragNormal;
6 | in vec3 fragWorldPos;
7 |
8 | uniform vec3 lightDir;
9 | uniform vec3 lightCol;
10 | uniform vec3 meshCol;
11 | uniform vec3 meshSpecCol;
12 | uniform vec3 ambientCol;
13 | uniform vec3 cameraPosition;
14 |
15 | out vec4 outColor;
16 |
17 | void main() {
18 | vec3 normal = normalize(fragNormal);
19 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
20 | vec3 halfVec = normalize(viewDir + lightDir);
21 |
22 | float diffuseAmount = max(0.0, dot(normal, lightDir));
23 | vec3 diffuseColor = meshCol * lightCol * diffuseAmount;
24 |
25 | float specularAmount = max(0.0, dot(halfVec, normal));
26 | float specularBrightnes = pow(specularAmount, 64.0);
27 | vec3 specularColor = meshSpecCol * lightCol * specularBrightnes;
28 |
29 | vec3 ambient = ambientCol * meshCol;
30 |
31 | outColor = vec4(diffuseColor + specularColor + ambient, 1.0);
32 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/blinnPhong.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 | uniform mat3 normalMatrix;
11 |
12 | out vec3 fragNormal;
13 | out vec3 fragWorldPos;
14 |
15 | void main() {
16 | fragNormal = normalMatrix * normal;
17 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
18 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
19 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/blinnShield.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragNormal;
6 | in vec3 fragWorldPos;
7 | in vec2 fragUV;
8 |
9 | uniform vec3 lightDir;
10 | uniform vec3 lightCol;
11 | uniform vec3 ambientCol;
12 | uniform vec3 cameraPosition;
13 | uniform sampler2D diffuseTex;
14 | uniform sampler2D specTex;
15 |
16 | out vec4 outColor;
17 |
18 | void main() {
19 | vec3 normal = normalize(fragNormal);
20 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
21 | vec3 halfVec = normalize(viewDir + lightDir);
22 |
23 | vec3 meshCol = texture(diffuseTex, fragUV).xyz;
24 | vec3 meshSpecCol = texture(specTex, fragUV).xyz;
25 |
26 | float diffuseAmount = max(0.0, dot(normal, lightDir));
27 | vec3 diffuseColor = meshCol * lightCol * diffuseAmount;
28 |
29 | float specularAmount = max(0.0, dot(halfVec, normal));
30 | float specularBrightnes = pow(specularAmount, 64.0);
31 | vec3 specularColor = meshSpecCol.x * lightCol * specularBrightnes;
32 |
33 | vec3 ambient = ambientCol * meshCol;
34 |
35 | outColor = vec4(diffuseColor + specularColor + ambient, 1.0);
36 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/blinnShield.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 | in vec2 uv;
8 |
9 | uniform mat4 modelViewMatrix;
10 | uniform mat4 projectionMatrix;
11 | uniform mat3 normalMatrix;
12 |
13 | out vec3 fragNormal;
14 | out vec3 fragWorldPos;
15 | out vec2 fragUV;
16 |
17 | void main() {
18 | fragUV = uv;
19 | fragNormal = normalMatrix * normal;
20 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
21 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
22 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/diffuseSpecular.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragNormal;
6 | in vec3 fragWorldPos;
7 |
8 | uniform vec3 lightDir;
9 | uniform vec3 lightCol;
10 | uniform vec3 meshCol;
11 | uniform vec3 meshSpecCol;
12 | uniform vec3 cameraPosition;
13 |
14 | out vec4 outColor;
15 |
16 | void main() {
17 | vec3 normal = normalize(fragNormal);
18 | vec3 reflection = reflect(-lightDir, normal);
19 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
20 |
21 | float diffuseAmount = max(0.0, dot(normal, lightDir));
22 | vec3 diffuseColor = meshCol * lightCol * diffuseAmount;
23 |
24 | float specularAmount = max(0.0, dot(reflection, viewDir));
25 | float specularBrightnes = pow(specularAmount, 16.0);
26 | vec3 specularColor = meshSpecCol * lightCol * specularBrightnes;
27 |
28 | outColor = vec4(diffuseColor + specularColor, 1.0);
29 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/diffuseSpecular.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 | uniform mat3 normalMatrix;
11 |
12 | out vec3 fragNormal;
13 | out vec3 fragWorldPos;
14 |
15 | void main() {
16 | fragNormal = normalMatrix * normal;
17 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
18 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
19 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/phong.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragNormal;
6 | in vec3 fragWorldPos;
7 |
8 | uniform vec3 lightDir;
9 | uniform vec3 lightCol;
10 | uniform vec3 meshCol;
11 | uniform vec3 meshSpecCol;
12 | uniform vec3 ambientCol;
13 | uniform vec3 cameraPosition;
14 |
15 | out vec4 outColor;
16 |
17 | void main() {
18 | vec3 normal = normalize(fragNormal);
19 | vec3 reflection = reflect(-lightDir, normal);
20 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
21 |
22 | float diffuseAmount = max(0.0, dot(normal, lightDir));
23 | vec3 diffuseColor = meshCol * lightCol * diffuseAmount;
24 |
25 | float specularAmount = max(0.0, dot(reflection, viewDir));
26 | float specularBrightnes = pow(specularAmount, 16.0);
27 | vec3 specularColor = meshSpecCol * lightCol * specularBrightnes;
28 |
29 | vec3 ambient = ambientCol * meshCol;
30 |
31 | outColor = vec4(diffuseColor + specularColor + ambient, 1.0);
32 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/phong.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 | uniform mat3 normalMatrix;
11 |
12 | out vec3 fragNormal;
13 | out vec3 fragWorldPos;
14 |
15 | void main() {
16 | fragNormal = normalMatrix * normal;
17 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
18 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
19 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/specular.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragNormal;
6 | in vec3 fragWorldPos;
7 |
8 | uniform vec3 lightDir;
9 | uniform vec3 lightCol;
10 | uniform vec3 meshCol;
11 | uniform vec3 meshSpecCol;
12 | uniform vec3 cameraPosition;
13 |
14 | out vec4 outColor;
15 | void main() {
16 | vec3 normal = normalize(fragNormal);
17 | vec3 reflection = reflect(-lightDir, normal);
18 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
19 |
20 | float specularAmount = max(0.0, dot(reflection, viewDir));
21 | float specularBrightnes = pow(specularAmount, 16.0);
22 |
23 | outColor = vec4(lightCol * meshSpecCol * specularBrightnes, 1.0);
24 | }
--------------------------------------------------------------------------------
/src/ch09/shaders/specular.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 |
8 | uniform mat4 modelViewMatrix;
9 | uniform mat4 projectionMatrix;
10 | uniform mat3 normalMatrix;
11 |
12 | out vec3 fragNormal;
13 | out vec3 fragWorldPos;
14 |
15 | void main() {
16 | fragNormal = normalMatrix * normal;
17 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
18 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
19 | }
--------------------------------------------------------------------------------
/src/ch10/NormalMapping.hx:
--------------------------------------------------------------------------------
1 | package ch10;
2 |
3 | import utils.LoadTexture.loadTexture;
4 | import externs.Ogl.Program;
5 | import externs.Ogl.Vec3;
6 | import utils.DirectionalLight;
7 |
8 | class NormalMapping extends NormalMappingBase {
9 | public function new() {
10 | super();
11 | }
12 | override private function createShader():Program {
13 | return new Program(gl, {
14 | vertex: Webpack.require("./shaders/normalMapping.vert.glsl"),
15 | fragment: Webpack.require("./shaders/normalMapping.frag.glsl"),
16 | uniforms: {
17 | lightCol: {value: getLightColor(light)},
18 | lightDir: {value: getLightDirection(light)},
19 | ambientCol: {value: new Vec3(0.0, 0.0, 0.0)},
20 | diffuseTex: {value: loadTexture(Webpack.require("../../original/ch10/Assets/shield_diffuse.png"), gl)},
21 | specTex: {value: loadTexture(Webpack.require("../../original/ch10/Assets/shield_spec.png"), gl)},
22 | normalTex: {value: loadTexture(Webpack.require("../../original/ch10/Assets/shield_normal.png"), gl)},
23 | },
24 | });
25 | }
26 |
27 | override private function getModel() {
28 | return Webpack.require("../../original/ch10/Assets/shield.ply");
29 | }
30 |
31 | override public function onFrame(dt:Float):Void {
32 | super.onFrame(dt);
33 | rotateMesh(dt);
34 | }
35 |
36 | function rotateMesh(dt:Float) {
37 | mesh.rotation.x = -Math.PI * 0.25;
38 | mesh.rotation.y += 0.01;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/ch10/NormalMappingBase.hx:
--------------------------------------------------------------------------------
1 | package ch10;
2 |
3 | import js.Browser;
4 | import externs.Ply.PLYLoader;
5 | import externs.Ply.Loader;
6 | import externs.Ogl.Mesh;
7 | import utils.OglBase;
8 | import externs.Ogl.Program;
9 | import externs.Ogl.Vec3;
10 | import utils.DirectionalLight;
11 | import utils.CreatePLYGeometry.createPLYGeometry;
12 |
13 | abstract class NormalMappingBase extends OglBase {
14 | private var program:Program;
15 | private var mesh:Mesh;
16 | private var light:DirectionalLight;
17 |
18 | public function new() {
19 | super();
20 | light = new DirectionalLight();
21 | light.intensity = 1.0;
22 | light.color = new Vec3(1, 1, 1);
23 | light.direction = new Vec3(0, -1, 0);
24 | camera.position.set(0, 0, 3);
25 | }
26 |
27 | override private function setup():Void {
28 | super.setup();
29 | Loader.load(getModel(), PLYLoader, {}).then(r -> {
30 | program = createShader();
31 | final geometry = createPLYGeometry(gl, r);
32 |
33 | mesh = new Mesh(gl, {geometry: geometry, program: program});
34 | mesh.rotation.x = Math.PI * 0.75;
35 | mesh.setParent(scene);
36 |
37 | Browser.window.requestAnimationFrame(onFrame);
38 | });
39 | }
40 |
41 | abstract private function createShader():Program;
42 |
43 | abstract function getModel(): String;
44 | }
45 |
--------------------------------------------------------------------------------
/src/ch10/Water.hx:
--------------------------------------------------------------------------------
1 | package ch10;
2 |
3 | import utils.LoadTexture.loadTexture;
4 | import js.html.webgl.WebGL2RenderingContext;
5 | import externs.Ogl.Program;
6 | import externs.Ogl.Vec3;
7 | import utils.DirectionalLight;
8 |
9 | class Water extends NormalMappingBase {
10 | public function new() {
11 | super();
12 | light.direction = new Vec3(0.5, -1, -1);
13 | }
14 | override private function createShader():Program {
15 | return new Program(gl, {
16 | vertex: Webpack.require("./shaders/water.vert.glsl"),
17 | fragment: Webpack.require("./shaders/water.frag.glsl"),
18 | uniforms: {
19 | time: { value: 0 },
20 | lightCol: {value: getLightColor(light)},
21 | lightDir: {value: getLightDirection(light)},
22 | normalTex: {value: loadTexture(
23 | Webpack.require("../../original/ch10/Assets/water_nrm.png"),
24 | gl,
25 | {
26 | wrapS: WebGL2RenderingContext.REPEAT,
27 | wrapT: WebGL2RenderingContext.REPEAT,
28 | flipY: false,
29 | }
30 | )},
31 | },
32 | cullFace: null,
33 | });
34 | }
35 |
36 | override private function getModel() {
37 | return Webpack.require("../../original/ch10/Assets/plane.ply");
38 | }
39 | override public function onFrame(dt:Float):Void {
40 | super.onFrame(dt);
41 | program.uniforms.time.value = dt * 0.001;
42 | mesh.rotation.x = Math.PI * 1.3;
43 | mesh.rotation.y = Math.PI;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/ch10/shaders/normalMapping.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragWorldPos;
6 | in vec2 fragUV;
7 | in mat3 TBN;
8 |
9 | uniform vec3 lightDir;
10 | uniform vec3 lightCol;
11 | uniform vec3 ambientCol;
12 | uniform vec3 cameraPosition;
13 | uniform sampler2D diffuseTex;
14 | uniform sampler2D specTex;
15 | uniform sampler2D normalTex;
16 |
17 | out vec4 outColor;
18 |
19 | void main() {
20 | vec3 normal = texture(normalTex, fragUV).rgb;
21 | normal = normalize(normal * 2.0 - 1.0);
22 | normal = normalize(TBN * normal);
23 |
24 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
25 | vec3 halfVec = normalize(viewDir + lightDir);
26 |
27 | vec3 meshCol = texture(diffuseTex, fragUV).xyz;
28 | vec3 meshSpecCol = texture(specTex, fragUV).xyz;
29 |
30 | float diffuseAmount = max(0.0, dot(normal, lightDir));
31 | vec3 diffuseColor = lightCol * diffuseAmount;
32 |
33 | float specularAmount = max(0.0, dot(halfVec, normal));
34 | float specularBrightnes = pow(specularAmount, 64.0);
35 | vec3 specularColor = meshSpecCol.x * lightCol * specularBrightnes;
36 |
37 | vec3 ambient = ambientCol * meshCol;
38 |
39 | outColor = vec4(diffuseColor + specularColor + ambient, 1.0);
40 | }
--------------------------------------------------------------------------------
/src/ch10/shaders/normalMapping.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 | in vec2 uv;
8 | in vec3 tangent;
9 |
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 projectionMatrix;
12 | uniform mat3 normalMatrix;
13 |
14 | out vec3 fragWorldPos;
15 | out vec2 fragUV;
16 | out mat3 TBN;
17 |
18 | void main() {
19 | vec3 T = normalize(normalMatrix * tangent.xyz);
20 | vec3 B = normalize(normal * cross(tangent.xyz, normal.xyz));
21 | vec3 N = normalize(normalMatrix * normal);
22 |
23 | TBN = mat3(T, B, N);
24 |
25 | fragUV = uv;
26 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
27 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
28 | }
--------------------------------------------------------------------------------
/src/ch10/shaders/water.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragWorldPos;
6 | in vec2 fragUV;
7 | in vec2 fragUV2;
8 | in mat3 TBN;
9 |
10 | uniform vec3 lightDir;
11 | uniform vec3 lightCol;
12 | uniform vec3 cameraPosition;
13 | uniform sampler2D normalTex;
14 |
15 | out vec4 outColor;
16 |
17 | void main() {
18 | vec3 normal = texture(normalTex, fragUV).rgb;
19 | normal = normalize(normal * 2.0 - 1.0);
20 |
21 | vec3 normal2 = texture(normalTex, fragUV2).rgb;
22 | normal2 = normalize(normal2 * 2.0 - 1.0);
23 |
24 | normal = normalize((normal + normal2));
25 |
26 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
27 | vec3 halfVec = normalize(viewDir + lightDir);
28 |
29 | float diffuseAmount = max(0.0, dot(normal, lightDir));
30 | vec3 diffuseColor = vec3(0.3, 0.3, 0.4) * lightCol * diffuseAmount;
31 |
32 | float specularAmount = max(0.0, dot(halfVec, normal));
33 | float specularBrightnes = pow(specularAmount, 512.0);
34 | vec3 specularColor = lightCol * specularBrightnes;
35 |
36 | outColor = vec4(diffuseColor + specularColor, 1.0);
37 | }
--------------------------------------------------------------------------------
/src/ch10/shaders/water.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 | in vec2 uv;
8 | in vec3 tangent;
9 |
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 projectionMatrix;
12 | uniform mat3 normalMatrix;
13 | uniform float time;
14 |
15 | out vec3 fragWorldPos;
16 | out vec2 fragUV;
17 | out vec2 fragUV2;
18 | out mat3 TBN;
19 |
20 | void main() {
21 | vec3 T = normalize(normalMatrix * tangent.xyz);
22 | vec3 B = normalize(normalMatrix * cross(tangent.xyz, normal.xyz));
23 | vec3 N = normalize(normalMatrix * normal);
24 |
25 | TBN = mat3(T, B, N);
26 |
27 | float t = time * 0.05;
28 | float t2 = time * 0.02;
29 | fragUV = vec2(uv.x + t, uv.y) * 3.0;
30 | fragUV2= vec2(uv.x + t2, uv.y - t2) * 2.0;
31 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
32 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
33 | }
--------------------------------------------------------------------------------
/src/ch11/CubeMap.hx:
--------------------------------------------------------------------------------
1 | package ch11;
2 |
3 | import externs.Ogl.Program;
4 | import externs.Ogl.Mesh;
5 | import ch11.CubeMapBase;
6 |
7 | class CubeMap extends CubeMapBase {
8 | private var mesh: Null = null;
9 | public function new() {
10 | super();
11 | }
12 | override private function setup():Void {
13 | super.setup();
14 | loadModel(
15 | Webpack.require("../../original/ch11/1_DrawCube/bin/data/cube.ply"),
16 | new Program(gl, {
17 | vertex: Webpack.require("./shaders/cubeMap.vert.glsl"),
18 | fragment: Webpack.require("./shaders/cubeMap.frag.glsl"),
19 | uniforms: {
20 | cubeTexture: {value: createCubeMapTexture(gl, [
21 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_left.jpg'),
22 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_right.jpg'),
23 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_top.jpg'),
24 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_bottom.jpg'),
25 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_back.jpg'),
26 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_front.jpg'),
27 | ])},
28 | },
29 | }),
30 | mesh -> {
31 | this.mesh = mesh;
32 | }
33 | );
34 | }
35 | override public function onFrame(dt:Float):Void {
36 | super.onFrame(dt);
37 | if (mesh != null) {
38 | mesh.rotation.y += 0.01;
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/ch11/CubeMapBase.hx:
--------------------------------------------------------------------------------
1 | package ch11;
2 |
3 | import js.html.Image;
4 | import js.lib.Promise;
5 | import utils.LoadImage.loadImage;
6 | import externs.Ogl.Texture;
7 | import js.html.webgl.WebGL2RenderingContext;
8 | import externs.Ogl.GL;
9 | import js.Browser;
10 | import externs.Ply.PLYLoader;
11 | import externs.Ply.Loader;
12 | import externs.Ogl.Mesh;
13 | import utils.OglBase;
14 | import externs.Ogl.Program;
15 | import externs.Ogl.Vec3;
16 | import utils.DirectionalLight;
17 | import utils.CreatePLYGeometry.createPLYGeometry;
18 |
19 | abstract class CubeMapBase extends OglBase {
20 | private var light:DirectionalLight;
21 | public function new() {
22 | super();
23 | }
24 |
25 | override private function setup():Void {
26 | super.setup();
27 | light = new DirectionalLight();
28 | light.intensity = 1.0;
29 | light.color = new Vec3(1, 1, 1);
30 | light.direction = new Vec3(0, -1, 0);
31 | camera.position.set(0, 0, 3);
32 | Browser.window.requestAnimationFrame(onFrame);
33 | }
34 |
35 | private function loadModel(path: String, shader: Program, ?onLoaded: (mesh: Mesh) -> Void) {
36 | Loader.load(path, PLYLoader, {}).then(r -> {
37 | final geometry = createPLYGeometry(gl, r);
38 | final mesh = new Mesh(gl, {geometry: geometry, program: shader});
39 | mesh.setParent(scene);
40 | if (onLoaded != null) {
41 | onLoaded(mesh);
42 | }
43 | });
44 | }
45 | private function createCubeMapTexture(gl: GL, images: Array): Texture {
46 | final texture = new Texture(gl, {
47 | target: WebGL2RenderingContext.TEXTURE_CUBE_MAP,
48 | });
49 | final imagesToLoad: Array> = [];
50 | for(path in images) {
51 | imagesToLoad.push(loadImage(path));
52 | }
53 | Promise.all(imagesToLoad).then((images: Array) -> {
54 | texture.image = images;
55 | });
56 | return texture;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/ch11/SkyBox.hx:
--------------------------------------------------------------------------------
1 | package ch11;
2 |
3 | import externs.Ogl.Vec3;
4 | import utils.LoadTexture.loadTexture;
5 | import utils.DirectionalLight.getLightDirection;
6 | import utils.DirectionalLight.getLightColor;
7 | import js.html.webgl.WebGL2RenderingContext;
8 | import externs.Ogl.Program;
9 | import externs.Ogl.Mesh;
10 | import ch11.CubeMapBase;
11 |
12 | class SkyBox extends CubeMapBase {
13 | private var water: Null;
14 | public function new() {
15 | super();
16 | }
17 | override private function setup():Void {
18 | super.setup();
19 | light.direction = new Vec3(0.5, -1, -1);
20 | final cubeTexture = createCubeMapTexture(gl, [
21 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_left.jpg'),
22 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_right.jpg'),
23 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_top.jpg'),
24 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_bottom.jpg'),
25 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_back.jpg'),
26 | Webpack.require('../../original/ch11/1_DrawCube/bin/data/cube_front.jpg'),
27 | ]);
28 | loadModel(
29 | Webpack.require("../../original/ch11/1_DrawCube/bin/data/cube.ply"),
30 | new Program(gl, {
31 | vertex: Webpack.require("./shaders/skyBox.vert.glsl"),
32 | fragment: Webpack.require("./shaders/cubeMap.frag.glsl"),
33 | uniforms: {
34 | cubeTexture: {value: cubeTexture},
35 | },
36 | depthFunc: WebGL2RenderingContext.LEQUAL,
37 | frontFace: WebGL2RenderingContext.CW,
38 | }),
39 | mesh -> {
40 | mesh.scale.set(4,4,4);
41 | }
42 | );
43 | loadModel(
44 | Webpack.require("../../original/ch11/Assets/plane.ply"),
45 | new Program(gl, {
46 | vertex: Webpack.require("./shaders/water.vert.glsl"),
47 | fragment: Webpack.require("./shaders/water.frag.glsl"),
48 | uniforms: {
49 | cubeTexture: {value: cubeTexture},
50 | time: { value: 0 },
51 | lightCol: {value: getLightColor(light)},
52 | lightDir: {value: getLightDirection(light)},
53 | normalTex: {value: loadTexture(
54 | Webpack.require("../../original/ch10/Assets/water_nrm.png"),
55 | gl,
56 | {
57 | wrapS: WebGL2RenderingContext.REPEAT,
58 | wrapT: WebGL2RenderingContext.REPEAT,
59 | }
60 | )},
61 | },
62 | }),
63 | mesh -> {
64 | mesh.scale.set(10,10,1);
65 | mesh.rotation.x = Math.PI * 1.45;
66 | mesh.rotation.y = Math.PI;
67 | mesh.position.y -= 4;
68 | mesh.position.z -= 8;
69 | water = mesh;
70 | }
71 | );
72 | }
73 | override public function onFrame(dt:Float):Void {
74 | super.onFrame(dt);
75 | if (water != null) {
76 | water.program.uniforms.time.value = dt * 0.001;
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/ch11/shaders/cubeMap.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragPos;
6 |
7 | uniform samplerCube cubeTexture;
8 |
9 | out vec4 outColor;
10 |
11 | void main() {
12 |
13 | outColor = texture(cubeTexture, fragPos);
14 | }
--------------------------------------------------------------------------------
/src/ch11/shaders/cubeMap.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 |
7 | uniform mat4 modelViewMatrix;
8 | uniform mat4 projectionMatrix;
9 |
10 | out vec3 fragPos;
11 |
12 | void main() {
13 | fragPos = position;
14 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
15 | }
--------------------------------------------------------------------------------
/src/ch11/shaders/skyBox.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 |
7 | uniform mat4 modelViewMatrix;
8 | uniform mat4 projectionMatrix;
9 |
10 | out vec3 fragPos;
11 |
12 | void main() {
13 | fragPos = position;
14 | gl_Position = (projectionMatrix * modelViewMatrix * vec4(position, 1.0)).xyww;
15 | }
--------------------------------------------------------------------------------
/src/ch11/shaders/water.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 fragWorldPos;
6 | in vec2 fragUV;
7 | in vec2 fragUV2;
8 | in mat3 TBN;
9 |
10 | uniform vec3 lightDir;
11 | uniform vec3 lightCol;
12 | uniform vec3 cameraPosition;
13 | uniform sampler2D normalTex;
14 | uniform samplerCube cubeTexture;
15 |
16 | out vec4 outColor;
17 |
18 | void main() {
19 | vec3 normal = texture(normalTex, fragUV).rgb;
20 | normal = normalize(normal * 2.0 - 1.0);
21 |
22 | vec3 normal2 = texture(normalTex, fragUV2).rgb;
23 | normal2 = normalize(normal2 * 2.0 - 1.0);
24 |
25 | normal = normalize((normal + normal2));
26 |
27 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
28 | vec3 halfVec = normalize(viewDir + lightDir);
29 |
30 | float diffuseAmount = max(0.0, dot(normal, lightDir));
31 | vec3 diffuseColor = texture(cubeTexture, reflect(-viewDir, normal)).xyz * lightCol * diffuseAmount;
32 |
33 | float specularAmount = max(0.0, dot(halfVec, normal));
34 | float specularBrightnes = pow(specularAmount, 512.0);
35 | vec3 specularColor = lightCol * specularBrightnes;
36 |
37 | outColor = vec4(diffuseColor + specularColor, 1.0);
38 | }
--------------------------------------------------------------------------------
/src/ch11/shaders/water.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 | in vec2 uv;
8 | in vec3 tangent;
9 |
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 projectionMatrix;
12 | uniform mat3 normalMatrix;
13 | uniform float time;
14 |
15 | out vec3 fragWorldPos;
16 | out vec2 fragUV;
17 | out vec2 fragUV2;
18 | out mat3 TBN;
19 |
20 | void main() {
21 | vec3 T = normalize(normalMatrix * tangent.xyz);
22 | vec3 B = normalize(normalMatrix * cross(tangent.xyz, normal.xyz));
23 | vec3 N = normalize(normalMatrix * normal);
24 |
25 | TBN = mat3(T, B, N);
26 |
27 | float t = time * 0.05;
28 | float t2 = time * 0.02;
29 | fragUV = vec2(uv.x + t, uv.y) * 3.0;
30 | fragUV2= vec2(uv.x + t2, uv.y - t2) * 2.0;
31 | fragWorldPos = (modelViewMatrix * vec4(position, 1.0)).xyz;
32 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
33 | }
--------------------------------------------------------------------------------
/src/ch12/LightBase.hx:
--------------------------------------------------------------------------------
1 | package ch12;
2 |
3 | import js.html.Image;
4 | import js.lib.Promise;
5 | import utils.LoadImage.loadImage;
6 | import externs.Ogl.Texture;
7 | import js.html.webgl.WebGL2RenderingContext;
8 | import externs.Ogl.GL;
9 | import js.Browser;
10 | import externs.Ply.PLYLoader;
11 | import externs.Ply.Loader;
12 | import externs.Ogl.Mesh;
13 | import utils.OglBase;
14 | import externs.Ogl.Program;
15 | import utils.CreatePLYGeometry.createPLYGeometry;
16 |
17 | abstract class LightBase extends OglBase {
18 | public function new() {
19 | super();
20 | }
21 |
22 | override private function setup():Void {
23 | super.setup();
24 | Browser.window.requestAnimationFrame(onFrame);
25 | }
26 |
27 | private function loadModel(path: String, shader: Program, ?onLoaded: (mesh: Mesh) -> Void) {
28 | Loader.load(path, PLYLoader, {}).then(r -> {
29 | final geometry = createPLYGeometry(gl, r);
30 | final mesh = new Mesh(gl, {geometry: geometry, program: shader});
31 | mesh.setParent(scene);
32 | if (onLoaded != null) {
33 | onLoaded(mesh);
34 | }
35 | });
36 | }
37 | private function createCubeMapTexture(gl: GL, images: Array): Texture {
38 | final texture = new Texture(gl, {
39 | target: WebGL2RenderingContext.TEXTURE_CUBE_MAP,
40 | });
41 | final imagesToLoad: Array> = [];
42 | for(path in images) {
43 | imagesToLoad.push(loadImage(path));
44 | }
45 | Promise.all(imagesToLoad).then((images: Array) -> {
46 | texture.image = images;
47 | });
48 | return texture;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/ch12/MultiPass.hx:
--------------------------------------------------------------------------------
1 | package ch12;
2 |
3 | import ch12.multipass.PointLight;
4 | import ch12.multipass.DirectionalLight;
5 | import utils.LoadTexture.loadTexture;
6 | import ch12.LightBase;
7 | import externs.Ogl.Mesh;
8 | import externs.Ogl.Program;
9 | import externs.Ogl.Vec3;
10 |
11 | class MultiPass extends LightBase {
12 | private var mesh: Null = null;
13 | private var directionalLightShader: Null = null;
14 | private var pointLightShader: Null = null;
15 | private var shieldShader: Null = null;
16 | private var directionalLight: Null = null;
17 | private var pointLights: Null> = null;
18 | public function new() {
19 | super();
20 | camera.position.set(0, 0, 6);
21 | }
22 |
23 | override private function setup():Void {
24 | super.setup();
25 | pointLights = [];
26 | directionalLight = new DirectionalLight(
27 | new Vec3(0, -1, 0),
28 | new Vec3(1, 1, 1),
29 | 2
30 | );
31 | pointLights.push(new PointLight(
32 | new Vec3(0, 0.5, 0.75),
33 | new Vec3(1, 0, 1),
34 | 4,
35 | 1
36 | ));
37 | pointLights.push(new PointLight(
38 | new Vec3(0.5, 0.5, 0.75),
39 | new Vec3(0, 1, 1),
40 | 4,
41 | 1
42 | ));
43 |
44 | directionalLightShader = new Program(gl, {
45 | vertex: Webpack.require("./shaders/light.vert.glsl"),
46 | fragment: Webpack.require("./shaders/pointLight.frag.glsl"),
47 | uniforms: {},
48 | });
49 |
50 | pointLightShader = new Program(gl, {
51 | vertex: Webpack.require("./shaders/light.vert.glsl"),
52 | fragment: Webpack.require("./shaders/pointLight.frag.glsl"),
53 | uniforms: {},
54 | });
55 |
56 | shieldShader = new Program(gl, {
57 | vertex: Webpack.require("./shaders/light.vert.glsl"),
58 | fragment: Webpack.require("./shaders/multiplLights.frag.glsl"),
59 | uniforms: {
60 | diffuseTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_diffuse.png"), gl) },
61 | specTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_spec.png"), gl)},
62 | normalTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_normal.png"), gl)} ,
63 | cubeTexture: {value: createCubeMapTexture(gl, [
64 | Webpack.require('../../original/ch12/Assets/night_left.jpg'),
65 | Webpack.require('../../original/ch12/Assets/night_right.jpg'),
66 | Webpack.require('../../original/ch12/Assets/night_top.jpg'),
67 | Webpack.require('../../original/ch12/Assets/night_bottom.jpg'),
68 | Webpack.require('../../original/ch12/Assets/night_back.jpg'),
69 | Webpack.require('../../original/ch12/Assets/night_front.jpg'),
70 | ])},
71 | },
72 | });
73 |
74 | loadModel(
75 | Webpack.require("../../original/ch12/Assets/shield.ply"),
76 | shieldShader,
77 | mesh -> {
78 | this.mesh = mesh;
79 | }
80 | );
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/ch12/MultipleLights.hx:
--------------------------------------------------------------------------------
1 | package ch12;
2 |
3 | import ch12.lights.PointLight;
4 | import utils.DirectionalLight;
5 | import utils.Degree.toRadians;
6 | import utils.LoadTexture.loadTexture;
7 | import ch12.LightBase;
8 | import ch12.lights.SpotLight;
9 | import externs.Ogl.Mesh;
10 | import externs.Ogl.Program;
11 | import externs.Ogl.Vec3;
12 |
13 | class MultipleLights extends LightBase {
14 | private var mesh: Null = null;
15 | public function new() {
16 | super();
17 | camera.position.set(0, 0, 6);
18 | }
19 |
20 | override private function setup():Void {
21 | super.setup();
22 | final directionalLights: Array = [];
23 | final pointLights: Array = [];
24 | final spotLights: Array = [];
25 | directionalLights.push(new DirectionalLight(
26 | new Vec3(0, -1, 0),
27 | new Vec3(1, 1, 1),
28 | 2
29 | ));
30 | pointLights.push(new PointLight(
31 | new Vec3(0, 0.5, 0.75),
32 | new Vec3(1, 0, 1),
33 | 4,
34 | 1
35 | ));
36 | pointLights.push(new PointLight(
37 | new Vec3(0.5, 0.5, 0.75),
38 | new Vec3(0, 1, 1),
39 | 4,
40 | 1
41 | ));
42 | spotLights.push(new SpotLight(
43 | new Vec3(0.5, 0 ,6),
44 | new Vec3(0, 0, -1),
45 | new Vec3(1, 0, 0),
46 | 1.0,
47 | Math.cos(toRadians(4.5))
48 | ));
49 | spotLights.push(new SpotLight(
50 | new Vec3(-0.5, 0 ,6),
51 | new Vec3(0, 0, -1),
52 | new Vec3(0, 1, 0),
53 | 1.0,
54 | Math.cos(toRadians(4.5))
55 | ));
56 |
57 | final program = new Program(gl, {
58 | vertex: Webpack.require("./shaders/light.vert.glsl"),
59 | fragment: Webpack.require("./shaders/multiplLights.frag.glsl"),
60 | uniforms: {
61 | "directionalLights": directionalLights,
62 | "spotLights": spotLights,
63 | "pointLights": pointLights,
64 | diffuseTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_diffuse.png"), gl) },
65 | specTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_spec.png"), gl)},
66 | normalTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_normal.png"), gl)} ,
67 | cubeTexture: {value: createCubeMapTexture(gl, [
68 | Webpack.require('../../original/ch12/Assets/night_left.jpg'),
69 | Webpack.require('../../original/ch12/Assets/night_right.jpg'),
70 | Webpack.require('../../original/ch12/Assets/night_top.jpg'),
71 | Webpack.require('../../original/ch12/Assets/night_bottom.jpg'),
72 | Webpack.require('../../original/ch12/Assets/night_back.jpg'),
73 | Webpack.require('../../original/ch12/Assets/night_front.jpg'),
74 | ])},
75 | },
76 | });
77 |
78 | loadModel(
79 | Webpack.require("../../original/ch12/Assets/shield.ply"),
80 | program,
81 | mesh -> {
82 | this.mesh = mesh;
83 | }
84 | );
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/ch12/PointLightExample.hx:
--------------------------------------------------------------------------------
1 | package ch12;
2 |
3 | import utils.LoadTexture.loadTexture;
4 | import ch12.LightBase;
5 | import ch12.lights.PointLight;
6 | import externs.Ogl.Mesh;
7 | import externs.Ogl.Program;
8 | import externs.Ogl.Vec3;
9 |
10 | class PointLightExample extends LightBase {
11 | private var mesh: Null = null;
12 | private var light: PointLight;
13 | private var time: Float = 0.0;
14 | public function new() {
15 | super();
16 | camera.position.set(0, 0, 6);
17 | }
18 |
19 | override private function setup():Void {
20 | super.setup();
21 | light = new PointLight();
22 | light.intensity = 3.0;
23 | light.radius = 1;
24 | light.color = new Vec3(1, 1, 1);
25 | light.position.set(0, 0.5, 0.75);
26 |
27 | loadModel(
28 | Webpack.require("../../original/ch12/1_PointLights/bin/shield.ply"),
29 | new Program(gl, {
30 | vertex: Webpack.require("./shaders/light.vert.glsl"),
31 | fragment: Webpack.require("./shaders/pointLight.frag.glsl"),
32 | uniforms: {
33 | lightCol: { value: getLightColor(light) },
34 | lightRadius: { value: light.radius },
35 | lightPos: { value: light.position },
36 | diffuseTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_diffuse.png"), gl) },
37 | specTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_spec.png"), gl)},
38 | normalTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_normal.png"), gl)} ,
39 | cubeTexture: {value: createCubeMapTexture(gl, [
40 | Webpack.require('../../original/ch12/1_PointLights/bin/cube_left.jpg'),
41 | Webpack.require('../../original/ch12/1_PointLights/bin/cube_right.jpg'),
42 | Webpack.require('../../original/ch12/1_PointLights/bin/cube_top.jpg'),
43 | Webpack.require('../../original/ch12/1_PointLights/bin/cube_bottom.jpg'),
44 | Webpack.require('../../original/ch12/1_PointLights/bin/cube_back.jpg'),
45 | Webpack.require('../../original/ch12/1_PointLights/bin/cube_front.jpg'),
46 | ])},
47 | },
48 | }),
49 | mesh -> {
50 | this.mesh = mesh;
51 | }
52 | );
53 | }
54 | override public function onFrame(dt:Float):Void {
55 | super.onFrame(dt);
56 | if (light != null) {
57 | time += 0.01;
58 | light.position = new Vec3(Math.sin(time), 0.5, 0.75);
59 | if (mesh != null) {
60 | mesh.program.uniforms.lightPos.value = light.position;
61 | mesh.rotation.x += 0.01;
62 | mesh.rotation.y += 0.01;
63 | mesh.rotation.z += 0.01;
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/ch12/SpotLights.hx:
--------------------------------------------------------------------------------
1 | package ch12;
2 |
3 | import utils.Degree.toRadians;
4 | import utils.LoadTexture.loadTexture;
5 | import ch12.LightBase;
6 | import ch12.lights.SpotLight;
7 | import externs.Ogl.Mesh;
8 | import externs.Ogl.Program;
9 | import externs.Ogl.Vec3;
10 |
11 | class SpotLights extends LightBase {
12 | private var mesh: Null = null;
13 | private var light: SpotLight;
14 | public function new() {
15 | super();
16 | camera.position.set(0, 0, 6);
17 | }
18 |
19 | override private function setup():Void {
20 | super.setup();
21 | light = new SpotLight();
22 | light.intensity = 1.0;
23 | light.color = new Vec3(1, 1, 1);
24 | light.direction = new Vec3(0, 0, -1);
25 | light.position.set(0.5,0, 6);
26 | light.cutoff = Math.cos(toRadians(4.5));
27 |
28 | loadModel(
29 | Webpack.require("../../original/ch12/2_SpotLights/bin/shield.ply"),
30 | new Program(gl, {
31 | vertex: Webpack.require("./shaders/light.vert.glsl"),
32 | fragment: Webpack.require("./shaders/spotLight.frag.glsl"),
33 | uniforms: {
34 | lightCol: { value: getLightColor(light) },
35 | lightCutoff: { value: light.cutoff },
36 | lightPos: { value: light.position },
37 | lightConeDir: { value: light.direction },
38 | diffuseTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_diffuse.png"), gl) },
39 | specTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_spec.png"), gl)},
40 | normalTex: { value: loadTexture(Webpack.require("../../original/ch12/Assets/shield_normal.png"), gl)} ,
41 | cubeTexture: {value: createCubeMapTexture(gl, [
42 | Webpack.require('../../original/ch12/Assets/night_left.jpg'),
43 | Webpack.require('../../original/ch12/Assets/night_right.jpg'),
44 | Webpack.require('../../original/ch12/Assets/night_top.jpg'),
45 | Webpack.require('../../original/ch12/Assets/night_bottom.jpg'),
46 | Webpack.require('../../original/ch12/Assets/night_back.jpg'),
47 | Webpack.require('../../original/ch12/Assets/night_front.jpg'),
48 | ])},
49 | },
50 | }),
51 | mesh -> {
52 | this.mesh = mesh;
53 | }
54 | );
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/ch12/lights/PointLight.hx:
--------------------------------------------------------------------------------
1 | package ch12.lights;
2 |
3 | import externs.Ogl.Vec3;
4 |
5 | class PointLight {
6 | public var position: Vec3;
7 | public var color: Vec3;
8 | public var intensity: Float;
9 | public var radius: Float;
10 | public function new(?position: Vec3, ?color: Vec3, ?intensity: Float, ?radius: Float) {
11 | this.position = (position != null) ? position : new Vec3();
12 | this.color = (color != null) ? color : new Vec3(1, 1, 1);
13 | this.intensity = (intensity != null) ? intensity : 1;
14 | this.radius = (radius != null) ? radius : std.Math.POSITIVE_INFINITY;
15 | }
16 | }
17 | function getLightColor(light: PointLight): Vec3 {
18 | return light.color.clone().multiply(light.intensity);
19 | }
--------------------------------------------------------------------------------
/src/ch12/lights/SpotLight.hx:
--------------------------------------------------------------------------------
1 | package ch12.lights;
2 |
3 | import externs.Ogl.Vec3;
4 |
5 | class SpotLight {
6 | public var position: Vec3;
7 | public var direction: Vec3;
8 | public var color: Vec3;
9 | public var intensity: Float;
10 | public var cutoff: Float;
11 | public function new(?position: Vec3, ?direction: Vec3, ?color: Vec3, ?intensity: Float, ?cutoff: Float) {
12 | this.position = (position != null) ? position : new Vec3();
13 | this.direction = (direction != null) ? direction : new Vec3();
14 | this.color = (color != null) ? color : new Vec3(1, 1, 1);
15 | this.intensity = (intensity != null) ? intensity : 1;
16 | this.cutoff = (cutoff != null) ? cutoff : Math.PI;
17 | }
18 | }
19 | function getLightColor(light: SpotLight): Vec3 {
20 | return light.color.clone().multiply(light.intensity);
21 | }
--------------------------------------------------------------------------------
/src/ch12/multipass/DirectionalLight.hx:
--------------------------------------------------------------------------------
1 | package ch12.multipass;
2 |
3 | import externs.Ogl.Program;
4 | import externs.Ogl.Vec3;
5 |
6 | class DirectionalLight extends Light {
7 | public var direction: Vec3;
8 | public var color: Vec3;
9 | public var intensity: Float;
10 |
11 | public function new(?direction: Vec3, ?color: Vec3, ?intensity: Float) {
12 | this.direction = (direction != null) ? direction : new Vec3();
13 | this.color = (color != null) ? color : new Vec3(1, 1, 1);
14 | this.intensity = (intensity != null) ? intensity : 1;
15 | }
16 |
17 | override public function apply(shader: Program): Void {
18 | shader.uniforms.lightDir.value = direction.clone().negate().normalize();
19 | shader.uniforms.lightCol.value = color.clone().multiply(intensity);
20 | }
21 | }
--------------------------------------------------------------------------------
/src/ch12/multipass/Light.hx:
--------------------------------------------------------------------------------
1 | package ch12.multipass;
2 |
3 | import externs.Ogl.Program;
4 |
5 | abstract class Light {
6 | public function isPointLight(): Bool {
7 | return false;
8 | }
9 | abstract public function apply(shader: Program): Void;
10 | }
--------------------------------------------------------------------------------
/src/ch12/multipass/PointLight.hx:
--------------------------------------------------------------------------------
1 | package ch12.multipass;
2 |
3 | import externs.Ogl.Program;
4 | import externs.Ogl.Vec3;
5 |
6 | class PointLight extends Light {
7 | public var position: Vec3;
8 | public var intensity: Float;
9 | public var radius: Float;
10 | public var color: Vec3;
11 |
12 | public function new(?position: Vec3, ?color: Vec3, ?intensity: Float, ?radius: Float) {
13 | this.position = (position != null) ? position : new Vec3();
14 | this.color = (color != null) ? color : new Vec3(1, 1, 1);
15 | this.intensity = (intensity != null) ? intensity : 1;
16 | this.radius = (radius != null) ? radius : std.Math.POSITIVE_INFINITY;
17 | }
18 |
19 | override public function isPointLight(): Bool {
20 | return true;
21 | }
22 |
23 | override public function apply(shader: Program): Void {
24 | shader.uniforms.lightPos.value = position;
25 | shader.uniforms.lightCol.value = color.clone().multiply(intensity);
26 | shader.uniforms.lightRadius.value = radius;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/ch12/shaders/light.glsl:
--------------------------------------------------------------------------------
1 | float diffuse(vec3 lightDir, vec3 normal) {
2 | return max(0.0, dot(normal, lightDir));
3 | }
4 | float specular(vec3 lightDir, vec3 viewDir, vec3 normal, float shininess) {
5 | vec3 halfVec = normalize(viewDir + lightDir);
6 | float specAmt = max(0.0, dot(halfVec, normal));
7 | return pow(specAmt, shininess);
8 | }
--------------------------------------------------------------------------------
/src/ch12/shaders/light.vert.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | in vec3 position;
6 | in vec3 normal;
7 | in vec2 uv;
8 | in vec3 tangent;
9 |
10 | uniform mat4 modelViewMatrix;
11 | uniform mat4 modelMatrix;
12 | uniform mat4 projectionMatrix;
13 | uniform mat3 normalMatrix;
14 |
15 | out vec3 fragWorldPos;
16 | out vec2 fragUV;
17 | out mat3 TBN;
18 |
19 | void main() {
20 | vec3 T = normalize(normalMatrix * tangent.xyz);
21 | vec3 B = normalize(normalMatrix * cross(tangent.xyz, normal.xyz));
22 | vec3 N = normalize(normalMatrix * normal);
23 |
24 | TBN = mat3(T, B, N);
25 |
26 | fragUV = uv;
27 | fragWorldPos = (modelMatrix * vec4(position, 1.0)).xyz;
28 | gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
29 | }
--------------------------------------------------------------------------------
/src/ch12/shaders/multiplLights.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | struct DirectionalLight {
6 | vec3 direction;
7 | vec3 color;
8 | };
9 | struct PointLight {
10 | vec3 position;
11 | vec3 color;
12 | float radius;
13 | };
14 | struct SpotLight {
15 | vec3 position;
16 | vec3 direction;
17 | vec3 color;
18 | float cutoff;
19 | };
20 |
21 | #define NUM_DIR_LIGHTS 1
22 | #define NUM_POINTS_LIGHT 2
23 | #define NUM_SPOT_LIGHTS 2
24 |
25 | uniform DirectionalLight directionalLights[NUM_DIR_LIGHTS];
26 | uniform SpotLight spotLights[NUM_SPOT_LIGHTS];
27 | uniform PointLight pointLights[NUM_POINTS_LIGHT];
28 |
29 | uniform sampler2D normalTex;
30 | uniform sampler2D diffuseTex;
31 | uniform sampler2D specTex;
32 | uniform samplerCube cubeTexture;
33 |
34 | uniform vec3 cameraPosition;
35 |
36 | in vec3 fragNormal;
37 | in vec3 fragWorldPos;
38 | in vec2 fragUV;
39 | in mat3 TBN;
40 |
41 | @import ./light;
42 |
43 | out vec4 outColor;
44 |
45 | void main() {
46 | vec3 normal = texture(normalTex, fragUV).rgb;
47 | normal = normalize(normal * 2.0 - 1.0);
48 | normal = normalize(TBN * normal);
49 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
50 |
51 | vec3 diffuseColor = texture(diffuseTex, fragUV).rgb;
52 | float specMask = texture(specTex, fragUV).x;
53 | vec3 envReflection = texture(cubeTexture, reflect(-viewDir, normal)).xyz;
54 |
55 | vec3 finalColor = vec3(0.0, 0.0, 0.0);
56 |
57 | for (int i = 0; i < NUM_DIR_LIGHTS; i++) {
58 | DirectionalLight light = directionalLights[i];
59 | vec3 sceneLight = mix(light.color, envReflection + light.color * 0.5, 0.5);
60 |
61 | float diffAmt = diffuse(light.direction, normal);
62 | float specAmt = specular(light.direction, viewDir, normal, 4.0) * specMask;
63 |
64 | vec3 envLighting = envReflection * specMask * diffAmt;
65 |
66 | vec3 specColor = specMask * sceneLight * specAmt;
67 |
68 | finalColor += diffuseColor * diffAmt * light.color;
69 | finalColor += specColor * sceneLight;
70 | }
71 |
72 | for (int i = 0; i < NUM_POINTS_LIGHT; i++) {
73 | PointLight light = pointLights[i];
74 | vec3 sceneLight = mix(light.color, envReflection + light.color * 0.5, 0.5);
75 |
76 | vec3 toLight = light.position - fragWorldPos;
77 | vec3 lightDir = normalize(toLight);
78 | float distToLight = length(toLight);
79 | float falloff = 1.0 - distToLight / light.radius;
80 |
81 | float diffAmt = diffuse(lightDir, normal) * falloff;
82 | float specAmt = specular(lightDir, viewDir, normal, 4.0) * specMask * falloff;
83 |
84 | vec3 envLighting = envReflection * specMask * diffAmt;
85 | vec3 specColor = specMask * sceneLight * specAmt;
86 |
87 | finalColor += diffAmt * sceneLight * diffuseColor;
88 | finalColor += specColor;
89 | }
90 |
91 | for (int i = 0; i < NUM_SPOT_LIGHTS; i++) {
92 | SpotLight light = spotLights[i];
93 | vec3 sceneLight = mix(light.color, envReflection + light.color * 0.5, 0.5);
94 |
95 | vec3 toLight = light.position - fragWorldPos;
96 | vec3 lightDir = normalize(toLight);
97 | float angle = dot(light.direction, -lightDir);
98 |
99 | float falloff = step(light.cutoff, angle);
100 |
101 | float diffAmt = diffuse(lightDir, normal) * falloff;
102 | float specAmt = specular(lightDir, viewDir, normal, 4.0) * specMask * falloff;
103 |
104 | vec3 envLighting = envReflection * specMask * diffAmt;
105 | vec3 specColor = specMask * sceneLight * specAmt;
106 |
107 | finalColor += diffAmt * sceneLight * diffuseColor;
108 | finalColor += specColor;
109 | }
110 |
111 | outColor = vec4(finalColor, 1.0);
112 | }
--------------------------------------------------------------------------------
/src/ch12/shaders/pointLight.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | uniform vec3 lightCol;
6 |
7 | uniform float lightRadius;
8 | uniform vec3 lightPos;
9 |
10 | uniform sampler2D normalTex;
11 | uniform sampler2D diffuseTex;
12 | uniform sampler2D specTex;
13 | uniform samplerCube cubeTexture;
14 |
15 | uniform vec3 cameraPosition;
16 |
17 | in vec3 fragWorldPos;
18 | in vec2 fragUV;
19 | in mat3 TBN;
20 |
21 | out vec4 outColor;
22 |
23 | @import ./light;
24 |
25 | void main() {
26 | vec3 normal = texture(normalTex, fragUV).rgb;
27 | normal = normalize(normal * 2.0 - 1.0);
28 | normal = normalize(TBN * normal);
29 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
30 |
31 | vec3 envSample = texture(cubeTexture, reflect(-viewDir, normal)).xyz;
32 | vec3 sceneLight = mix(lightCol, envSample + lightCol * 0.5, 0.5);
33 |
34 | vec3 toLight = lightPos - fragWorldPos;
35 | vec3 lightDir = normalize(toLight);
36 | float distToLight = length(toLight);
37 | float falloff = max(0.0, 1.0 - distToLight / lightRadius);
38 | float specMask = texture(specTex, fragUV).x;
39 |
40 | float diffAmt = diffuse(lightDir, normal) * falloff;
41 | float specAmt = specular(lightDir, viewDir, normal, 4.0) * specMask * falloff;
42 |
43 | vec3 diffCol = texture(diffuseTex, fragUV).rgb * sceneLight * diffAmt;
44 |
45 |
46 | vec3 specCol = specMask * sceneLight * specAmt;
47 |
48 |
49 | outColor = vec4(diffCol + specCol, 1.0);
50 | }
--------------------------------------------------------------------------------
/src/ch12/shaders/spotLight.frag.glsl:
--------------------------------------------------------------------------------
1 | #version 300 es
2 | precision highp int;
3 | precision highp float;
4 |
5 | uniform vec3 lightCol;
6 |
7 | uniform float lightCutoff;
8 | uniform vec3 lightPos;
9 |
10 | uniform sampler2D normalTex;
11 | uniform sampler2D diffuseTex;
12 | uniform sampler2D specTex;
13 | uniform samplerCube cubeTexture;
14 |
15 | uniform vec3 cameraPosition;
16 | uniform vec3 lightConeDir;
17 |
18 | in vec3 fragWorldPos;
19 | in vec2 fragUV;
20 | in mat3 TBN;
21 |
22 | out vec4 outColor;
23 |
24 | @import ./light;
25 |
26 | void main() {
27 | vec3 normal = texture(normalTex, fragUV).rgb;
28 | normal = normalize(normal * 2.0 - 1.0);
29 | normal = normalize(TBN * normal);
30 | vec3 viewDir = normalize(cameraPosition - fragWorldPos);
31 |
32 | vec3 envSample = texture(cubeTexture, reflect(-viewDir, normal)).xyz;
33 | vec3 sceneLight = mix(lightCol, envSample + lightCol * 0.5, 0.5);
34 |
35 | vec3 toLight = lightPos - fragWorldPos;
36 | vec3 lightDir = normalize(toLight);
37 | float angle = dot(lightConeDir, -lightDir);
38 |
39 | float falloff = step(lightCutoff, angle);
40 |
41 | float diffAmt = diffuse(lightDir, normal) * falloff;
42 | float specAmt = specular(lightDir, viewDir, normal, 4.0) * specMask * falloff;
43 |
44 | vec3 diffCol = texture(diffuseTex, fragUV).rgb * sceneLight * diffAmt;
45 |
46 | float specMask = texture(specTex, fragUV).x;
47 | vec3 specCol = specMask * sceneLight * specAmt;
48 |
49 | vec3 envLighting = envSample * specMask * diffAmt;
50 | specCol = mix(envLighting, specCol, min(1.0, specAmt));
51 |
52 | outColor = vec4(diffCol + specCol, 1.0);
53 | }
--------------------------------------------------------------------------------
/src/externs/Ogl.hx:
--------------------------------------------------------------------------------
1 | package externs;
2 |
3 | import haxe.extern.EitherType;
4 | import js.html.Image;
5 | import js.html.webgl.PowerPreference;
6 | import js.lib.Float32Array;
7 | import js.lib.Uint32Array;
8 | import js.html.webgl.RenderingContext;
9 |
10 |
11 | typedef RendererOptions = {
12 | var ?dpr: Float;
13 | var ?antialias: Bool;
14 | var ?powerPreference: PowerPreference;
15 | };
16 |
17 | @:jsRequire("ogl", "GL")
18 | class GL extends RenderingContext {
19 | var renderer: Renderer;
20 | }
21 |
22 | typedef RenderProps = {
23 | var scene: Transform;
24 | var camera: Camera;
25 | }
26 |
27 | @:jsRequire("ogl", "Renderer")
28 | extern class Renderer {
29 | public function new(options: RendererOptions): Void;
30 | public var gl: GL;
31 | public function setSize(width: Float, height: Float): Void;
32 | public function render(props: RenderProps): Void;
33 |
34 | }
35 | @:jsRequire("ogl", "Vec3")
36 | extern class Vec3 {
37 | public function new(?x: Float, ?y: Float, ?z: Float): Void;
38 | var x: Float;
39 | var y: Float;
40 | var z: Float;
41 | public function set(x: Float, y: Float, z: Float): Void;
42 | public function multiply(v: Float): Vec3;
43 | public function negate(?v: Vec3): Vec3;
44 | public function normalize(): Vec3;
45 | public function clone(): Vec3;
46 | public function copy(v: Vec3): Vec3;
47 | public function sub(v: Vec3, ?v2: Vec3): Vec3;
48 | }
49 | @:jsRequire("ogl", "Vec2")
50 | extern class Vec2 {
51 | public function new(?x: Float, ?y: Float): Void;
52 | var x: Float;
53 | var y: Float;
54 | public function set(x: Float, y: Float): Void;
55 | public function multiply(v: Float): Vec2;
56 | public function normalize(): Vec2;
57 | public function clone(): Vec2;
58 | public function sub(v: Vec2, ?v2: Vec2): Vec2;
59 | }
60 | @:jsRequire("ogl", "Eulor")
61 | extern class Euler {
62 | public function new(?x: Float, ?y: Float, ?z: Float): Void;
63 | var x: Float;
64 | var y: Float;
65 | var z: Float;
66 | public function set(x: Float, y: Float, z: Float): Void;
67 | }
68 | @:jsRequire("ogl", "Transform")
69 | extern class Transform {
70 | var position: Vec3;
71 | var rotation: Euler;
72 | public function new(): Void;
73 | public function lookAt(target: Vec3, ?inverse: Bool): Void;
74 | public function setParent(node: Null): Void;
75 | }
76 |
77 | typedef CreateCameraProps = {
78 | var ?fov: Int;
79 | }
80 | typedef CameraPerspectiveProps = {
81 | var aspect: Float;
82 | }
83 | @:jsRequire("ogl", "Camera")
84 | extern class Camera extends Transform {
85 | public function new(gl: GL, options: CreateCameraProps): Void;
86 | public function perspective(props: CameraPerspectiveProps): Void;
87 | }
88 |
89 | typedef CreateProgramProps = {
90 | var vertex: String;
91 | var fragment: String;
92 | var ?uniforms: Dynamic;
93 | var ?cullFace: Null;
94 | var ?depthTest: Bool;
95 | var ?depthFunc: Int;
96 | var ?frontFace: Int;
97 | }
98 | typedef Uniform = {
99 | var value: T;
100 | }
101 | @:jsRequire("ogl", "Program")
102 | extern class Program {
103 | public var uniforms: Dynamic;
104 | public function new(gl: GL, options: CreateProgramProps): Void;
105 | }
106 |
107 | typedef TextureProps = {
108 | var ?wrapS: Int;
109 | var ?wrapT: Int;
110 | var ?flipY: Bool;
111 | var ?target: Int;
112 | };
113 | @:jsRequire("ogl", "Texture")
114 | extern class Texture {
115 | public var image: EitherType>;
116 | public function new(gl: GL, ?options: TextureProps): Void;
117 | }
118 |
119 | typedef GeometryData = {
120 | var size: Int;
121 | var data: T;
122 | };
123 |
124 | typedef CreateGeometryProps = {
125 | var position: GeometryData;
126 | var ?uv: GeometryData;
127 | var ?normal: GeometryData;
128 | var ?index: GeometryData;
129 | var ?tangent: GeometryData;
130 | }
131 | @:jsRequire("ogl", "Geometry")
132 | extern class Geometry {
133 | public function new(gl: GL, options: CreateGeometryProps): Void;
134 | public function setDrawRange(start: Int, count: Int): Void;
135 | }
136 |
137 | typedef CreateMeshProps = {
138 | var program: Program;
139 | var geometry: Geometry;
140 | };
141 | @:jsRequire("ogl", "Mesh")
142 | extern class Mesh extends Transform {
143 | var scale: Vec3;
144 | var program: Program;
145 | public function new(gl: GL, options: CreateMeshProps): Void;
146 | }
--------------------------------------------------------------------------------
/src/externs/Ply.hx:
--------------------------------------------------------------------------------
1 | package externs;
2 |
3 | import js.lib.Float32Array;
4 | import js.lib.Uint32Array;
5 | import js.lib.Promise;
6 |
7 | @:jsRequire("@loaders.gl/ply", "PLYLoader")
8 | extern class PLYLoader {
9 |
10 | }
11 |
12 | interface Attribute {
13 | var size: Int;
14 | var value: Float32Array;
15 | }
16 |
17 | interface Indicies {
18 | var size: Int;
19 | var value: Uint32Array;
20 | }
21 |
22 | interface Attributes {
23 | var NORMAL: Attribute;
24 | var POSITION: Attribute;
25 | var TEXCOORD_0: Attribute;
26 | }
27 |
28 | interface PlyModel {
29 | var attributes: Attributes;
30 | var indices: Indicies;
31 | }
32 |
33 | @:jsRequire("@loaders.gl/core")
34 | extern class Loader {
35 | public static function load(urls: String, loader: Dynamic, options: Dynamic): Promise;
36 | }
--------------------------------------------------------------------------------
/src/types/Types.hx:
--------------------------------------------------------------------------------
1 | package types;
2 |
3 | import VectorMath.Mat4;
4 | import VectorMath.Vec2;
5 | import VectorMath.Vec4;
6 | import VectorMath.Vec3;
7 | import js.html.webgl.Program;
8 | import js.lib.Float32Array;
9 |
10 | interface BaseApp {
11 | // public function update():Void;
12 | public function draw(delta:Float):Void;
13 | public function setBlendingMode(source: Int, destination: Int): Void;
14 | public function enableDepthTest(): Void;
15 | public function disableDepthTest(): Void;
16 | }
17 |
18 | interface Mesh {
19 | public function build():Void;
20 | public function draw():Void;
21 | public function addVertex(vertex: Vec3):Void;
22 | public function getVertex(index: Int): Vec3;
23 | public function setVertex(index: Int, v: Vec3): Void;
24 | public function addColor(color: Vec4): Void;
25 | public function addIndicies(indicies: Array): Void;
26 | public function addTexCoord(c: Vec2): Void;
27 | }
28 |
29 | interface IShader {
30 | public var program:Program;
31 | public function load(vert:String, frag:String):Void;
32 | public function begin():Void;
33 | public function end():Void;
34 | public function setUniform4f(name: String, v: Vec4): Void;
35 | public function setUniform3f(name: String, v: Vec3): Void;
36 | public function setUniform2f(name: String, v: Vec2): Void;
37 | public function setUniform1f(name: String, f: Float): Void;
38 | public function setUniformMatrix4f(name: String, m: Mat4): Void;
39 | public function setUniformTexture(name: String, src: String, slot: Int, ?flipY: Int): Void;
40 | }
41 |
42 | interface Camera {
43 | public var position: Vec3;
44 | public var rotation: Float;
45 | }
46 |
--------------------------------------------------------------------------------
/src/utils/BaseOfApp.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import VectorMath.log;
4 | import js.html.KeyboardEvent;
5 | import js.Browser;
6 | import js.html.webgl.RenderingContext;
7 | import types.Types.BaseApp;
8 | import js.html.webgl.PowerPreference;
9 |
10 | class BaseOfApp implements BaseApp {
11 | private var ctx:RenderingContext;
12 | private var blendSource = RenderingContext.SRC_ALPHA;
13 | private var blendDestination = RenderingContext.ONE_MINUS_SRC_ALPHA;
14 | private var previousFrameTime: Float = -1;
15 | public function new() {
16 | setup();
17 | }
18 |
19 | private function setup():Void {
20 | final canvas = Browser.document.createCanvasElement();
21 | canvas.width = 1024;
22 | canvas.height = 768;
23 | canvas.id = "canvas";
24 | ctx = canvas.getContextWebGL2({
25 | powerPreference: PowerPreference.HIGH_PERFORMANCE,
26 | premultipliedAlpha: true,
27 | antialias: true,
28 | alpha: false
29 | });
30 | ctx.viewport(0, 0, canvas.width, canvas.height);
31 | Browser.document.body.appendChild(canvas);
32 | Browser.window.requestAnimationFrame(onFrame);
33 | }
34 | public function setBlendingMode(source: Int, destination: Int): Void {
35 | blendSource = source;
36 | blendDestination = destination;
37 | ctx.blendFunc(blendSource, blendDestination);
38 | }
39 | public function onFrame(time: Float) {
40 | var delta = 0.0;
41 | if (previousFrameTime == -1) {
42 | delta = 16;
43 | } else {
44 | delta = time - previousFrameTime;
45 | }
46 | previousFrameTime = time;
47 | draw(delta);
48 | Browser.window.requestAnimationFrame(onFrame);
49 | }
50 | public function draw(delta:Float) {
51 | ctx.viewport(0, 0, ctx.canvas.width, ctx.canvas.height);
52 | ctx.enable(RenderingContext.BLEND);
53 | ctx.enable(RenderingContext.DEPTH_TEST);
54 | ctx.blendFunc(blendSource, blendDestination);
55 | ctx.clearColor(0.2, 0.2, 0.2, 1.0);
56 | ctx.clear(RenderingContext.COLOR_BUFFER_BIT | RenderingContext.DEPTH_BUFFER_BIT);
57 |
58 | }
59 | public function enableDepthTest(): Void {
60 | ctx.enable(RenderingContext.DEPTH_TEST);
61 | }
62 | public function disableDepthTest(): Void {
63 | ctx.disable(RenderingContext.DEPTH_TEST);
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/utils/BuildMatrix.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import utils.Transformation.scale;
4 | import utils.Transformation.rotate;
5 | import utils.Transformation.translate;
6 | import VectorMath.Mat4;
7 | import VectorMath.Vec3;
8 |
9 | function buildMatrix(trans: Vec3, rot: Float, scaling: Vec3): Mat4 {
10 | return translate(trans) * rotate(rot, new Vec3(0, 0, 1)) * scale(scaling);
11 | }
--------------------------------------------------------------------------------
/src/utils/CalculateTangents.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import externs.Ogl.Vec2;
4 | import externs.Ogl.Vec3;
5 | import js.lib.Float32Array;
6 | import externs.Ply.PlyModel;
7 |
8 | function calculateTangents(model:PlyModel):Float32Array {
9 | final tangents:Array = [];
10 | final indexCount:Int = Std.int(model.indices.value.length / model.indices.size);
11 | final uvs = model.attributes.TEXCOORD_0.value;
12 | final vertices = model.attributes.POSITION.value;
13 | final indices = model.indices.value;
14 | for (i in 0...indexCount - 2) {
15 | if (i % 3 == 0) {
16 | final v0:Vec3 = new Vec3(vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]]);
17 | final v1:Vec3 = new Vec3(vertices[indices[i + 3]], vertices[indices[i + 4]], vertices[indices[i + 5]]);
18 | final v2:Vec3 = new Vec3(vertices[indices[i + 6]], vertices[indices[i + 7]], vertices[indices[i + 8]]);
19 |
20 | final uv0:Vec2 = new Vec2(uvs[indices[i]], uvs[indices[i + 1]]);
21 | final uv1:Vec2 = new Vec2(uvs[indices[i + 2]], uvs[indices[i + 3]]);
22 | final uv2:Vec2 = new Vec2(uvs[indices[i + 4]], uvs[indices[i + 5]]);
23 |
24 | final edge1 = v1.clone().sub(v0);
25 | final edge2 = v2.clone().sub(v0);
26 | final dUV1 = uv1.clone().sub(uv0);
27 | final dUV2 = uv2.clone().sub(uv0);
28 |
29 | final f = 1.0 / (dUV1.x * dUV2.y - dUV2.x * dUV1.y);
30 |
31 | final tan:Vec3 = new Vec3();
32 | tan.x = f * (dUV2.y * edge1.x - dUV1.y * edge2.x);
33 | tan.y = f * (dUV2.y * edge1.y - dUV1.y * edge2.y);
34 | tan.z = f * (dUV2.y * edge1.z - dUV1.y * edge2.z);
35 | tan.normalize();
36 |
37 | tangents[indices[i]] = tan.clone();
38 | tangents[indices[i + 1]] = tan.clone();
39 | tangents[indices[i + 2]] = tan.clone();
40 | }
41 | }
42 | final result = new Float32Array(tangents.length * 3);
43 | for (i in 0...tangents.length) {
44 | final t = tangents[i];
45 | result[i] = t.x;
46 | result[i + 1] = t.y;
47 | result[i + 2] = t.z;
48 | }
49 | return result;
50 | }
--------------------------------------------------------------------------------
/src/utils/Camera.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import VectorMath.Vec3;
4 | import types.Types.Camera as ICamera;
5 |
6 | class Camera implements ICamera {
7 | public var position: Vec3;
8 | public var rotation: Float;
9 | public function new(position: Vec3, rotation: Float) {
10 | this.position = position;
11 | this.rotation = rotation;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/utils/CreatePLYGeometry.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import utils.CalculateTangents.calculateTangents;
4 | import externs.Ogl.CreateGeometryProps;
5 | import externs.Ogl.GL;
6 | import externs.Ply.PlyModel;
7 | import externs.Ogl.Geometry;
8 |
9 | function createPLYGeometry(gl: GL, model: PlyModel): Geometry {
10 | final props: CreateGeometryProps = {
11 | position: { size: model.attributes.POSITION.size, data: model.attributes.POSITION.value },
12 | };
13 | if (model.attributes.NORMAL != null) {
14 | props.normal = { size: model.attributes.NORMAL.size, data: model.attributes.NORMAL.value };
15 | if (model.attributes.TEXCOORD_0 != null && model.indices != null) {
16 | props.tangent = { size: model.attributes.NORMAL.size, data: calculateTangents(model) };
17 | }
18 | }
19 | if (model.attributes.TEXCOORD_0 != null) {
20 | props.uv = { size: model.attributes.TEXCOORD_0.size, data: model.attributes.TEXCOORD_0.value };
21 | }
22 | if (model.indices != null) {
23 | props.index = { size: model.indices.size, data: model.indices.value };
24 | }
25 | return new Geometry(gl, props);
26 | }
--------------------------------------------------------------------------------
/src/utils/Degree.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | function toRadians(degree: Float): Float {
4 | return degree * Math.PI / 180;
5 | }
--------------------------------------------------------------------------------
/src/utils/DirectionalLight.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import externs.Ogl.Vec3;
4 |
5 | class DirectionalLight {
6 | public var direction: Vec3;
7 | public var color: Vec3;
8 | public var intensity: Float;
9 | public function new(?direction: Vec3, ?color: Vec3, ?intensity: Float) {
10 | this.direction = (direction != null) ? direction : new Vec3();
11 | this.color = (color != null) ? color : new Vec3(1, 1, 1);
12 | this.intensity = (intensity != null) ? intensity : 1;
13 | }
14 | }
15 |
16 | function getLightDirection(light: DirectionalLight): Vec3 {
17 | return light.direction.clone().negate().normalize();
18 | }
19 | function getLightColor(light: DirectionalLight): Vec3 {
20 | return light.color.clone().multiply(light.intensity);
21 | }
--------------------------------------------------------------------------------
/src/utils/LoadImage.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import js.html.Image;
4 | import js.lib.Promise;
5 |
6 | function loadImage(src: String): Promise {
7 | return new Promise((success, reject) -> {
8 | final img = new Image();
9 | img.onload = () -> success(img);
10 | img.src = src;
11 | });
12 | }
--------------------------------------------------------------------------------
/src/utils/LoadTexture.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import utils.LoadImage.loadImage;
4 | import externs.Ogl.GL;
5 | import externs.Ogl.TextureProps;
6 | import externs.Ogl.Texture;
7 |
8 | function loadTexture(path:String, gl: GL, ?props: TextureProps):Texture {
9 | final texture = new Texture(gl, props);
10 | loadImage(path).then(img -> {
11 | texture.image = img;
12 | });
13 | return texture;
14 | }
--------------------------------------------------------------------------------
/src/utils/Material.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import js.lib.Float32Array;
4 | import VectorMath.Mat4;
5 | import VectorMath.Vec3;
6 | import VectorMath.Vec2;
7 | import js.html.webgl.UniformLocation;
8 | import VectorMath.Vec4;
9 | import types.Types.IShader;
10 | import js.html.webgl.Program;
11 | import js.html.webgl.RenderingContext;
12 | import js.html.webgl.Shader;
13 |
14 | class Material implements IShader {
15 | private var ctx:RenderingContext;
16 | private var textures: Array = [];
17 |
18 | public var program:Program;
19 |
20 | private var slot = 0;
21 |
22 | public function new(ctx:RenderingContext) {
23 | this.ctx = ctx;
24 | }
25 |
26 | public function load(vert:String, frag:String) {
27 | program = createProgram(ctx, vert, frag);
28 | ctx.linkProgram(program);
29 | }
30 |
31 | public function begin() {
32 | ctx.useProgram(program);
33 | if (textures.length > 0) {
34 | ctx.texParameteri(RenderingContext.TEXTURE_2D, RenderingContext.TEXTURE_WRAP_S, RenderingContext.CLAMP_TO_EDGE);
35 | ctx.texParameteri(RenderingContext.TEXTURE_2D, RenderingContext.TEXTURE_WRAP_T, RenderingContext.CLAMP_TO_EDGE);
36 | ctx.uniform1i(textures[0], slot);
37 | }
38 | }
39 |
40 | public function end() {}
41 |
42 | public function setUniform4f(name: String, v: Vec4): Void {
43 | final location = ctx.getUniformLocation(program, name);
44 | ctx.uniform4f(location, v.x, v.y, v.z, v.w);
45 | }
46 | public function setUniform3f(name: String, v: Vec3): Void {
47 | final location = ctx.getUniformLocation(program, name);
48 | ctx.uniform3f(location, v.x, v.y, v.z);
49 | }
50 | public function setUniform2f(name: String, v: Vec2): Void {
51 | final location = ctx.getUniformLocation(program, name);
52 | ctx.uniform2f(location, v.x, v.y);
53 | }
54 | public function setUniform1f(name: String, f: Float): Void {
55 | final location = ctx.getUniformLocation(program, name);
56 | if (location != null) {
57 | ctx.uniform1f(location, f);
58 | }
59 | }
60 | public function setUniformTexture(name: String, src: String, slot: Int, ?flipY = 1): Void {
61 | this.slot = slot;
62 | new Texture(src, ctx, slot, flipY);
63 | final textureLocation = ctx.getUniformLocation(program, name);
64 | if (textureLocation != null) {
65 | textures.push(textureLocation);
66 | }
67 | }
68 | public function setUniformMatrix4f(name: String, m: Mat4): Void {
69 | final convertedM = new Float32Array(16);
70 | convertedM[0] = m[0].x;
71 | convertedM[1] = m[0].y;
72 | convertedM[2] = m[0].z;
73 | convertedM[3] = m[0].w;
74 |
75 | convertedM[4] = m[1].x;
76 | convertedM[5] = m[1].y;
77 | convertedM[6] = m[1].z;
78 | convertedM[7] = m[1].w;
79 |
80 | convertedM[8] = m[2].x;
81 | convertedM[9] = m[2].y;
82 | convertedM[10] = m[2].z;
83 | convertedM[11] = m[2].w;
84 |
85 | convertedM[12] = m[3].x;
86 | convertedM[13] = m[3].y;
87 | convertedM[14] = m[3].z;
88 | convertedM[15] = m[3].w;
89 | final location = ctx.getUniformLocation(program, name);
90 | if (location != null) {
91 | ctx.uniformMatrix4fv(location, false, convertedM);
92 | }
93 | }
94 | }
95 |
96 | private function createProgram(ctx:RenderingContext, vert:String, frag:String):Program {
97 | final program = ctx.createProgram();
98 | ctx.attachShader(program, createShader(ctx, RenderingContext.VERTEX_SHADER, vert));
99 | ctx.attachShader(program, createShader(ctx, RenderingContext.FRAGMENT_SHADER, frag));
100 | return program;
101 | }
102 |
103 | private function createShader(ctx:RenderingContext, type:Int, source:String):Shader {
104 | final shader = ctx.createShader(type);
105 | ctx.shaderSource(shader, source);
106 | ctx.compileShader(shader);
107 | return shader;
108 | }
109 |
--------------------------------------------------------------------------------
/src/utils/Matrix.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import VectorMath.Mat4;
4 |
5 | function inverse(m:Mat4):Mat4 {
6 | final out = new Mat4(
7 | 1,0,0,0,
8 | 0,1,0,0,
9 | 0,0,1,0,
10 | 0,0,0,1
11 | );
12 | final det = determinant(m, 4);
13 | for (row in 0...4) {
14 | for (column in 0...4) {
15 | out[column][row] = cofactor(m, row, column, 4) / det;
16 | }
17 | }
18 | return out;
19 | }
20 |
21 | function determinant(m:Mat4, length: Int):Float {
22 | var det:Float = 0;
23 | if (length == 2) {
24 | det = m[0][0] * m[1][1] - m[0][1] * m[1][0];
25 | } else {
26 | for (column in 0...length) {
27 | det += m[0][column] * cofactor(m, 0, column, length);
28 | }
29 | }
30 | return det;
31 | }
32 |
33 | function cofactor(m:Mat4, row:UInt, column:UInt, length: Int):Float {
34 | final minorValue = minor(m, row, column, length);
35 |
36 | return (row + column) % 2 == 0 ? minorValue : minorValue * -1;
37 | }
38 |
39 | function minor(m:Mat4, row:UInt, column:UInt, length: Int):Float {
40 | return determinant(submatrix(m, row, column, length - 1), length - 1);
41 | }
42 |
43 | function submatrix(m:Mat4, rowToRemove:UInt, columnToRemove:UInt, length: Int):Mat4 {
44 | final out = new Mat4(
45 | 1,0,0,0,
46 | 0,1,0,0,
47 | 0,0,1,0,
48 | 0,0,0,1
49 | );
50 | var rows: Int;
51 | var columns: Int;
52 | if (length == 4) {
53 | rows = 3;
54 | columns = 3;
55 | } else {
56 | rows = 2;
57 | columns = 2;
58 | }
59 | var currentRow = 0;
60 | var currentColumn = 0;
61 | for (row in 0...rows) {
62 | if (row != rowToRemove) {
63 | currentColumn = 0;
64 | for (column in 0...columns) {
65 | if (column != columnToRemove) {
66 | out[currentRow][currentColumn] = m[row][column];
67 | currentColumn++;
68 | }
69 | }
70 | currentRow++;
71 | }
72 | }
73 | return out;
74 | }
--------------------------------------------------------------------------------
/src/utils/Mesh3D.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import js.html.webgl.Buffer;
4 | import VectorMath.Vec2;
5 | import VectorMath.Vec4;
6 | import VectorMath.Vec3;
7 | import js.html.webgl.Program;
8 | import js.lib.Float32Array;
9 | import js.lib.Uint16Array;
10 | import js.html.webgl.RenderingContext;
11 | import types.Types.Mesh;
12 |
13 | class Mesh3D implements Mesh {
14 | private var ctx:RenderingContext;
15 | private var vertices:Array;
16 | private var indicies:Array;
17 | private var uv:Array;
18 | private var colors:Array;
19 | private var shader:Program;
20 | private var indiciesBuffer: Null;
21 | private var vertexPositionBuffer: Null;
22 | private var vertexColorBuffer: Null;
23 | private var uvBuffer: Null;
24 |
25 | public function new(ctx:RenderingContext, shader:Program) {
26 | this.ctx = ctx;
27 | this.shader = shader;
28 | vertices = [];
29 | colors = [];
30 | indicies = [];
31 | uv = [];
32 | };
33 |
34 | public function addVertex(vertex: Vec3):Void {
35 | vertices.push(vertex.x);
36 | vertices.push(vertex.y);
37 | vertices.push(vertex.z);
38 | }
39 | public function setVertex(index: Int, v:Vec3):Void {
40 | vertices[index] = v.x;
41 | vertices[index + 1] = v.y;
42 | vertices[index + 2] = v.z;
43 | }
44 | public function getVertex(index: Int):Vec3 {
45 | return new Vec3(
46 | vertices[index],
47 | vertices[index + 1],
48 | vertices[index + 2]
49 | );
50 | }
51 | public function addColor(color: Vec4): Void {
52 | colors.push(color.x);
53 | colors.push(color.y);
54 | colors.push(color.z);
55 | colors.push(color.w);
56 | }
57 | public function addIndicies(indicies: Array): Void {
58 | this.indicies = this.indicies.concat(indicies);
59 | }
60 | public function addTexCoord(c: Vec2): Void {
61 | uv.push(c.x);
62 | uv.push(c.y);
63 | }
64 | public function build():Void {
65 | final positionAttriuteLocation = ctx.getAttribLocation(shader, "position");
66 | vertexPositionBuffer = ctx.createBuffer();
67 | ctx.enableVertexAttribArray(positionAttriuteLocation);
68 | ctx.bindBuffer(RenderingContext.ARRAY_BUFFER, vertexPositionBuffer);
69 | ctx.vertexAttribPointer(positionAttriuteLocation, 3, RenderingContext.FLOAT, false, 0, 0);
70 | ctx.bufferData(RenderingContext.ARRAY_BUFFER, new Float32Array(vertices), RenderingContext.STATIC_DRAW);
71 |
72 | final colorAttriuteLocation = ctx.getAttribLocation(shader, "color");
73 | if (colorAttriuteLocation >= 0) {
74 | vertexColorBuffer = ctx.createBuffer();
75 | ctx.enableVertexAttribArray(colorAttriuteLocation);
76 | ctx.bindBuffer(RenderingContext.ARRAY_BUFFER, vertexColorBuffer);
77 | ctx.vertexAttribPointer(colorAttriuteLocation, 4, RenderingContext.FLOAT, false, 0, 0);
78 | ctx.bufferData(RenderingContext.ARRAY_BUFFER, new Float32Array(colors), RenderingContext.STATIC_DRAW);
79 | }
80 | final uvAttriuteLocation = ctx.getAttribLocation(shader, "uv");
81 | if (uvAttriuteLocation >= 0) {
82 | uvBuffer = ctx.createBuffer();
83 | ctx.enableVertexAttribArray(uvAttriuteLocation);
84 | ctx.bindBuffer(RenderingContext.ARRAY_BUFFER, uvBuffer);
85 | ctx.vertexAttribPointer(uvAttriuteLocation, 2, RenderingContext.FLOAT, false, 0, 0);
86 | ctx.bufferData(RenderingContext.ARRAY_BUFFER, new Float32Array(uv), RenderingContext.STATIC_DRAW);
87 | }
88 | if (indicies.length > 0) {
89 | indiciesBuffer = ctx.createBuffer();
90 | ctx.bindBuffer(RenderingContext.ELEMENT_ARRAY_BUFFER, indiciesBuffer);
91 | ctx.bufferData(RenderingContext.ELEMENT_ARRAY_BUFFER, new Uint16Array(indicies), RenderingContext.STATIC_DRAW);
92 | }
93 | }
94 |
95 | public function draw():Void {
96 | if (vertexPositionBuffer != null) {
97 | ctx.enableVertexAttribArray(ctx.getAttribLocation(shader, "position"));
98 | ctx.bindBuffer(RenderingContext.ARRAY_BUFFER, vertexPositionBuffer);
99 | ctx.vertexAttribPointer(ctx.getAttribLocation(shader, "position"), 3, RenderingContext.FLOAT, false, 0, 0);
100 | ctx.bufferData(RenderingContext.ARRAY_BUFFER, new Float32Array(vertices), RenderingContext.STATIC_DRAW);
101 | }
102 | if (vertexColorBuffer != null) {
103 | ctx.bindBuffer(RenderingContext.ARRAY_BUFFER, vertexColorBuffer);
104 | ctx.bufferData(RenderingContext.ARRAY_BUFFER, new Float32Array(colors), RenderingContext.STATIC_DRAW);
105 | }
106 | if (uvBuffer != null) {
107 | ctx.enableVertexAttribArray(ctx.getAttribLocation(shader, "uv"));
108 | ctx.bindBuffer(RenderingContext.ARRAY_BUFFER, uvBuffer);
109 | ctx.vertexAttribPointer(ctx.getAttribLocation(shader, "uv"), 2, RenderingContext.FLOAT, false, 0, 0);
110 | ctx.bufferData(RenderingContext.ARRAY_BUFFER, new Float32Array(uv), RenderingContext.STATIC_DRAW);
111 | }
112 | if (indiciesBuffer != null) {
113 | ctx.bindBuffer(RenderingContext.ELEMENT_ARRAY_BUFFER, indiciesBuffer);
114 | ctx.bufferData(RenderingContext.ELEMENT_ARRAY_BUFFER, new Uint16Array(indicies), RenderingContext.STATIC_DRAW);
115 | ctx.drawElements(RenderingContext.TRIANGLES, indicies.length, RenderingContext.UNSIGNED_SHORT, 0);
116 | } else {
117 | ctx.drawArrays(RenderingContext.TRIANGLES, 0, Std.int(vertices.length / 3));
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/utils/OglBase.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import js.html.webgl.PowerPreference;
4 | import externs.Ogl.Renderer;
5 | import externs.Ogl.Camera;
6 | import externs.Ogl.GL;
7 | import externs.Ogl.Transform;
8 | import externs.Ogl.Vec3;
9 | import js.Browser;
10 |
11 | class OglBase {
12 | private var renderer: Renderer;
13 | private var gl: GL;
14 | private var camera: Camera;
15 | private var scene: Transform;
16 | public function new() {
17 | createEngine();
18 | setup();
19 | }
20 | private function createEngine(): Void {
21 | renderer = new Renderer({
22 | dpr: 2,
23 | antialias: true,
24 | powerPreference: PowerPreference.HIGH_PERFORMANCE
25 | });
26 | gl = renderer.gl;
27 | Browser.document.body.appendChild(gl.canvas);
28 |
29 | gl.clearColor(1, 1, 1, 1);
30 |
31 | camera = new Camera(gl, { fov: 35 });
32 | camera.position.set(0, 0, 15);
33 | camera.lookAt(new Vec3(0, 0, 0));
34 |
35 | Browser.window.addEventListener("resize", resize, false);
36 |
37 | scene = new Transform();
38 |
39 | resize();
40 | }
41 | private function resize(): Void {
42 | renderer.setSize(Browser.window.innerWidth, Browser.window.innerHeight);
43 | camera.perspective({ aspect: gl.canvas.width / gl.canvas.height });
44 | }
45 | private function onFrame(dt: Float): Void {
46 | renderer.render({ scene: scene , camera: camera });
47 | Browser.window.requestAnimationFrame(onFrame);
48 | }
49 | private function setup():Void {
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/utils/Texture.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import js.lib.Uint8Array;
4 | import js.Browser;
5 | import js.html.webgl.RenderingContext;
6 |
7 | class Texture {
8 | public function new(src: String, ctx: RenderingContext, index: Int, flipY: Int) {
9 | final texture = ctx.createTexture();
10 | ctx.activeTexture(RenderingContext.TEXTURE0 + index);
11 | ctx.bindTexture(RenderingContext.TEXTURE_2D, texture);
12 | ctx.pixelStorei(RenderingContext.UNPACK_FLIP_Y_WEBGL, flipY);
13 | ctx.texImage2D(RenderingContext.TEXTURE_2D, 0, RenderingContext.RGBA, 1, 1, 0, RenderingContext.RGBA, RenderingContext.UNSIGNED_BYTE,
14 | new Uint8Array([0, 0, 0, 255]));
15 | final img = Browser.document.createImageElement();
16 | img.src = src;
17 | img.addEventListener("load", () -> {
18 | ctx.activeTexture(RenderingContext.TEXTURE0 + index);
19 | ctx.bindTexture(RenderingContext.TEXTURE_2D, texture);
20 | ctx.pixelStorei(RenderingContext.UNPACK_FLIP_Y_WEBGL, flipY);
21 | ctx.texImage2D(RenderingContext.TEXTURE_2D, 0, RenderingContext.RGBA, RenderingContext.RGBA, RenderingContext.UNSIGNED_BYTE, img);
22 | ctx.generateMipmap(RenderingContext.TEXTURE_2D);
23 | });
24 | }
25 | }
--------------------------------------------------------------------------------
/src/utils/Transformation.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import VectorMath.Vec3;
4 | import VectorMath.Mat4;
5 |
6 | function translate(v: Vec3): Mat4 {
7 | return new Mat4(
8 | 1, 0, 0, v.x,
9 | 0, 1, 0, v.y,
10 | 0, 0, 1, v.z,
11 | 0, 0, 0, 1
12 | );
13 | }
14 |
15 | function scale(v: Vec3): Mat4 {
16 | return new Mat4(
17 | v.x, 0, 0, 0,
18 | 0, v.y, 0, 0,
19 | 0, 0, v.z, 0,
20 | 0, 0, 0, 1
21 | );
22 | }
23 |
24 | function rotate(radians: Float, axis: Vec3): Mat4 {
25 | var m = new Mat4(
26 | 1, 0, 0, 0,
27 | 0, 1, 0, 0,
28 | 0, 0, 1, 0,
29 | 0, 0, 0, 1
30 | );
31 | if (axis.x > 0) {
32 | m = m * rotateX(radians);
33 | }
34 | if (axis.y > 0) {
35 | m = m * rotateY(radians);
36 | }
37 | if (axis.z > 0) {
38 | m = m * rotateZ(radians);
39 | }
40 | return m;
41 | }
42 |
43 | private function rotateX(radians: Float): Mat4 {
44 | return new Mat4(
45 | 1, 0, 0, 0,
46 | 0, Math.cos(radians), -Math.sin(radians), 0,
47 | 0, Math.sin(radians), Math.cos(radians), 0,
48 | 0, 0, 0, 1
49 | );
50 | }
51 | private function rotateY(radians: Float): Mat4 {
52 | return new Mat4(
53 | Math.cos(radians), 0, Math.sin(radians), 0,
54 | 0, 1, 0, 0,
55 | -Math.sin(radians), 0, Math.cos(radians), 0,
56 | 0, 0, 0, 1
57 | );
58 | }
59 | private function rotateZ(radians: Float): Mat4 {
60 | return new Mat4(
61 | Math.cos(radians), -Math.sin(radians), 0, 0,
62 | Math.sin(radians), Math.cos(radians), 0, 0,
63 | 0, 0, 1, 0,
64 | 0, 0, 0, 1
65 | );
66 | }
--------------------------------------------------------------------------------
/src/utils/ViewMatrix.hx:
--------------------------------------------------------------------------------
1 | package utils;
2 |
3 | import VectorMath.Vec3;
4 | import utils.BuildMatrix.buildMatrix;
5 | import utils.Matrix.inverse;
6 | import types.Types.Camera;
7 | import VectorMath.Mat4;
8 |
9 | function buildViewMatrix(camera: Camera): Mat4 {
10 | return inverse(buildMatrix(camera.position, camera.rotation, new Vec3(1, 1, 1)));
11 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const HtmlWebpackPlugin = require('html-webpack-plugin');
3 |
4 | module.exports = {
5 | mode: 'development',
6 | devtool: 'source-map',
7 | entry: './build.hxml',
8 | output: {
9 | filename: 'main.js',
10 | path: path.resolve(__dirname, 'bin'),
11 | },
12 | module: {
13 | rules: [
14 | {
15 | test: /\.hxml$/,
16 | loader: 'haxe-loader',
17 | options: {
18 | debug: true
19 | }
20 | },
21 | {
22 | test: /\.glsl$/,
23 | loader: 'webpack-glsl-loader'
24 | },
25 | {
26 | test: /\.(png|jpe?g|gif|ply)$/i,
27 | use: [
28 | {
29 | loader: 'file-loader',
30 | options: {
31 | esModule: false,
32 | },
33 | },
34 | ],
35 | },
36 | ]
37 | },
38 | plugins: [
39 | new HtmlWebpackPlugin({
40 | template: './bin/index.html'
41 | })
42 | ],
43 | devServer: {
44 | compress: true,
45 | port: 4444,
46 | overlay: true,
47 | hot: true,
48 | disableHostCheck: true
49 | }
50 | }
--------------------------------------------------------------------------------