Bladeren bron

Fix widget dispose, frameCount uniform check in SSAO, add new webgi examples.

master
Palash Bansal 1 jaar geleden
bovenliggende
commit
136f463d43
No account linked to committer's email address

+ 37
- 0
examples/anisotropy-plugin/index.html Bestand weergeven

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bloom Plugin</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.3.0/dist/index.mjs",
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 48
- 0
examples/anisotropy-plugin/script.ts Bestand weergeven

import {_testFinish, IObject3D, LoadingScreenPlugin, PickingPlugin, SSAAPlugin, ThreeViewer} from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
// @ts-expect-error todo fix
import {AnisotropyPlugin, BloomPlugin, OutlinePlugin, SSContactShadowsPlugin, TemporalAAPlugin} from '@threepipe/webgi-plugins'

async function init() {
const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
rgbm: true,
zPrepass: false,
renderScale: 'auto',
// rgbm: false,
maxHDRIntensity: 8,
dropzone: {
addOptions: {
disposeSceneObjects: true,
},
},
plugins: [LoadingScreenPlugin, SSAAPlugin, TemporalAAPlugin, BloomPlugin, PickingPlugin, OutlinePlugin, SSContactShadowsPlugin],
})

const anisotropy = viewer.addPluginSync(AnisotropyPlugin)
const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))

await viewer.setEnvironmentMap('https://demo-assets.pixotronics.com/pixo/hdr/gem_2.hdr', {
setBackground: false,
})
await viewer.load<IObject3D>('https://demo-assets.pixotronics.com/pixo/gltf/anisotropyScene.glb', {
autoCenter: true,
autoScale: true,
})

viewer.scene.mainCamera.position.set(5, 0, 0)

ui.setupPluginUi(anisotropy)
ui.setupPluginUi(BloomPlugin)
ui.setupPluginUi(PickingPlugin)

// // add a light to test shader compile with sscs
// const light = new DirectionalLight2()
// viewer.scene.addObject(light)
// light.castShadow = true


}

init().then(_testFinish)

+ 45
- 44
examples/index.html Bestand weergeven

padding: 0; padding: 0;
} }


.sidebar h1 a {
a.brand-link{
//background: linear-gradient(to right, rgb(231, 7, 7), rgb(91, 34, 203), rgb(7, 108, 211)); //background: linear-gradient(to right, rgb(231, 7, 7), rgb(91, 34, 203), rgb(7, 108, 211));
background: linear-gradient(to right, var(--secondary-color), var(--secondary-color), rgb(231, 7, 7)); background: linear-gradient(to right, var(--secondary-color), var(--secondary-color), rgb(231, 7, 7));
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
text-decoration: none; text-decoration: none;
} }
a.brand-link.webgi-link::after {
content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAQElEQVR42qXKwQkAIAxDUUdxtO6/RBQkQZvSi8I/pL4BoGw/XPkh4XigPmsUgh0626AjRsgxHTkUThsG2T/sIlzdTsp52kSS1wAAAABJRU5ErkJggg==);
margin: 0 3px 0 5px;
filter: invert(1);
}


.sidebar h1 a:hover { .sidebar h1 a:hover {
color: var(--text-color-accent); color: var(--text-color-accent);
} }


.sidebar ul { .sidebar ul {
font-size: 1rem;
list-style: none;
padding: 0 0 0 1rem;
margin: 0 0 1rem;
display: flex;
flex-direction: column;
font-weight: normal;
gap: 0.6rem;
font-size: 1rem; list-style: none;
padding: 0 0 0 1rem; margin: 0 0 1rem;
display: flex; gap: 0.6rem;
flex-direction: column; font-weight: normal;
} }


.sidebar ul li a { .sidebar ul li a {
} }


.iframe-container { .iframe-container {
flex: 1;
height: 100%;
overflow: hidden;
flex: 1; height: 100%; overflow: hidden;
} }


.iframe-container iframe { .iframe-container iframe {
width: 100%;
height: 100%;
width: 100%; height: 100%;
border: none; border: none;
} }


.closed > ul {
display: none;
}

.closed > h1 {
display: none;
}

.closed > h2 {
.closed > ul, .closed > h1, .closed > h2 {
display: none; display: none;
} }


.closed:before{ .closed:before{
content: attr(data-selected-example); content: attr(data-selected-example);
position: absolute; position: absolute;
top: 0;
left: 0;
height: 100%;
width: 3.3rem;
top: 0; left: 0;
height: 100%; width: 3.3rem;
color: var(--primary-color); color: var(--primary-color);
font-size: 1.25rem; font-size: 1.25rem;
text-align: center;
vertical-align: middle;
text-align: center; vertical-align: middle;
line-height: 3.25rem; line-height: 3.25rem;
writing-mode: vertical-lr; writing-mode: vertical-lr;
text-orientation: upright;
text-transform: uppercase;
text-orientation: upright; text-transform: uppercase;
font-family: "Source Code Pro", Menlo, Courier, monospace; font-family: "Source Code Pro", Menlo, Courier, monospace;
} }


} }
.search-bar{ .search-bar{
box-sizing: border-box; box-sizing: border-box;
margin-bottom: 1rem;
width: 90%;
margin-bottom: 1rem; width: 90%;
background: transparent; background: transparent;
position: relative; position: relative;
} }
.search-bar input{ .search-bar input{
box-sizing: border-box; box-sizing: border-box;
width: 100%;
padding: 0.5rem;
width: 100%; padding: 0.5rem;
color: var(--text-color-accent); color: var(--text-color-accent);
background: var(--background-color-search); background: var(--background-color-search);
border: none;
border-radius: 4px;
border: none; border-radius: 4px;
transition: all 0.3s ease-in-out; transition: all 0.3s ease-in-out;
} }
.search-bar input:hover { .search-bar input:hover {
} }
.search-icon { .search-icon {
position: absolute; position: absolute;
top: 50%;
left: 10px;
top: 50%; left: 10px;
transform: translateY(-50%); transform: translateY(-50%);
color: var(--primary-color); color: var(--primary-color);
width: 15px;
height: 15px;
width: 15px; height: 15px;
} }


.search-bar input { .search-bar input {
padding-left: 2rem; padding-left: 2rem;
} }


.github-icon{
position: absolute; right:-1.25rem; top: 0.1rem; fill: #eeeeee; cursor: pointer;
}

@media only screen and (max-width: 768px) { @media only screen and (max-width: 768px) {
.root-container { .root-container {
flex-direction: column; flex-direction: column;
} }
} }



</style> </style>
<script> <script>
window.addEventListener('DOMContentLoaded', () => { window.addEventListener('DOMContentLoaded', () => {
<div class="root-container"> <div class="root-container">
<div class="sidebar" data-selected-example="Tweakpane Editor"> <div class="sidebar" data-selected-example="Tweakpane Editor">
<button class="hamburger"> &#9776;</button> <button class="hamburger"> &#9776;</button>
<h1><a href="https://github.com/repalash/threepipe">ThreePipe</a> Examples</h1>
<h1 style="position:relative;">
<a class="brand-link" href="https://threepipe.org">ThreePipe</a>
Examples
<a class="brand-link" target="_blank" href="https://github.com/repalash/threepipe">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
width="28" height="28" viewBox="0 0 24 24"
class="github-icon">
<path d="M10.9,2.1c-4.6,0.5-8.3,4.2-8.8,8.7c-0.5,4.7,2.2,8.9,6.3,10.5C8.7,21.4,9,21.2,9,20.8v-1.6c0,0-0.4,0.1-0.9,0.1 c-1.4,0-2-1.2-2.1-1.9c-0.1-0.4-0.3-0.7-0.6-1C5.1,16.3,5,16.3,5,16.2C5,16,5.3,16,5.4,16c0.6,0,1.1,0.7,1.3,1c0.5,0.8,1.1,1,1.4,1 c0.4,0,0.7-0.1,0.9-0.2c0.1-0.7,0.4-1.4,1-1.8c-2.3-0.5-4-1.8-4-4c0-1.1,0.5-2.2,1.2-3C7.1,8.8,7,8.3,7,7.6c0-0.4,0-0.9,0.2-1.3 C7.2,6.1,7.4,6,7.5,6c0,0,0.1,0,0.1,0C8.1,6.1,9.1,6.4,10,7.3C10.6,7.1,11.3,7,12,7s1.4,0.1,2,0.3c0.9-0.9,2-1.2,2.5-1.3 c0,0,0.1,0,0.1,0c0.2,0,0.3,0.1,0.4,0.3C17,6.7,17,7.2,17,7.6c0,0.8-0.1,1.2-0.2,1.4c0.7,0.8,1.2,1.8,1.2,3c0,2.2-1.7,3.5-4,4 c0.6,0.5,1,1.4,1,2.3v2.6c0,0.3,0.3,0.6,0.7,0.5c3.7-1.5,6.3-5.1,6.3-9.3C22,6.1,16.9,1.4,10.9,2.1z"></path>
</svg>
</a>
</h1>

<div class="search-bar"> <div class="search-bar">
<svg class="search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg class="search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="8"></circle> <circle cx="11" cy="11" r="8"></circle>
</svg> </svg>
<input id="filterInput" type="text" placeholder="Search" autocomplete="off" autofocus > <input id="filterInput" type="text" placeholder="Search" autocomplete="off" autofocus >
</div> </div>

<h2 class="category">Editors/Viewers</h2> <h2 class="category">Editors/Viewers</h2>
<ul> <ul>
<li><a class="selected" href="./tweakpane-editor/">Tweakpane Editor </a></li> <li><a class="selected" href="./tweakpane-editor/">Tweakpane Editor </a></li>
<li><a href="./basic-svg-renderer-plugin/">Basic SVG Renderer Plugin </a></li> <li><a href="./basic-svg-renderer-plugin/">Basic SVG Renderer Plugin </a></li>
<li><a href="./three-svg-renderer-plugin/">Three SVG Renderer Plugin </a></li> <li><a href="./three-svg-renderer-plugin/">Three SVG Renderer Plugin </a></li>
</ul> </ul>
<h2 class="category">Realistic Rendering (webgi)</h2>
<h2 class="category">Realistic Rendering (<a class="brand-link webgi-link" href="https://webgi.dev/" target="_blank">webgi</a>)</h2>
<ul> <ul>
<li><a href="./bloom-plugin/">HDR Bloom Plugin </a></li> <li><a href="./bloom-plugin/">HDR Bloom Plugin </a></li>
<li><a href="./depthoffield-plugin/">DepthOfField Plugin </a></li> <li><a href="./depthoffield-plugin/">DepthOfField Plugin </a></li>
<li><a href="./ssreflection-plugin/">Screen Space Reflection(SSR) Plugin </a></li> <li><a href="./ssreflection-plugin/">Screen Space Reflection(SSR) Plugin </a></li>
<li><a href="./temporalaa-plugin/">Temporal Anti-aliasing Plugin </a></li> <li><a href="./temporalaa-plugin/">Temporal Anti-aliasing Plugin </a></li>
<li><a href="./outline-plugin/">Outline(Picking) Plugin </a></li>
<li><a href="./ssgi-plugin/">Screen Space Global Illumination(SSGI) Plugin </a></li>
<li><a href="./ssgi-ssr-plugin/">SSGI + SSR Plugins </a></li>
<!--<li><a href="./ssrtao-plugin/">Screen Space Ray Traced AO Plugin </a></li>-->
<li><a href="./anisotropy-plugin/">Anisotropy(Blender) Plugin </a></li>
<li><a href="./velocity-buffer-plugin/">Velocity Buffer Plugin (TAA) </a></li> <li><a href="./velocity-buffer-plugin/">Velocity Buffer Plugin (TAA) </a></li>
<li><a href="./sscontactshadows-plugin/">Contact Shadows(SSCS) Plugin </a></li> <li><a href="./sscontactshadows-plugin/">Contact Shadows(SSCS) Plugin </a></li>
</ul> </ul>

+ 37
- 0
examples/outline-plugin/index.html Bestand weergeven

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSReflection Plugin</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.3.0/dist/index.mjs",
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 68
- 0
examples/outline-plugin/script.ts Bestand weergeven

import {
_testFinish,
BaseGroundPlugin,
GBufferPlugin,
IObject3D,
LoadingScreenPlugin,
PickingPlugin, RenderTargetPreviewPlugin,
SSAAPlugin,
ThreeViewer,
} from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
import {
BloomPlugin,
OutlinePlugin,
SSReflectionPlugin,
TemporalAAPlugin,
VelocityBufferPlugin,
// @ts-expect-error todo fix
} from '@threepipe/webgi-plugins'

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
rgbm: true,
dropzone: {
addOptions: {
disposeSceneObjects: true,
},
},
plugins: [LoadingScreenPlugin, GBufferPlugin, BloomPlugin, SSAAPlugin, TemporalAAPlugin, new VelocityBufferPlugin(undefined, false)],
})
viewer.renderManager.stableNoise = true

const inline = true
const ssrefl = viewer.addPluginSync(new SSReflectionPlugin(inline))
const ground = viewer.addPluginSync(new BaseGroundPlugin())
ground.material!.roughness = 0.2
viewer.addPluginSync(PickingPlugin)
console.log(ssrefl)

const outline = viewer.addPluginSync(OutlinePlugin)
outline.enableHighlight = true

const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))

await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', {
setBackground: true,
})
await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
autoCenter: true,
autoScale: true,
})

ui.setupPluginUi(outline)
ui.setupPluginUi(BaseGroundPlugin)
ui.setupPluginUi(PickingPlugin)
ui.setupPluginUi(BloomPlugin)
ui.setupPluginUi(TemporalAAPlugin)
ui.setupPluginUi(VelocityBufferPlugin)

const targetPreview = viewer.addPluginSync(RenderTargetPreviewPlugin)
targetPreview.addTarget(()=>outline.target, 'outline', false, true, true, (s)=>`${s} = 1.-${s};`)

}

init().then(_testFinish)

+ 37
- 0
examples/ssgi-plugin/index.html Bestand weergeven

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSReflection Plugin</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.3.0/dist/index.mjs",
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 146
- 0
examples/ssgi-plugin/script.ts Bestand weergeven

import {
_testFinish,
BaseGroundPlugin, DirectionalLight2,
GBufferPlugin,
IObject3D, LoadingScreenPlugin, PhysicalMaterial,
PickingPlugin,
RenderTargetPreviewPlugin, SSAAPlugin,
ThreeViewer, Object3DWidgetsPlugin, TransformControlsPlugin, AssetExporterPlugin, OrbitControls3,
} from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
// @ts-expect-error todo fix
import {BloomPlugin, SSReflectionPlugin, TemporalAAPlugin, VelocityBufferPlugin, SSGIPlugin} from '@threepipe/webgi-plugins'

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
rgbm: true,
zPrepass: false,
renderScale: 'auto',
maxRenderScale: 1.5,
dropzone: {
addOptions: {
disposeSceneObjects: true,
},
},
plugins: [LoadingScreenPlugin, GBufferPlugin, BloomPlugin, SSAAPlugin, TemporalAAPlugin, Object3DWidgetsPlugin, TransformControlsPlugin, AssetExporterPlugin, new VelocityBufferPlugin(undefined, false), SSReflectionPlugin],
// rgbm: false,
})
viewer.renderManager.stableNoise = true

viewer.getPlugin(SSReflectionPlugin)!.enabled = false

const ssgi = viewer.addPluginSync(new SSGIPlugin())
viewer.addPluginSync(new BaseGroundPlugin())

const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))
await viewer.setEnvironmentMap('https://hdrihaven.r2cache.com/hdr/1k/empty_warehouse_01_1k.hdr', {
setBackground: true,
})
await viewer.load<IObject3D>('https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Sponza/glTF/Sponza.gltf', {
autoCenter: false,
autoScale: true,
autoScaleRadius: 30,
})

viewer.scene.modelRoot.traverse((o) => {
if (o.material) {
const mat = o.material as PhysicalMaterial
mat.emissiveIntensity *= 10
}
})
viewer.scene.envMapIntensity = 0.0

ui.setupPluginUi(ssgi)
ui.setupPluginUi(SSReflectionPlugin)
ui.setupPluginUi(BaseGroundPlugin)
ui.setupPluginUi(PickingPlugin)
ui.setupPluginUi(BloomPlugin)
ui.setupPluginUi(TemporalAAPlugin)
ui.setupPluginUi(VelocityBufferPlugin)
ui.setupPluginUi(AssetExporterPlugin)

const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin)
targetPreview.addTarget(() => ssgi.target, 'ssgi')
// const gb = viewer.getPlugin(GBufferPlugin)
// targetPreview.addTarget(() => gb?.target, 'depth')

const camera = viewer.scene.mainCamera
camera.position.set(-1, 5, -0.7)
camera.target.set(-4, 4, -0.7)
const controls = camera.controls as OrbitControls3
controls.minDistance = 2
controls.maxDistance = 3
controls.autoPushTarget = true
controls.autoPullTarget = true

const light = new DirectionalLight2()
viewer.scene.addObject(light)
light.position.set(0, 20, 0)
light.lookAt(-25, 0, 0)
light.intensity = 30
light.castShadow = true
light.shadow.camera.left = -25
light.shadow.camera.right = 25
light.shadow.camera.top = 25
light.shadow.camera.bottom = -25
light.shadow.mapSize.set(1024, 1024)

// todo add to DirectionalLight
light.uiConfig.children!.push({
type: 'vec2',
label: 'Shadow Map Size',
property: [light?.shadow, 'mapSize'],
onChange: ()=>{
light.shadow.map?.dispose()
light.shadow.mapPass?.dispose()
light.shadow.map = null as any
light.shadow.mapPass = null as any
},
},
{
type: 'slider',
bounds: [-0.001, 0.001],
stepSize: 0.00002,
label: 'Shadow Bias',
property: [light?.shadow, 'bias'],
onChange: (e)=>light.setDirty(e),
},
{
type: 'slider',
bounds: [-0.1, 0.1],
stepSize: 0.005,
label: 'Shadow Normal Bias',
property: [light?.shadow, 'normalBias'],
onChange: (e)=>light.setDirty(e),
},
{
type: 'slider',
bounds: [0, 5],
label: 'Shadow radius',
property: [light?.shadow, 'radius'],
onChange: (e)=>light.setDirty(e),
},
{
type: 'slider',
bounds: [0.1, 50],
label: 'Shadow frustum',
// property: [light.shadow, 'radius'],
getValue: ()=>{
return light.shadow.camera.right * 2
},
setValue: (v: number)=>{
light.shadow.camera.left = -v / 2
light.shadow.camera.right = v / 2
light.shadow.camera.top = v / 2
light.shadow.camera.bottom = -v / 2
},
onChange: (e)=>light.setDirty(e),
})

ui.appendChild(light.uiConfig)
}

init().then(_testFinish)

+ 37
- 0
examples/ssgi-ssr-plugin/index.html Bestand weergeven

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SSReflection Plugin</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.3.0/dist/index.mjs",
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 63
- 0
examples/ssgi-ssr-plugin/script.ts Bestand weergeven

import {
_testFinish,
AssetExporterPlugin,
GBufferPlugin,
IObject3D,
LoadingScreenPlugin,
Object3DWidgetsPlugin,
PickingPlugin,
RenderTargetPreviewPlugin,
SSAAPlugin,
ThreeViewer,
} from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
// @ts-expect-error todo fix
import {BloomPlugin, SSGIPlugin, SSReflectionPlugin, TemporalAAPlugin, OutlinePlugin} from '@threepipe/webgi-plugins'

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
rgbm: true,
zPrepass: false,
renderScale: 'auto',
maxRenderScale: 1.5,
dropzone: {
addOptions: {
disposeSceneObjects: true,
},
},
plugins: [LoadingScreenPlugin, GBufferPlugin, BloomPlugin, PickingPlugin, SSAAPlugin, TemporalAAPlugin, OutlinePlugin, Object3DWidgetsPlugin, AssetExporterPlugin, new SSReflectionPlugin(ssrInline), SSGIPlugin],
// rgbm: false,
})
viewer.renderManager.stableNoise = true

viewer.getPlugin(SSReflectionPlugin)!.enabled = false

const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))
const model = await viewer.load<IObject3D>('https://asset-samples.threepipe.org/demos/sponza-ssgi-ssr.glb')
viewer.scene.envMapIntensity = 0.0
viewer.getPlugin(SSGIPlugin)!.pass.stepCount = 8

ui.setupPluginUi(SSGIPlugin)
ui.setupPluginUi(SSReflectionPlugin)
model?.traverse((obj) => {
if (obj.isLight) {
ui.appendChild(obj.uiConfig)
}
})
ui.setupPluginUi(PickingPlugin)
ui.setupPluginUi(BloomPlugin)
ui.setupPluginUi(TemporalAAPlugin)

const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin)
targetPreview.addTarget(() => viewer.getPlugin(SSGIPlugin)!.target, 'ssgi')
!ssrInline && targetPreview.addTarget(() => viewer.getPlugin(SSReflectionPlugin)!.target, 'ssr')

}

// todo: inline = false has a bug, not clearing maybe?
const ssrInline = true

init().then(_testFinish)

+ 1
- 2
examples/ssreflection-plugin/index.html Bestand weergeven

<script type="importmap"> <script type="importmap">
{ {
"imports": { "imports": {
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.2.0/dist/index.mjs",

"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.3.0/dist/index.mjs",
"threepipe": "./../../dist/index.mjs", "threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs" "@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs"
} }

+ 19
- 28
examples/ssreflection-plugin/script.ts Bestand weergeven

import { import {
_testFinish, _testFinish,
BaseGroundPlugin, BaseGroundPlugin,
Color,
GBufferPlugin, GBufferPlugin,
IObject3D, LoadingScreenPlugin,
LoadingScreenPlugin,
PickingPlugin, PickingPlugin,
RenderTargetPreviewPlugin, SSAAPlugin,
RenderTargetPreviewPlugin,
SSAAPlugin,
ThreeViewer, ThreeViewer,
} from 'threepipe' } from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane' import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
// @ts-expect-error todo fix
// @ts-expect-error todo fix import
import {BloomPlugin, SSReflectionPlugin, TemporalAAPlugin} from '@threepipe/webgi-plugins' import {BloomPlugin, SSReflectionPlugin, TemporalAAPlugin} from '@threepipe/webgi-plugins'


async function init() { async function init() {
const ssrefl = viewer.addPluginSync(new SSReflectionPlugin(inline)) const ssrefl = viewer.addPluginSync(new SSReflectionPlugin(inline))
const ground = viewer.addPluginSync(BaseGroundPlugin) const ground = viewer.addPluginSync(BaseGroundPlugin)
viewer.addPluginSync(PickingPlugin) viewer.addPluginSync(PickingPlugin)
console.log(ssrefl)
const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))


await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', {
setBackground: true,
})
await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
autoCenter: true,
autoScale: true,
})
// const model = result?.getObjectByName('node_damagedHelmet_-6514')
// const materials = (model?.materials || []) as PhysicalMaterial[]
const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))


ui.setupPluginUi(ssrefl)
ui.setupPluginUi(ssrefl, {expanded: true})
ui.setupPluginUi(BaseGroundPlugin) ui.setupPluginUi(BaseGroundPlugin)
ui.setupPluginUi(PickingPlugin) ui.setupPluginUi(PickingPlugin)
ui.setupPluginUi(BloomPlugin) ui.setupPluginUi(BloomPlugin)


// for (const material of materials) {
// ui.appendChild(material.uiConfig)
// }

// bloom.pass!.intensity = 3
// bloom.pass!.threshold = 1

// viewer.scene.background = null
// bloom.pass!.bloomDebug = true

ground.material!.roughness = 0.2
const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin) const targetPreview = await viewer.addPlugin(RenderTargetPreviewPlugin)
if (!ssrefl.inlineShaderRayTrace) { if (!ssrefl.inlineShaderRayTrace) {
targetPreview.addTarget(() => ssrefl.target, 'ssrefl') targetPreview.addTarget(() => ssrefl.target, 'ssrefl')
} }
// const gb = viewer.getPlugin(GBufferPlugin)
// targetPreview.addTarget(() => gb?.target, 'depth')

await viewer.load('https://asset-samples.threepipe.org/demos/classic-watch.glb', {
autoCenter: true,
autoScale: false,
})

viewer.scene.backgroundColor = new Color(0x1B1B1F)
ground.tonemapGround = false
ground.material!.color.set(0x1B1B1F)
ground.material!.roughness = 0.2
ground.material!.userData.separateEnvMapIntensity = true
ground.material!.envMapIntensity = 0


} }



+ 1
- 1
examples/tweakpane-editor/index.html Bestand weergeven

"@threepipe/plugin-network": "./../../plugins/network/dist/index.mjs", "@threepipe/plugin-network": "./../../plugins/network/dist/index.mjs",
"@threepipe/plugin-gltf-transform": "./../../plugins/gltf-transform/dist/index.mjs", "@threepipe/plugin-gltf-transform": "./../../plugins/gltf-transform/dist/index.mjs",
"@threepipe/plugin-gaussian-splatting": "./../../plugins/gaussian-splatting/dist/index.mjs", "@threepipe/plugin-gaussian-splatting": "./../../plugins/gaussian-splatting/dist/index.mjs",
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.2.1/dist/index.mjs"
"@threepipe/webgi-plugins": "https://unpkg.com/@threepipe/webgi-plugins@0.3.1/dist/index.mjs"
} }
} }



+ 10
- 7
examples/tweakpane-editor/script.ts Bestand weergeven

import {AWSClientPlugin, TransfrSharePlugin} from '@threepipe/plugin-network' import {AWSClientPlugin, TransfrSharePlugin} from '@threepipe/plugin-network'
import {GLTFDracoExportPlugin} from '@threepipe/plugin-gltf-transform' import {GLTFDracoExportPlugin} from '@threepipe/plugin-gltf-transform'
// @ts-expect-error todo fix import // @ts-expect-error todo fix import
import {BloomPlugin, DepthOfFieldPlugin, SSContactShadowsPlugin, SSReflectionPlugin, TemporalAAPlugin, VelocityBufferPlugin} from '@threepipe/webgi-plugins'
import {BloomPlugin, DepthOfFieldPlugin, SSContactShadowsPlugin, SSReflectionPlugin, TemporalAAPlugin, VelocityBufferPlugin, OutlinePlugin, SSGIPlugin, AnisotropyPlugin} from '@threepipe/webgi-plugins'


function checkQuery(key: string, def = true) { function checkQuery(key: string, def = true) {
return !['false', 'no', 'f'].includes(getUrlQueryParam(key, def ? 'yes' : 'no').toLowerCase()) return !['false', 'no', 'f'].includes(getUrlQueryParam(key, def ? 'yes' : 'no').toLowerCase())
new SSAAPlugin(), new SSAAPlugin(),
GLTFAnimationPlugin, GLTFAnimationPlugin,
TransformAnimationPlugin, TransformAnimationPlugin,
new GBufferPlugin(HalfFloatType, true, true, true),
new DepthBufferPlugin(HalfFloatType, false, false),
new NormalBufferPlugin(HalfFloatType, false),
PickingPlugin, PickingPlugin,
new TransformControlsPlugin(false), new TransformControlsPlugin(false),
OutlinePlugin,
EditorViewWidgetPlugin, EditorViewWidgetPlugin,
CameraViewPlugin, CameraViewPlugin,
ViewerUiConfigPlugin, ViewerUiConfigPlugin,
FragmentClippingExtensionPlugin, FragmentClippingExtensionPlugin,
NoiseBumpMaterialPlugin, NoiseBumpMaterialPlugin,
CustomBumpMapPlugin, CustomBumpMapPlugin,
AnisotropyPlugin,
new ParallaxMappingPlugin(false), new ParallaxMappingPlugin(false),
GLTFKHRMaterialVariantsPlugin, GLTFKHRMaterialVariantsPlugin,
VirtualCamerasPlugin, VirtualCamerasPlugin,
// new SceneUiConfigPlugin(), // this is already in ViewerUiPlugin // new SceneUiConfigPlugin(), // this is already in ViewerUiPlugin
new GBufferPlugin(HalfFloatType, true, true, true),
new DepthBufferPlugin(HalfFloatType, false, false),
new NormalBufferPlugin(HalfFloatType, false),
new RenderTargetPreviewPlugin(false), new RenderTargetPreviewPlugin(false),
new FrameFadePlugin(), new FrameFadePlugin(),
new HDRiGroundPlugin(false, true), new HDRiGroundPlugin(false, true),
BloomPlugin, BloomPlugin,
TemporalAAPlugin, TemporalAAPlugin,
new VelocityBufferPlugin(UnsignedByteType, false), new VelocityBufferPlugin(UnsignedByteType, false),
new SSGIPlugin(UnsignedByteType, 1, false),
KTX2LoadPlugin, KTX2LoadPlugin,
KTXLoadPlugin, KTXLoadPlugin,
PLYLoadPlugin, PLYLoadPlugin,
editor.loadPlugins({ editor.loadPlugins({
['Viewer']: [ViewerUiConfigPlugin, DropzonePlugin, FullScreenPlugin, TweakpaneUiPlugin, LoadingScreenPlugin, InteractionPromptPlugin], ['Viewer']: [ViewerUiConfigPlugin, DropzonePlugin, FullScreenPlugin, TweakpaneUiPlugin, LoadingScreenPlugin, InteractionPromptPlugin],
['Scene']: [SSAAPlugin, BaseGroundPlugin, SceneUiConfigPlugin, ContactShadowGroundPlugin], ['Scene']: [SSAAPlugin, BaseGroundPlugin, SceneUiConfigPlugin, ContactShadowGroundPlugin],
['Interaction']: [HierarchyUiPlugin, TransformControlsPlugin, PickingPlugin, Object3DGeneratorPlugin, GeometryGeneratorPlugin, EditorViewWidgetPlugin, Object3DWidgetsPlugin, MeshOptSimplifyModifierPlugin],
['Interaction']: [HierarchyUiPlugin, TransformControlsPlugin, PickingPlugin, OutlinePlugin, Object3DGeneratorPlugin, GeometryGeneratorPlugin, EditorViewWidgetPlugin, Object3DWidgetsPlugin, MeshOptSimplifyModifierPlugin],
['GBuffer']: [GBufferPlugin, DepthBufferPlugin, NormalBufferPlugin], ['GBuffer']: [GBufferPlugin, DepthBufferPlugin, NormalBufferPlugin],
['Post-processing']: [TonemapPlugin, ProgressivePlugin, SSAOPlugin, SSReflectionPlugin, BloomPlugin, DepthOfFieldPlugin, FrameFadePlugin, VignettePlugin, ChromaticAberrationPlugin, FilmicGrainPlugin, TemporalAAPlugin, VelocityBufferPlugin, SSContactShadowsPlugin],
['Post-processing']: [TonemapPlugin, ProgressivePlugin, SSAOPlugin, SSReflectionPlugin, BloomPlugin, DepthOfFieldPlugin, SSGIPlugin, FrameFadePlugin, VignettePlugin, ChromaticAberrationPlugin, FilmicGrainPlugin, TemporalAAPlugin, VelocityBufferPlugin, SSContactShadowsPlugin],
['Export']: [AssetExporterPlugin, CanvasSnapshotPlugin, AWSClientPlugin, TransfrSharePlugin], ['Export']: [AssetExporterPlugin, CanvasSnapshotPlugin, AWSClientPlugin, TransfrSharePlugin],
['Configurator']: [MaterialConfiguratorPlugin, SwitchNodePlugin, GLTFKHRMaterialVariantsPlugin], ['Configurator']: [MaterialConfiguratorPlugin, SwitchNodePlugin, GLTFKHRMaterialVariantsPlugin],
['Animation']: [GLTFAnimationPlugin, CameraViewPlugin], ['Animation']: [GLTFAnimationPlugin, CameraViewPlugin],
['Extras']: [HDRiGroundPlugin, Rhino3dmLoadPlugin, ClearcoatTintPlugin, FragmentClippingExtensionPlugin, NoiseBumpMaterialPlugin, CustomBumpMapPlugin, VirtualCamerasPlugin],
['Extras']: [HDRiGroundPlugin, Rhino3dmLoadPlugin, ClearcoatTintPlugin, FragmentClippingExtensionPlugin, NoiseBumpMaterialPlugin, AnisotropyPlugin, CustomBumpMapPlugin, VirtualCamerasPlugin],
['Debug']: [RenderTargetPreviewPlugin], ['Debug']: [RenderTargetPreviewPlugin],
}) })



+ 44
- 2
package-lock.json Bestand weergeven

{ {
"name": "threepipe", "name": "threepipe",
"version": "0.0.36",
"version": "0.0.37",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "threepipe", "name": "threepipe",
"version": "0.0.36",
"version": "0.0.37",
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.153.1002/package.tgz", "@types/three": "https://github.com/repalash/three-ts-types/releases/download/v0.153.1002/package.tgz",
} }
} }
}, },
"../threepipe-webgi": {
"name": "@threepipe/webgi-plugins",
"version": "0.3.1",
"extraneous": true,
"license": "GPL-3.0-only",
"dependencies": {
"@threepipe/plugin-tweakpane": "^0.5.1",
"threepipe": "^0.0.36"
},
"devDependencies": {
"@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-replace": "^5.0.2",
"@typescript-eslint/eslint-plugin": "^5.59.7",
"@typescript-eslint/parser": "^5.59.5",
"clean-package": "^2.2.0",
"copyfiles": "^2.4.1",
"eslint": "^8.40.0",
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-deprecation": "^1.4.1",
"eslint-plugin-html": "^7.1.0",
"eslint-plugin-import": "^2.27.5",
"popmotion": "^11.0.5",
"rimraf": "^5.0.1",
"rollup-plugin-glsl": "^1.3.0",
"rollup-plugin-license": "^3.0.1",
"rollup-plugin-postcss": "^4.0.2",
"terser": "^5.31.6",
"ts-browser-helpers": "^0.16.2",
"tslib": "^2.5.0",
"typedoc": "^0.27.5",
"typescript": "^5.7.2",
"typescript-plugin-css-modules": "^5.0.1",
"vite": "^6.0.5",
"vite-plugin-dts": "^4.4.0",
"vitepress": "^1.5.0",
"vitepress-plugin-nprogress": "^0.0.4",
"vitepress-theme-api": "^0.1.7"
},
"optionalDependencies": {
"win-node-env": "^0.6.1"
}
},
"node_modules/@75lb/deep-merge": { "node_modules/@75lb/deep-merge": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.2.tgz", "resolved": "https://registry.npmjs.org/@75lb/deep-merge/-/deep-merge-1.1.2.tgz",

+ 1
- 1
package.json Bestand weergeven

{ {
"name": "threepipe", "name": "threepipe",
"version": "0.0.36",
"version": "0.0.37",
"description": "A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.", "description": "A 3D viewer framework built on top of three.js in TypeScript with a focus on quality rendering, modularity and extensibility.",
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/index.mjs", "module": "dist/index.mjs",

+ 1
- 1
src/plugins/extras/Object3DWidgetsPlugin.ts Bestand weergeven



onAdded(viewer: ThreeViewer) { onAdded(viewer: ThreeViewer) {
super.onAdded(viewer) super.onAdded(viewer)
viewer.scene.addEventListener('addSceneObject', this._addSceneObject)
viewer.scene.addObject(this._widgetRoot, {addToRoot: true, autoScale: false, autoCenter: false}) viewer.scene.addObject(this._widgetRoot, {addToRoot: true, autoScale: false, autoCenter: false})
viewer.scene.addEventListener('addSceneObject', this._addSceneObject)
} }
onRemove(viewer: ThreeViewer) { onRemove(viewer: ThreeViewer) {
viewer.scene.removeEventListener('addSceneObject', this._addSceneObject) viewer.scene.removeEventListener('addSceneObject', this._addSceneObject)

+ 4
- 0
src/plugins/pipeline/shaders/SSAOPlugin.pass.glsl Bestand weergeven

varying vec2 vUv; varying vec2 vUv;


uniform sampler2D tLastThis; uniform sampler2D tLastThis;

#ifndef D_frameCount
#define D_frameCount
uniform float frameCount; uniform float frameCount;
#endif


uniform vec4 saoData; uniform vec4 saoData;
uniform vec3 saoBiasEpsilon; uniform vec3 saoBiasEpsilon;

+ 1
- 0
src/plugins/ui/RenderTargetPreviewPlugin.ts Bestand weergeven

this._viewer.renderManager.blit(null, { this._viewer.renderManager.blit(null, {
source: tex, source: tex,
clear: !targetBlock.transparent, clear: !targetBlock.transparent,
// transparent: targetBlock.transparent, // todo
respectColorSpace: !targetBlock.originalColorSpace, respectColorSpace: !targetBlock.originalColorSpace,
viewport: new Vector4(rect.x, rect.y, rect.width, rect.height), viewport: new Vector4(rect.x, rect.y, rect.width, rect.height),
material: targetBlock.material, material: targetBlock.material,

+ 1
- 0
src/three/widgets/AHelperWidget.ts Bestand weergeven

this.matrix = object.matrixWorld this.matrix = object.matrixWorld
this.matrixAutoUpdate = false this.matrixAutoUpdate = false


this.dispose = this.dispose.bind(this)
this._objectUpdate = this._objectUpdate.bind(this) this._objectUpdate = this._objectUpdate.bind(this)
this.attach(object) this.attach(object)
this.traverse(o => { this.traverse(o => {

+ 8
- 3
src/viewer/ThreeViewer.ts Bestand weergeven

*/ */
forceZPrepass?: boolean // todo forceZPrepass?: boolean // todo


/*
/**
* Render scale, 1 = full resolution, 0.5 = half resolution, 2 = double resolution. * Render scale, 1 = full resolution, 0.5 = half resolution, 2 = double resolution.
* Same as pixelRatio in three.js * Same as pixelRatio in three.js
* Can be set to `window.devicePixelRatio` to render at device resolution in browsers. * Can be set to `window.devicePixelRatio` to render at device resolution in browsers.
* An optimal value is `Math.min(2, window.devicePixelRatio)` to prevent issues on mobile. This is set when 'auto' is passed. * An optimal value is `Math.min(2, window.devicePixelRatio)` to prevent issues on mobile. This is set when 'auto' is passed.
* Default is 1.
* @default 1
*/ */
renderScale?: number | 'auto' renderScale?: number | 'auto'
/**
* Max render scale when set to 'auto'
* @default 2
*/
maxRenderScale?: number


debug?: boolean debug?: boolean


depthBuffer: !(options.zPrepass ?? options.useGBufferDepth ?? false), depthBuffer: !(options.zPrepass ?? options.useGBufferDepth ?? false),
screenShader: options.screenShader, screenShader: options.screenShader,
renderScale: typeof options.renderScale === 'string' ? options.renderScale === 'auto' ? renderScale: typeof options.renderScale === 'string' ? options.renderScale === 'auto' ?
Math.min(2, window.devicePixelRatio) : parseFloat(options.renderScale) :
Math.min(options.maxRenderScale || 2, window.devicePixelRatio) : parseFloat(options.renderScale) :
options.renderScale, options.renderScale,
maxHDRIntensity: options.maxHDRIntensity, maxHDRIntensity: options.maxHDRIntensity,
}) })

+ 1
- 1
src/viewer/version.ts Bestand weergeven

export const VERSION = '0.0.35'
export const VERSION = '0.0.37'

Laden…
Annuleren
Opslaan