Skip to content

Commit

Permalink
🧱 Custom renderable builder
Browse files Browse the repository at this point in the history
  • Loading branch information
benc-uk committed Feb 28, 2024
1 parent 8e47a8e commit 2383697
Show file tree
Hide file tree
Showing 17 changed files with 470 additions and 42 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ jobs:
needs: lint-check

# Only run on main branch
if: github.ref == 'refs/heads/main'
if: github.ref == 'DISABLED FOR NOW refs/heads/main'

steps:
- uses: actions/checkout@v3
with:
persist-credentials: false
fetch-depth: 0

- name: Use Node.js v18
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: x.20
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Use Node.js v18
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: x.18
registry-url: 'https://npm.pkg.github.com'
node-version: x.20
cache: 'npm'
registry-url: 'https://registry.npmjs.org'

- name: Build all bundles
env:
Expand All @@ -41,4 +41,4 @@ jobs:
run: |
npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
178 changes: 166 additions & 12 deletions dist-single/gsots3d.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist-single/gsots3d.js.map

Large diffs are not rendered by default.

Binary file added examples/_textures/tr1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions examples/builder/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<title>GSOTS-3D Custom Builder</title>
<link rel="shortcut icon" href="https://code.benco.io/gsots3d/icon.png" type="image/png" />

<link rel="stylesheet" href="../style.css" />
<script type="module" src="../screen.mjs"></script>
<script type="module" src="./main.mjs"></script>
</head>

<body>
<div>
<canvas width="1280" height="720"></canvas>
</div>
</body>
</html>
28 changes: 28 additions & 0 deletions examples/builder/main.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Context, Material, RenderableBuilder } from '../../dist-single/gsots3d.js'

const ctx = await Context.init()
ctx.start()

// Create a pyramid using RenderableBuilder
const builder = new RenderableBuilder()

// Base on x z plane, anti-clockwise, reversed
builder.addQuad([-1, 0, -1], [1, 0, -1], [1, 0, 1], [-1, 0, 1], [0, 0], [1, 0], [1, 1], [0, 1])

// Four triangles as sides
builder.addTriangle([-1, 0, 1], [1, 0, 1], [0, 2, 0], [0, 0], [1, 0], [0.5, 1])
builder.addTriangle([1, 0, 1], [1, 0, -1], [0, 2, 0], [0, 0], [1, 0], [0.5, 1])
builder.addTriangle([1, 0, -1], [-1, 0, -1], [0, 2, 0], [0, 0], [1, 0], [0.5, 1])
builder.addTriangle([-1, 0, -1], [-1, 0, 1], [0, 2, 0], [0, 0], [1, 0], [0.5, 1])

const m = Material.createBasicTexture('../_textures/brickwall.jpg', true)
const pyramid = ctx.createCustomInstance(builder, m)

ctx.camera.position = [0, 0, 6]
ctx.globalLight.setAsPosition(20, 70, 500)

ctx.update = (delta) => {
pyramid.rotateY(0.8 * delta)
pyramid.rotateX(0.6 * delta)
pyramid.rotateZ(0.4 * delta)
}
3 changes: 2 additions & 1 deletion examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ <h1>🥽 GSOTS-3D &mdash; Examples & Samples</h1>
</p>

<ul>
<li><a href="hello-world/">Hello World</a> - Minimal GOSTS example, a single sphere</li>
<li><a href="demo/">Demo scene</a> - Room with various objects for no reason</li>
<li><a href="demo-2/">Demo scene 2</a> - Showcasing dynamic reflections & normal mapping</li>
<li><a href="physics/">Physics demo</a> - Using cannon-es for physics</li>
Expand All @@ -34,7 +35,7 @@ <h1>🥽 GSOTS-3D &mdash; Examples & Samples</h1>
<li><a href="effects/">Post processing</a> - Showing full screen post processing effects</li>
<li><a href="shadow-test/">Shadow test</a> - Simple test scene for debugging shadows</li>
<li><a href="earth/">Planet Earth</a> - Very simple demo with the earth spinning in space</li>
<li><a href="hello-world/">Hello World</a> - Minimal GOSTS example, a single sphere</li>
<li><a href="builder/">Custom Builder</a> - How to use the builder</li>
</ul>
</main>
</body>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "gsots3d",
"version": "0.0.5-alpha.6",
"version": "0.0.5-alpha.7",
"description": "Getting S**t On The Screen in 3D. A library for doing 3D graphics in the browser.",
"author": "Ben Coleman",
"license": "MIT",
Expand Down
20 changes: 14 additions & 6 deletions shaders/phong/glsl.frag
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ struct Material {
sampler2D specularTex;
sampler2D normalTex;
bool hasNormalTex;
bool unshaded;
};

// Inputs from vertex shader
Expand Down Expand Up @@ -186,12 +187,19 @@ void main() {
N = normalize(TBN * normMap);
}

// Handle the main directional light, only one of these
vec4 outColorPart = shadeDirLight(u_lightDirGlobal, u_mat, N, V);

// Add positional lights
for (int i = 0; i < u_lightsPosCount; i++) {
outColorPart += shadePosLight(u_lightsPos[i], u_mat, N, V);
vec4 outColorPart;
if (u_mat.unshaded) {
// Skip lighting/shading and just use the texture if unshaded
vec3 diffuseTexCol = vec3(texture(u_mat.diffuseTex, texCoord)) * u_mat.diffuse;
outColorPart = vec4(diffuseTexCol, 1.0);
} else {
// Handle the main directional light, only one of these
outColorPart = shadeDirLight(u_lightDirGlobal, u_mat, N, V);

// Add positional lights
for (int i = 0; i < u_lightsPosCount; i++) {
outColorPart += shadePosLight(u_lightsPos[i], u_mat, N, V);
}
}

// Add emissive component
Expand Down
25 changes: 24 additions & 1 deletion src/core/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { Model } from '../renderable/model.ts'
import { HUD } from './hud.ts'
import { Stats } from './stats.ts'
import { PostEffects } from '../engine/post-effects.ts'
import { RenderableBuilder } from '../renderable/builder.ts'

// Import shaders, tsup will inline these as text strings
import fragShaderPhong from '../../shaders/phong/glsl.frag'
Expand Down Expand Up @@ -87,6 +88,9 @@ export class Context {
/** Set the fixed time step for physics stepping, only used when physicsWorld is set */
public physicsTimeStep: number

/** Backface culling */
public disableCulling = false

// ==== Getters =============================================================

/** Get the active camera */
Expand Down Expand Up @@ -336,7 +340,8 @@ export class Context {
// ------------------------------------------------
// RENDER CORE - Draw all standard opaque instances
// ------------------------------------------------
this.gl.enable(this.gl.CULL_FACE)
if (this.disableCulling) this.gl.disable(this.gl.CULL_FACE)
else this.gl.enable(this.gl.CULL_FACE)
this.gl.enable(this.gl.BLEND)
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA)

Expand Down Expand Up @@ -789,4 +794,22 @@ export class Context {
removeEffect() {
this.postEffects = undefined
}

/**
*
*/
createCustomInstance(builder: RenderableBuilder, material: Material) {
const renderable = builder.build(this.gl)

renderable.material = material
const instance = new Instance(renderable)

this.addInstance(instance, material)
Stats.triangles += renderable.triangleCount
Stats.instances++

log.debug(`🗿 Created a custom renderable instance`)

return instance
}
}
37 changes: 27 additions & 10 deletions src/engine/material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ export class Material {
*/
public normalTex?: WebGLTexture

/**
* Don't apply any lighting or shading to this material
* @default false
*/
public unshaded: boolean

/**
* Create a new default material with diffuse white colour, all all default properties
*/
Expand All @@ -81,6 +87,8 @@ export class Material {
this.opacity = 1.0
this.reflectivity = 0.0

this.unshaded = false

// 1 pixel white texture is used for solid colour & flat materials
// A trick to avoid having multiple shaders for textured & non-textured materials
this.diffuseTex = TextureCache.defaultWhite
Expand Down Expand Up @@ -180,8 +188,7 @@ export class Material {

/** Create a simple diffuse red Material */
static get RED() {
const m = Material.createSolidColour(1.0, 0.0, 0.0)
return m
return Material.createSolidColour(1.0, 0.0, 0.0)
}

/** Create a simple diffuse green Material */
Expand All @@ -191,23 +198,32 @@ export class Material {

/** Create a simple diffuse blue Material */
static get BLUE() {
const m = Material.createSolidColour(0.0, 0.0, 1.0)

return m
return Material.createSolidColour(0.0, 0.0, 1.0)
}

/** Create a simple diffuse white Material */
static get WHITE() {
const m = Material.createSolidColour(1.0, 1.0, 1.0)

return m
return Material.createSolidColour(1.0, 1.0, 1.0)
}

/** Create a simple diffuse black Material */
static get BLACK() {
const m = Material.createSolidColour(0.0, 0.0, 0.0)
return Material.createSolidColour(0.0, 0.0, 0.0)
}

return m
/** Create a simple diffuse yellow Material */
static get YELLOW() {
return Material.createSolidColour(1.0, 1.0, 0.0)
}

/** Create a simple diffuse magenta Material */
static get MAGENTA() {
return Material.createSolidColour(1.0, 0.0, 1.0)
}

/** Create a simple diffuse cyan Material */
static get CYAN() {
return Material.createSolidColour(0.0, 1.0, 1.0)
}

/**
Expand Down Expand Up @@ -240,6 +256,7 @@ export class Material {
specularTex: this.specularTex ? this.specularTex : null,
normalTex: this.normalTex ? this.normalTex : null,
hasNormalTex: this.normalTex ? true : false,
unshaded: this.unshaded,
} as UniformSet
}

Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ export * from './renderable/model.ts'
export * from './renderable/instance.ts'
export * from './renderable/primitive.ts'
export * from './renderable/billboard.ts'
export * from './renderable/builder.ts'
1 change: 0 additions & 1 deletion src/renderable/billboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export class Billboard implements Renderable {
protected bufferInfo: twgl.BufferInfo
private programInfo: twgl.ProgramInfo
public material: Material
public tex: WebGLTexture | undefined
public type: BillboardType = BillboardType.CYLINDRICAL

/** Creates a square billboard */
Expand Down
Loading

0 comments on commit 2383697

Please sign in to comment.