xr lens layer wip

This commit is contained in:
Leon van Kammen 2023-11-25 12:40:38 +01:00
parent 2262168c3e
commit 99ea791adb
5 changed files with 40 additions and 38 deletions

Binary file not shown.

View File

@ -24,7 +24,6 @@ xrf.patchRenderer = function(opts){
renderer.render = ((render) => function(scene,camera){ renderer.render = ((render) => function(scene,camera){
// update clock // update clock
let time = xrf.clock.getDelta() let time = xrf.clock.getDelta()
// allow entities to do stuff during render (onBeforeRender and onAfterRender don't always fire)
xrf.emit('render',{scene,camera,time,render}) // allow fragments to do something at renderframe xrf.emit('render',{scene,camera,time,render}) // allow fragments to do something at renderframe
render(scene,camera) render(scene,camera)
xrf.emit('renderPost',{scene,camera,time,render,renderer}) // allow fragments to do something after renderframe xrf.emit('renderPost',{scene,camera,time,render,renderer}) // allow fragments to do something after renderframe

View File

@ -60,7 +60,6 @@ xrf.filter.process = function(frag,scene,opts){
const setVisible = (n,visible,filter,processed) => { const setVisible = (n,visible,filter,processed) => {
if( processed && processed[n.uuid] ) return if( processed && processed[n.uuid] ) return
getOrCloneMaterial(n).visible = visible getOrCloneMaterial(n).visible = visible
console.log(n.name+" => "+(visible?"show":"hide"))
if( filter.deep ) n.traverse( (m) => getOrCloneMaterial(m).visible = visible ) if( filter.deep ) n.traverse( (m) => getOrCloneMaterial(m).visible = visible )
if( processed ) processed[n.uuid] == true if( processed ) processed[n.uuid] == true
} }

View File

@ -20,8 +20,11 @@ xrf.frag.src.addModel = (model,url,frag,opts) => {
if( mesh.material ) mesh.material.visible = false // hide placeholder object if( mesh.material ) mesh.material.visible = false // hide placeholder object
//enableSourcePortation(scene) //enableSourcePortation(scene)
if( xrf.frag.src.renderAsPortal(mesh) ){ if( xrf.frag.src.renderAsPortal(mesh) ){
if( !opts.isLocal ) xrf.scene.add(scene) // only add remote objects, because
return xrf.portalNonEuclidian({...opts,model,scene:model.scene}) // local scene-objects are already added to scene
xrf.portalNonEuclidian({...opts,model,scene:model.scene})
if( !opts.isLocal && !mesh.portal.isLens ) xrf.scene.add(scene)
return
}else{ }else{
xrf.frag.src.scale( scene, opts, url ) // scale scene xrf.frag.src.scale( scene, opts, url ) // scale scene
mesh.add(scene) mesh.add(scene)

View File

@ -3,7 +3,6 @@
xrf.portalNonEuclidian = function(opts){ xrf.portalNonEuclidian = function(opts){
let { frag, mesh, model, camera, scene, renderer} = opts let { frag, mesh, model, camera, scene, renderer} = opts
mesh.portal = { mesh.portal = {
pos: mesh.position.clone(), pos: mesh.position.clone(),
posWorld: new xrf.THREE.Vector3(), posWorld: new xrf.THREE.Vector3(),
@ -13,18 +12,22 @@ xrf.portalNonEuclidian = function(opts){
stencilObject: false, stencilObject: false,
cameraDirection: new THREE.Vector3(), cameraDirection: new THREE.Vector3(),
cameraPosition: new THREE.Vector3(), cameraPosition: new THREE.Vector3(),
raycaster: new THREE.Raycaster() raycaster: new THREE.Raycaster(),
isLocal: opts.isLocal,
isLens: false
} }
// allow objects to flip between original and stencil position (which puts them behind stencilplane) // allow objects to flip between original and stencil position (which puts them behind stencilplane)
const addStencilFeature = (n) => { const addStencilFeature = (n) => {
if( n.stencil ) return n // run once if( n.stencil ) return n // run once
n.stencil = ( (pos,scale) => (sRef,newPos, newScale) => { n.stencil = ( (pos,scale) => (sRef,newPos, newScale) => {
n.position.copy( sRef == 0 ? pos : newPos ) if( !mesh.portal.isLens ){
if( sRef > 0 ) n.scale.multiply( newScale ) n.position.copy( sRef == 0 ? pos : newPos )
else n.scale.copy( scale ) if( sRef > 0 ) n.scale.multiply( newScale )
else n.scale.copy( scale )
n.updateMatrixWorld(true)
}
xrf.portalNonEuclidian.selectStencil(n, sRef ) xrf.portalNonEuclidian.selectStencil(n, sRef )
n.updateMatrixWorld(true)
} }
)( n.position.clone(), n.scale.clone() ) )( n.position.clone(), n.scale.clone() )
return n return n
@ -32,14 +35,22 @@ xrf.portalNonEuclidian = function(opts){
this.setupStencilObjects = (scene,opts) => { this.setupStencilObjects = (scene,opts) => {
// collect related objects to render inside stencilplane // collect related objects to render inside stencilplane
let stencilObject = opts.srcFrag.target ? scene.getObjectByName( opts.srcFrag.target.key ) : scene // strip # let stencilObject = scene
if( opts.srcFrag.target ){
stencilObject = scene.getObjectByName( opts.srcFrag.target.key )
// scan if object is child of portal (then project lens)
mesh.traverse( (n) => n.name == opts.srcFrag.target.key && (stencilObject = n) && (mesh.portal.isLens = true) )
}
if( !stencilObject ) return console.warn(`no objects were found (src:${mesh.userData.src}) for (portal)object name '${mesh.name}'`) if( !stencilObject ) return console.warn(`no objects were found (src:${mesh.userData.src}) for (portal)object name '${mesh.name}'`)
if( !opts.isLocal ) stencilObject.visible = false mesh.portal.stencilObject = stencilObject
let stencilObjects = [mesh,stencilObject]
// spec: if src points to child, act as lens
if( !mesh.portal.isLocal || mesh.portal.isLens ) stencilObject.visible = false
let stencilObjects = [stencilObject]
stencilObjects = stencilObjects stencilObjects = stencilObjects
.filter( (n) => !n.portal ) // filter out (self)references to portals (prevent recursion) .filter( (n) => !n.portal ) // filter out (self)references to portals (prevent recursion)
.map(addStencilFeature) .map(addStencilFeature)
mesh.portal.stencilObject = stencilObject
//// add missing lights to make sure things get lit properly //// add missing lights to make sure things get lit properly
xrf.scene.traverse( (n) => n.isLight && xrf.scene.traverse( (n) => n.isLight &&
@ -70,16 +81,8 @@ xrf.portalNonEuclidian = function(opts){
this.setupListeners = () => { this.setupListeners = () => {
mesh.onBeforeRender = function(renderer, scene, camera, geometry, material, group ){
}
mesh.onAfterRender = function(renderer, scene, camera, geometry, material, group ){ mesh.onAfterRender = function(renderer, scene, camera, geometry, material, group ){
mesh.portal.needUpdate = true if( mesh.portal && mesh.portal.stencilObjects ){
}
xrf.addEventListener('renderPost', (opts) => {
if( mesh.portal && mesh.portal.needUpdate && mesh.portal.stencilObjects ){
let {scene,camera,time,render} = opts
let stencilRef = mesh.portal.stencilRef let stencilRef = mesh.portal.stencilRef
let newPos = mesh.portal.posWorld let newPos = mesh.portal.posWorld
let stencilObject = mesh.portal.stencilObject let stencilObject = mesh.portal.stencilObject
@ -89,15 +92,14 @@ xrf.portalNonEuclidian = function(opts){
let raycaster = mesh.portal.raycaster let raycaster = mesh.portal.raycaster
// init // init
if( !opts.isLocal ) stencilObject.visible = true if( !mesh.portal.isLocal || mesh.portal.isLens ) stencilObject.visible = true
mesh.portal.stencilObjects.traverse( (n) => showPortal(n,false) && n.stencil && n.stencil(stencilRef,newPos,newScale) ) mesh.portal.stencilObjects.traverse( (n) => showPortal(n,false) && n.stencil && n.stencil(stencilRef,newPos,newScale) )
renderer.autoClear = false renderer.autoClear = false
renderer.clearDepth()
// render // render
render( mesh.portal.stencilObjects, camera ) renderer.render( mesh.portal.stencilObjects, camera )
// de-init // de-init
mesh.portal.stencilObjects.traverse( (n) => showPortal(n,true) && n.stencil && (n.stencil(0)) ) mesh.portal.stencilObjects.traverse( (n) => showPortal(n,true) && n.stencil && (n.stencil(0)) )
if( !opts.isLocal ) stencilObject.visible = false if( !mesh.portal.isLocal || mesh.portal.isLens ) stencilObject.visible = false
// trigger href upon camera collide // trigger href upon camera collide
@ -114,10 +116,8 @@ xrf.portalNonEuclidian = function(opts){
setTimeout( () => mesh.portal.teleporting = false, 500) // dont flip back and forth setTimeout( () => mesh.portal.teleporting = false, 500) // dont flip back and forth
} }
} }
mesh.portal.needUpdate = false
} }
}) }
return this return this
} }
@ -126,6 +126,7 @@ xrf.portalNonEuclidian = function(opts){
.portalNonEuclidian .portalNonEuclidian
.setMaterial(mesh) .setMaterial(mesh)
.getWorldPosition(mesh.portal.posWorld) .getWorldPosition(mesh.portal.posWorld)
mesh.portal.posWorld.y +=0.2
this this
.setupListeners() .setupListeners()
@ -143,23 +144,23 @@ xrf.portalNonEuclidian.selectStencil = (n, stencilRef, nested) => {
} }
xrf.portalNonEuclidian.setMaterial = function(mesh){ xrf.portalNonEuclidian.setMaterial = function(mesh){
mesh.material = new xrf.THREE.MeshBasicMaterial({ color: 'white' }); mesh.material = new xrf.THREE.MeshBasicMaterial({ color: 'orange' });
mesh.material.depthWrite = false; mesh.material.depthWrite = false;
mesh.material.depthTest = false;
mesh.material.colorWrite = false; mesh.material.colorWrite = false;
mesh.material.stencilWrite = true; mesh.material.stencilWrite = true;
mesh.material.stencilRef = xrf.portalNonEuclidian.stencilRef; mesh.material.stencilRef = xrf.portalNonEuclidian.stencilRef;
mesh.renderOrder = 0;//xrf.portalNonEuclidian.stencilRef; mesh.renderOrder = 10;//xrf.portalNonEuclidian.stencilRef;
mesh.material.stencilFunc = THREE.AlwaysStencilFunc; mesh.material.stencilFunc = xrf.THREE.AlwaysStencilFunc;
mesh.material.stencilZPass = THREE.ReplaceStencilOp; mesh.material.stencilZPass = xrf.THREE.ReplaceStencilOp;
//mesh.material.stencilFail = THREE.ReplaceStencilOp; mesh.material.stencilZFail = xrf.THREE.ReplaceStencilOp;
//mesh.material.stencilZFail = THREE.ReplaceStencilOp; //n.material.depthFunc = stencilRef > 0 ? xrf.THREE.AlwaysDepth : xrf.THREE.LessEqualDepth
//mesh.material.depthTest = false;
return mesh return mesh
} }
xrf.addEventListener('parseModel',(opts) => { xrf.addEventListener('parseModel',(opts) => {
const scene = opts.model.scene const scene = opts.model.scene
scene.traverse( (n) => n.renderOrder = 10 ) // rendering everything *after* the stencil buffers scene.traverse( (n) => n.renderOrder = 0 ) // rendering everything *after* the stencil buffers
}) })