From ca3b9865fe0c0016caaa75592312ccf5580c3754 Mon Sep 17 00:00:00 2001 From: DUDSS Date: Sat, 25 May 2024 01:31:00 +0200 Subject: [PATCH] Added ClearView normal distance importance. --- src/main.js | 1 + src/renderer/Clearview.js | 18 +++++++----- src/renderer/shaders/clearview.frag | 42 +++++++++++++++++++++++++++- src/renderer/shaders/isosurface.frag | 8 ------ src/ui/UI.js | 19 +++++++++++-- 5 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/main.js b/src/main.js index 30e3a16..1c70e53 100644 --- a/src/main.js +++ b/src/main.js @@ -111,6 +111,7 @@ class Settings { importanceMethod = 3; curvatureMultiplier = 1.0; distanceMultiplier = 4.0; + normalDistanceMultiplier = 10.0; worldSpaceLighting = false; isoColor1 = new THREE.Color(0.56, 0.72, 0.91); diff --git a/src/renderer/Clearview.js b/src/renderer/Clearview.js index b8c3497..0f7c017 100644 --- a/src/renderer/Clearview.js +++ b/src/renderer/Clearview.js @@ -1,8 +1,8 @@ import * as THREE from "three"; -// import {resolveInclude} from "~/utils.js"; +import {resolveInclude} from "~/utils.js"; -// import shader_chunk_raymarcher_frag from "./shaders/chunks/raymarcher.chunk.frag"; +import shader_chunk_raymarcher_frag from "./shaders/chunks/raymarcher.chunk.frag"; import shader_clearview_frag from "./shaders/clearview.frag"; import shader_basic_vert from "./shaders/basic.vert"; import "./Raymarcher.js"; @@ -44,6 +44,7 @@ export default class Clearview { u_worldSpaceLight: { value: false }, u_color1: { value: settings.isoColor1 }, u_color2: { value: settings.isoColor2 }, + u_isovalue2: { value: settings.isovalue2 }, u_iso1PosTex: { value: this.isosurface1Target.textures[0] }, u_iso1NormalTex: { value: this.isosurface1Target.textures[1] }, u_iso2PosTex: { value: this.isosurface2Target.textures[0] }, @@ -52,10 +53,10 @@ export default class Clearview { transparent: true, side: THREE.BackSide, } ); - // this.clearviewShader.onBeforeCompile = (shader) => { - // shader.fragmentShader = resolveInclude(shader.fragmentShader, "raymarcher.chunk.frag", shader_chunk_raymarcher_frag); - // }; - // this.addRaymarcherUniforms(this.isosurfaceShader.uniforms, resolution); + this.clearviewShader.onBeforeCompile = (shader) => { + shader.fragmentShader = resolveInclude(shader.fragmentShader, "raymarcher.chunk.frag", shader_chunk_raymarcher_frag); + }; + this.raymarcher.addRaymarcherUniforms(this.clearviewShader.uniforms, resolution); this.cube = new THREE.Mesh(box, this.clearviewShader); @@ -86,12 +87,15 @@ export default class Clearview { this.clearviewShader.uniforms.u_importanceStrength.value = settings.distanceMultiplier; } else if (settings.importanceMethod == 3) { this.clearviewShader.uniforms.u_importanceStrength.value = settings.curvatureMultiplier; + } else if (settings.importanceMethod == 4) { + this.clearviewShader.uniforms.u_importanceStrength.value = settings.normalDistanceMultiplier; } this.clearviewShader.uniforms.u_worldSpaceLight.value = settings.worldSpaceLighting; this.clearviewShader.uniforms.u_color1.value = settings.isoColor1; this.clearviewShader.uniforms.u_color2.value = settings.isoColor2; + this.clearviewShader.uniforms.u_isovalue2.value = settings.isovalue2; - // this.updateRaymarcherUniforms(this.isosurfaceShader, settings); + this.raymarcher.updateRaymarcherUniforms(this.clearviewShader, settings); } resize(realWidth, realHeight) { diff --git a/src/renderer/shaders/clearview.frag b/src/renderer/shaders/clearview.frag index b0e8cc7..44dec73 100644 --- a/src/renderer/shaders/clearview.frag +++ b/src/renderer/shaders/clearview.frag @@ -4,6 +4,8 @@ varying vec3 aPos; uniform vec2 u_resolution; +#include + uniform vec3 u_focusPoint; uniform float u_focusArea; uniform float u_focusAreaSharpness; @@ -20,6 +22,8 @@ uniform sampler2D u_iso1NormalTex; uniform sampler2D u_iso2PosTex; uniform sampler2D u_iso2NormalTex; +uniform float u_isovalue2; + struct Material { vec3 ambient; vec3 diffuse; @@ -81,6 +85,31 @@ float calculateCurvature(ivec2 fragCoord, vec4 fragNormal, in sampler2D normalSa return curvature; } +float calculateNormalDistance(vec3 startPos, vec3 normal, float isoThreshold, float stepSize, float stopDist) { + // Raymarch from the position, along the inverse of the normal until you hit another isosurface + vec3 rayDir = -normal; + vec3 pos = startPos; + + float step = 0.; + + int stepCount = int(stopDist / stepSize); + + for (int i = 0; i < stepCount; i++) { + float density = sampleVolume(pos); + + if (density > isoThreshold) { + return step; + } + + if (step > stopDist) { + break; + } + step += stepSize; + pos += rayDir * stepSize; + } + return 1.0 * 1.0 / u_importanceStrength; // Isosurface too far away +} + void main() { Material material1; material1.ambient = u_color1 * 0.08; @@ -123,9 +152,20 @@ void main() { trans = 1. - pow(clamp(max(fade, fadeHeuristic), 0., 1.), u_focusAreaSharpness); break; } + // Normal distance based importance + case 4: { + float normalDistance = 0.0; + if (fade <= 1.0) { + float longestSpan = u_focusArea * 2.0; + float stepSize = longestSpan / (float(u_volumeSamples) * 0.6); // TODO: Maybe create separate sample count slider in the UI for this + normalDistance = calculateNormalDistance(iso1Position.xyz, iso1Normal.xyz, u_isovalue2, stepSize, longestSpan); + normalDistance *= u_importanceStrength; + } + trans = 1. - pow(clamp(max(fade, normalDistance), 0., 1.), u_focusAreaSharpness); + break; + } // Distance based importance case 1: { - float fade = length(u_focusPoint - contextPos) / u_focusArea; trans = 1. - pow(clamp(fade, 0., 1.), u_focusAreaSharpness); break; } diff --git a/src/renderer/shaders/isosurface.frag b/src/renderer/shaders/isosurface.frag index 72b7869..72f7f25 100644 --- a/src/renderer/shaders/isosurface.frag +++ b/src/renderer/shaders/isosurface.frag @@ -86,14 +86,6 @@ void main() { setupRaymarcher(coords, rayDir, frontPos, stepSize, stepCount, raySpanLen); - // vec4 color; - - // color = raymarchAccumulate(rayDir, frontPos, stepSize, stepCount, raySpanLen); - // color = raymarchAverage(rayDir, frontPos, stepSize, stepCount, raySpanLen); - - // oPosition = color; - // oNormal = vec4(vec3(raySpanLen), 1.0); - IsosurfacePoint point = raymarchIsosurface(rayDir, frontPos, stepSize, stepCount, raySpanLen, u_isovalue); oPosition = point.position; oNormal = point.normal; diff --git a/src/ui/UI.js b/src/ui/UI.js index 4af3572..cebb7a1 100644 --- a/src/ui/UI.js +++ b/src/ui/UI.js @@ -17,7 +17,7 @@ export default class UI { expanded: true, }); this.pane.registerPlugin(CamerakitPlugin); - + this.pane.addBlade({ view: "list", label: "method", @@ -48,7 +48,7 @@ export default class UI { importanceAware.hidden = false; } }); - + this.pane.addBlade({ view: "list", label: "mode", @@ -116,6 +116,7 @@ export default class UI { label: "importance method", options: [ { text: "view distance", value: 0 }, + { text: "normal distance", value: 4 }, { text: "distance", value: 1 }, { text: "curvature", value: 3 }, ], @@ -126,14 +127,22 @@ export default class UI { case 0: curvatureMultiplier.hidden = true; distanceMultiplier.hidden = false; + normalDistanceMultiplier.hidden = true; break; case 3: curvatureMultiplier.hidden = false; distanceMultiplier.hidden = true; + normalDistanceMultiplier.hidden = true; + break; + case 4: + curvatureMultiplier.hidden = true; + distanceMultiplier.hidden = true; + normalDistanceMultiplier.hidden = false; break; default: curvatureMultiplier.hidden = true; distanceMultiplier.hidden = true; + normalDistanceMultiplier.hidden = true; } }); let curvatureMultiplier = clearview.addBinding(settings, "curvatureMultiplier", { @@ -146,8 +155,14 @@ export default class UI { min: 0.0, max: 20.0, }); + let normalDistanceMultiplier = clearview.addBinding(settings, "normalDistanceMultiplier", { + label: "distance strength", + min: 0.0, + max: 20.0, + }); curvatureMultiplier.hidden = false; distanceMultiplier.hidden = true; + normalDistanceMultiplier.hidden = true; clearview.addBlade({ view: "separator",