diff --git a/_projects/bathroom_shelf.md b/_projects/bathroom_shelf.md
index c050501..067756f 100644
--- a/_projects/bathroom_shelf.md
+++ b/_projects/bathroom_shelf.md
@@ -15,7 +15,7 @@ model: /assets/projects/bathroom_shelf/models/ikea.glb
---
{% include mastodon_post.html post_id = "111822564173512216" %}
-
+
Loading model...
diff --git a/_projects/ceramics.md b/_projects/ceramics.md
index c865fd7..6c6741d 100644
--- a/_projects/ceramics.md
+++ b/_projects/ceramics.md
@@ -17,7 +17,7 @@ model: /assets/projects/ceramics/scan.glb
Loading model...
-->
-
+
Loading model...
\ No newline at end of file
diff --git a/assets/js/outline-model-viewer/CustomOutlinePass.js b/assets/js/outline-model-viewer/CustomOutlinePass.js
index dbfef5a..dfa551a 100644
--- a/assets/js/outline-model-viewer/CustomOutlinePass.js
+++ b/assets/js/outline-model-viewer/CustomOutlinePass.js
@@ -1,9 +1,7 @@
import * as THREE from "three";
import { Pass } from "three/addons/postprocessing/Pass.js";
import { FullScreenQuad } from "three/addons/postprocessing/Pass.js";
-import {
- getSurfaceIdMaterial,
-} from "./FindSurfaces.js";
+import { getSurfaceIdMaterial } from "./FindSurfaces.js";
// Follows the structure of
// https://github.com/mrdoob/three.js/blob/master/examples/jsm/postprocessing/OutlinePass.js
@@ -19,8 +17,7 @@ class CustomOutlinePass extends Pass {
this.fsQuad = new FullScreenQuad(null);
this.fsQuad.material = this.createOutlinePostProcessMaterial();
- // Create a buffer to store the normals of the scene onto
- // or store the "surface IDs"
+ // Create a buffer to surface ids
const surfaceBuffer = new THREE.WebGLRenderTarget(
this.resolution.x,
this.resolution.y
@@ -117,7 +114,7 @@ class CustomOutlinePass extends Pass {
uniform float cameraFar;
uniform vec4 screenSize;
uniform vec3 outlineColor;
- uniform vec2 multiplierParameters;
+ uniform vec3 multiplierParameters;
uniform int debugVisualize;
varying vec2 vUv;
@@ -152,19 +149,36 @@ class CustomOutlinePass extends Pass {
return clamp(num, 0.0, 1.0);
}
- float getSufaceIdDiff(vec3 surfaceValue) {
- float surfaceIdDiff = 0.0;
- surfaceIdDiff += distance(surfaceValue, getSurfaceValue(1, 0));
- surfaceIdDiff += distance(surfaceValue, getSurfaceValue(0, 1));
- surfaceIdDiff += distance(surfaceValue, getSurfaceValue(0, 1));
- surfaceIdDiff += distance(surfaceValue, getSurfaceValue(0, -1));
- surfaceIdDiff += distance(surfaceValue, getSurfaceValue(1, 1));
- surfaceIdDiff += distance(surfaceValue, getSurfaceValue(1, -1));
- surfaceIdDiff += distance(surfaceValue, getSurfaceValue(-1, 1));
- surfaceIdDiff += distance(surfaceValue, getSurfaceValue(-1, -1));
- return surfaceIdDiff;
- }
+ float getSurfaceIdDiff(vec3 surfaceValue) {
+ float surfaceIdDiff = 0.0;
+
+ surfaceIdDiff += any(notEqual(surfaceValue, getSurfaceValue(1, 0))) ? 1.0 : 0.0;
+ surfaceIdDiff += any(notEqual(surfaceValue, getSurfaceValue(0, 1))) ? 1.0 : 0.0;
+ surfaceIdDiff += any(notEqual(surfaceValue, getSurfaceValue(-1, 0))) ? 1.0 : 0.0;
+ surfaceIdDiff += any(notEqual(surfaceValue, getSurfaceValue(0, -1))) ? 1.0 : 0.0;
+
+ surfaceIdDiff += any(notEqual(surfaceValue, getSurfaceValue(1, 1))) ? 1.0 : 0.0;
+ surfaceIdDiff += any(notEqual(surfaceValue, getSurfaceValue(1, -1))) ? 1.0 : 0.0;
+ surfaceIdDiff += any(notEqual(surfaceValue, getSurfaceValue(-1, 1))) ? 1.0 : 0.0;
+ surfaceIdDiff += any(notEqual(surfaceValue, getSurfaceValue(-1, -1))) ? 1.0 : 0.0;
+
+ return surfaceIdDiff;
+ }
+
+ float getDepthDiff(float depth) {
+ float depthDiff = 0.0;
+ depthDiff += abs(depth - getPixelDepth(1, 0));
+ depthDiff += abs(depth - getPixelDepth(-1, 0));
+ depthDiff += abs(depth - getPixelDepth(0, 1));
+ depthDiff += abs(depth - getPixelDepth(0, -1));
+
+ depthDiff += abs(depth - getPixelDepth(1, 1));
+ depthDiff += abs(depth - getPixelDepth(1, -1));
+ depthDiff += abs(depth - getPixelDepth(-1, 1));
+ depthDiff += abs(depth - getPixelDepth(-1, -1));
+ return depthDiff;
+ }
const uint k = 1103515245U; // GLIB C
@@ -184,34 +198,44 @@ class CustomOutlinePass extends Pass {
vec3 surfaceValue = getSurfaceValue(0, 0);
// Get the difference between depth of neighboring pixels and current.
- float depthDiff = 0.0;
- depthDiff += abs(depth - getPixelDepth(1, 0));
- depthDiff += abs(depth - getPixelDepth(-1, 0));
- depthDiff += abs(depth - getPixelDepth(0, 1));
- depthDiff += abs(depth - getPixelDepth(0, -1));
+ float depthDiff = getDepthDiff(depth);
// Get the difference between surface values of neighboring pixels
// and current
- float surfaceValueDiff = getSufaceIdDiff(surfaceValue);
+ float surfaceValueDiff = getSurfaceIdDiff(surfaceValue);
// Apply multiplier & bias to each
float depthBias = multiplierParameters.x;
float depthMultiplier = multiplierParameters.y;
+ float lerp = multiplierParameters.z;
- depthDiff = depthDiff * depthMultiplier;
- depthDiff = saturateValue(depthDiff);
+ depthDiff = saturateValue(depthDiff * depthMultiplier);
depthDiff = pow(depthDiff, depthBias);
+ if (debugVisualize == 7) {
+ // Surface ID difference
+ gl_FragColor = vec4(vec3(surfaceValueDiff), 1.0);
+ }
+
if (surfaceValueDiff != 0.0) surfaceValueDiff = 1.0;
+
+ float outline;
+ vec4 outlineColor = vec4(outlineColor, 1.0);;
- float outline = saturateValue(surfaceValueDiff + depthDiff);
-
- // Combine outline with scene color.
- vec4 outlineColor = vec4(outlineColor, 1.0);
- gl_FragColor = vec4(mix(sceneColor, outlineColor, outline));
+ // Normal mode, use the surface ids to draw outlines and add the shaded scene in too
+ if (debugVisualize == 0) {
+ outline = saturateValue(surfaceValueDiff);
+ gl_FragColor = vec4(mix(sceneColor, outlineColor, outline));
+ }
- //// For debug visualization of the different inputs to this shader.
- if (debugVisualize == 2) {
+ // Depth mode, use the depth to draw outlines only at the outside
+ if (debugVisualize == 1) {
+ outline = saturateValue(depthDiff);
+ gl_FragColor = vec4(mix(sceneColor, outlineColor, outline));
+ }
+
+ //Scene color no outline
+ if (debugVisualize == 2) {
gl_FragColor = sceneColor;
}
if (debugVisualize == 3) {
@@ -223,8 +247,14 @@ class CustomOutlinePass extends Pass {
}
if (debugVisualize == 5) {
// Outlines only
+ outline = mix(surfaceValueDiff, depthDiff, lerp);
+ outline = saturateValue(outline);
gl_FragColor = mix(vec4(0,0,0,0), outlineColor, outline);
}
+ if (debugVisualize == 6) {
+ // Depth difference
+ gl_FragColor = vec4(vec3(depthDiff), 1.0);
+ }
}
`;
}
@@ -237,10 +267,8 @@ class CustomOutlinePass extends Pass {
depthBuffer: {},
surfaceBuffer: {},
outlineColor: { value: new THREE.Color(this.outlineColor) },
- //4 scalar values packed in one uniform:
- // depth multiplier, depth bias
multiplierParameters: {
- value: new THREE.Vector2(0.9, 20),
+ value: new THREE.Vector3(0.9, 20, 0.5),
},
cameraNear: { value: this.renderCamera.near },
cameraFar: { value: this.renderCamera.far },
diff --git a/assets/js/outline-model-viewer/FindSurfaces.js b/assets/js/outline-model-viewer/FindSurfaces.js
index dc343a0..b4dcbc1 100644
--- a/assets/js/outline-model-viewer/FindSurfaces.js
+++ b/assets/js/outline-model-viewer/FindSurfaces.js
@@ -12,6 +12,7 @@ class FindSurfaces {
constructor() {
// This identifier, must be globally unique for each surface
// across all geometry rendered on screen
+ // reserve 10 special ids for various purposes
this.surfaceId = 10;
}
diff --git a/assets/js/outline-model-viewer/index.js b/assets/js/outline-model-viewer/index.js
index df228ee..e326285 100644
--- a/assets/js/outline-model-viewer/index.js
+++ b/assets/js/outline-model-viewer/index.js
@@ -106,7 +106,6 @@ export class OutlineModelViewer extends HTMLElement {
const canvas = this.shadow.querySelector("canvas");
let canvas_rect = canvas.getBoundingClientRect();
- console.log(canvas_rect);
// determine the outline and bg colors
const body = document.getElementsByTagName("body")[0];
@@ -138,11 +137,18 @@ export class OutlineModelViewer extends HTMLElement {
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(canvas_rect.width, canvas_rect.height, false);
- const light = new THREE.DirectionalLight(0xffffff, 2);
- scene.add(light);
- light.position.set(1.7, 1, -1);
+ const directionalLight = new THREE.DirectionalLight(
+ 0xffffff,
+ this.getAttribute("directional-light") || 2
+ );
+ scene.add(directionalLight);
+ directionalLight.position.set(1.7, 1, -1);
- scene.add(new THREE.AmbientLight(0xffffff, 5));
+ const ambientLight = new THREE.AmbientLight(
+ 0xffffff,
+ this.getAttribute("ambient-light") || 0.5
+ );
+ scene.add(ambientLight);
// Set up post processing
// Create a render target that holds a depthTexture so we can use it in the outline pass
@@ -180,6 +186,7 @@ export class OutlineModelViewer extends HTMLElement {
composer.addPass(effectFXAA);
const surfaceFinder = new FindSurfaces();
+
// Load model
const loader = new GLTFLoader();
const dracoLoader = new DRACOLoader();
@@ -189,7 +196,6 @@ export class OutlineModelViewer extends HTMLElement {
loader.load(model_path, (gltf) => {
scene.add(gltf.scene);
- surfaceFinder.surfaceId = 0;
// Compute bounding box
let box = new THREE.Box3().setFromObject(gltf.scene);
@@ -212,6 +218,7 @@ export class OutlineModelViewer extends HTMLElement {
if (node.type == "Mesh") {
// Add surface ID attribute to the geometry
const colorsTypedArray = surfaceFinder.getSurfaceIdAttribute(node);
+ node.surfaceId = colorsTypedArray;
node.geometry.setAttribute(
"color",
new THREE.BufferAttribute(colorsTypedArray, 4)
@@ -293,7 +300,9 @@ export class OutlineModelViewer extends HTMLElement {
);
}
- shadow.querySelector("#clicked-item").innerText = object.name;
+ shadow.querySelector(
+ "#clicked-item"
+ ).innerText = `${object.name} - ${object.type}`;
}
} else if (this.intersectedObject) {
this.intersectedObject = null;
@@ -359,22 +368,23 @@ export class OutlineModelViewer extends HTMLElement {
injectStyles: false,
closeFolders: true,
});
- gui.close();
+
+ if ((this.getAttribute("model") || "closed") === "closed") gui.close();
const uniforms = customOutline.fsQuad.material.uniforms;
- uniforms.debugVisualize.value =
- this.getAttribute("outlines") === "false" ? 2 : 0;
+ uniforms.debugVisualize.value = parseInt(this.getAttribute("mode")) || 0;
const params = {
- selectedObject: "None",
spin: controls.autoRotate,
- mode: uniforms.debugVisualize.value,
- // depthBias: uniforms.multiplierParameters.value.x,
- // depthMult: uniforms.multiplierParameters.value.y,
+ ambientLight: parseFloat(ambientLight.intensity),
+ directionalLight: parseFloat(directionalLight.intensity),
+ mode: { Mode: uniforms.debugVisualize.value },
+ depthBias: uniforms.multiplierParameters.value.x,
+ depthMult: uniforms.multiplierParameters.value.y,
+ lerp: uniforms.multiplierParameters.value.z,
printCamera: () => console.log(serialiseCamera(camera, controls)),
};
- gui.add(params, "selectedObject").listen();
gui.add(params, "spin").onChange((value) => {
controls.autoRotate = value;
});
@@ -383,21 +393,34 @@ export class OutlineModelViewer extends HTMLElement {
gui
.add(params.mode, "Mode", {
"Outlines + Shaded (default)": 0,
+ "Only outer outlines + shading": 1,
Shaded: 2,
"Depth buffer": 3,
"SurfaceID buffer": 4,
Outlines: 5,
+ "Depth Difference": 6,
+ "SurfaceID Difference": 7,
})
.onChange(function (value) {
uniforms.debugVisualize.value = value;
});
- // gui.add(params, "depthBias", 0.0, 5).onChange(function (value) {
- // uniforms.multiplierParameters.value.x = value;
- // });
- // gui.add(params, "depthMult", 0.0, 20).onChange(function (value) {
- // uniforms.multiplierParameters.value.y = value;
- // });
+ gui.add(params, "ambientLight", 0.0, 10.0).onChange(function (value) {
+ ambientLight.intensity = value;
+ });
+ gui.add(params, "directionalLight", 0.0, 10.0).onChange(function (value) {
+ directionalLight.intensity = value;
+ });
+
+ gui.add(params, "depthBias", 0.0, 5).onChange(function (value) {
+ uniforms.multiplierParameters.value.x = value;
+ });
+ gui.add(params, "depthMult", 0.0, 40.0).onChange(function (value) {
+ uniforms.multiplierParameters.value.y = value;
+ });
+ gui.add(params, "lerp", 0.0, 1.0).onChange(function (value) {
+ uniforms.multiplierParameters.value.z = value;
+ });
// Toggle fullscreen mode
const shadow = this.shadow;