Fixed #987 and an additonal issue with null clipping planes

#987
This commit is contained in:
AlexandruPopovici
2022-09-08 12:53:34 +03:00
parent d7142b344d
commit b99a4afb18
7 changed files with 164 additions and 20 deletions
@@ -126,7 +126,7 @@ export default class SpeckleRenderer {
this._renderer.toneMappingExposure = 0.5
this.renderer.shadowMap.enabled = true
this.renderer.shadowMap.type = VSMShadowMap
this.renderer.shadowMap.autoUpdate = true
this.renderer.shadowMap.autoUpdate = false
this.renderer.shadowMap.needsUpdate = true
this.renderer.physicallyCorrectLights = true
@@ -277,7 +277,7 @@ export default class SpeckleRenderer {
{
depthPacking: RGBADepthPacking
},
['USE_RTE']
['USE_RTE', 'ALPHATEST_REJECTION']
)
}
})
@@ -327,6 +327,7 @@ export default class SpeckleRenderer {
}
}
})
this.renderer.shadowMap.needsUpdate = true
}
private addDirectLights() {
@@ -8,7 +8,7 @@ import { NodeRenderView } from '../tree/NodeRenderView'
import { Batch, BatchUpdateRange, GeometryType, HideAllBatchUpdateRange } from './Batch'
import PointBatch from './PointBatch'
// import { FilterMaterialType } from '../FilteringManager'
import { WebGLRenderer } from 'three'
import { Material, WebGLRenderer } from 'three'
import { FilterMaterial, FilterMaterialType } from '../filtering/FilteringManager'
export default class Batcher {
@@ -157,7 +157,10 @@ export default class Batcher {
return {
offset: rv.batchStart,
count: rv.batchCount,
material: this.materials.getFilterMaterial(rv, filterMaterial.filterType),
material: this.materials.getFilterMaterial(
rv,
filterMaterial.filterType
) as Material,
materialOptions: this.materials.getFilterMaterialOptions(filterMaterial)
} as BatchUpdateRange
})
@@ -132,6 +132,7 @@ export default class Materials {
['USE_RTE']
)
this.meshGhostMaterial.depthWrite = false
this.meshGhostMaterial.alphaTest = 1
this.meshGradientMaterial = new SpeckleStandardColoredMaterial(
{
@@ -196,7 +197,8 @@ export default class Materials {
emissive: 0x0,
roughness: 1,
metalness: 0,
side: DoubleSide // TBD
side: DoubleSide // TBD,
// clippingPlanes: []
},
['USE_RTE']
)
@@ -563,6 +565,10 @@ export default class Materials {
break
}
}
/** There's a bug in three.js where it checks for the length of the planes without checking if they exist first
* It's been allegedly fixed in a later version but until we update we'll just assing an empty array
*/
this.materialMap[hash].clippingPlanes = []
return this.materialMap[hash]
}
@@ -712,21 +718,33 @@ export default class Materials {
public getFilterMaterial(
renderView: NodeRenderView,
filterMaterial: FilterMaterialType
) {
): Material {
let retMaterial: Material
switch (filterMaterial) {
case FilterMaterialType.SELECT:
return this.getHighlightMaterial(renderView)
retMaterial = this.getHighlightMaterial(renderView)
break
case FilterMaterialType.GHOST:
return this.getGhostMaterial(renderView)
retMaterial = this.getGhostMaterial(renderView)
break
case FilterMaterialType.GRADIENT:
return this.getGradientMaterial(renderView)
retMaterial = this.getGradientMaterial(renderView)
break
case FilterMaterialType.COLORED:
return this.getColoredMaterial(renderView)
retMaterial = this.getColoredMaterial(renderView)
break
case FilterMaterialType.OVERLAY:
return this.getOverlayMaterial(renderView)
retMaterial = this.getOverlayMaterial(renderView)
break
case FilterMaterialType.HIDDEN:
return this.getHiddenMaterial(renderView)
retMaterial = this.getHiddenMaterial(renderView)
break
}
/** There's a bug in three.js where it checks for the length of the planes without checking if they exist first
* It's been allegedly fixed in a later version but until we update we'll just assing an empty array
*/
retMaterial.clippingPlanes = []
return retMaterial
}
public getFilterMaterialOptions(filterMaterial: FilterMaterial) {
@@ -2,8 +2,8 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable camelcase */
import { Matrix4, ShaderLib, UniformsUtils, Vector3 } from 'three'
import { speckleBasicVert } from './shaders/speckle-basic-vert'
import { speckleBasicFrag } from './shaders/speckle-basic-frag'
import { speckleGhostVert } from './shaders/speckle-ghost-vert'
import { speckleGhostFrag } from './shaders/speckle-ghost-frag'
import SpeckleBasicMaterial from './SpeckleBasicMaterial'
class SpeckleGhostMaterial extends SpeckleBasicMaterial {
@@ -15,8 +15,8 @@ class SpeckleGhostMaterial extends SpeckleBasicMaterial {
this.userData.uViewer_low = {
value: new Vector3()
}
;(this as any).vertProgram = speckleBasicVert
;(this as any).fragProgram = speckleBasicFrag
;(this as any).vertProgram = speckleGhostVert
;(this as any).fragProgram = speckleGhostFrag
;(this as any).uniforms = UniformsUtils.merge([
ShaderLib.standard.uniforms,
{
@@ -42,8 +42,6 @@ class SpeckleGhostMaterial extends SpeckleBasicMaterial {
for (let k = 0; k < defines.length; k++) {
this.defines[defines[k]] = ' '
}
this.defines['NO_SHADOWS'] = ''
}
}
@@ -19,10 +19,17 @@ void main() {
#endif
#include <map_fragment>
#include <alphamap_fragment>
#include <alphatest_fragment>
// #include <alphatest_fragment>
#ifdef USE_ALPHATEST
if ( diffuseColor.a < alphaTest ) discard;
/** This is a workaround for rejecting shadows for certain materials, since three.js gave me no choice*/
#ifdef ALPHATEST_REJECTION
if (alphaTest > 0. ) discard;
#endif
#endif
#include <logdepthbuf_fragment>
// Higher precision equivalent of gl_FragCoord.z. This assumes depthRange has been left to its default values.
float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;
float fragCoordZ = (0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5);
#if DEPTH_PACKING == 3200
gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );
#elif DEPTH_PACKING == 3201
@@ -0,0 +1,54 @@
export const speckleGhostFrag = /* glsl */ `
uniform vec3 diffuse;
uniform float opacity;
#ifndef FLAT_SHADED
varying vec3 vNormal;
#endif
#include <common>
#include <dithering_pars_fragment>
#include <color_pars_fragment>
#include <uv_pars_fragment>
#include <uv2_pars_fragment>
#include <map_pars_fragment>
#include <alphamap_pars_fragment>
#include <alphatest_pars_fragment>
#include <aomap_pars_fragment>
#include <lightmap_pars_fragment>
#include <envmap_common_pars_fragment>
#include <envmap_pars_fragment>
#include <cube_uv_reflection_fragment>
#include <fog_pars_fragment>
#include <specularmap_pars_fragment>
#include <logdepthbuf_pars_fragment>
#include <clipping_planes_pars_fragment>
void main() {
#include <clipping_planes_fragment>
vec4 diffuseColor = vec4( diffuse, opacity );
#include <logdepthbuf_fragment>
#include <map_fragment>
#include <color_fragment>
#include <alphamap_fragment>
// We're disabling alpha testing because we need to use it for shadow rejection. Three.js gave me no choice
// #include <alphatest_fragment>
#include <specularmap_fragment>
ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );
// accumulation (baked indirect lighting only)
#ifdef USE_LIGHTMAP
vec4 lightMapTexel = texture2D( lightMap, vUv2 );
reflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;
#else
reflectedLight.indirectDiffuse += vec3( 1.0 );
#endif
// modulation
#include <aomap_fragment>
reflectedLight.indirectDiffuse *= diffuseColor.rgb;
vec3 outgoingLight = reflectedLight.indirectDiffuse;
#include <envmap_fragment>
#include <output_fragment>
#include <tonemapping_fragment>
#include <encodings_fragment>
#include <fog_fragment>
#include <premultiplied_alpha_fragment>
#include <dithering_fragment>
}
`
@@ -0,0 +1,63 @@
export const speckleGhostVert = /* glsl */ `
#include <common>
#ifdef USE_RTE
// The high component is stored as the default 'position' attribute buffer
attribute vec3 position_low;
uniform vec3 uViewer_high;
uniform vec3 uViewer_low;
#endif
#include <uv_pars_vertex>
#include <uv2_pars_vertex>
#include <envmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
#include <uv_vertex>
#include <uv2_vertex>
#include <color_vertex>
#include <morphcolor_vertex>
#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )
#include <beginnormal_vertex>
#include <morphnormal_vertex>
#include <skinbase_vertex>
#include <skinnormal_vertex>
#include <defaultnormal_vertex>
#endif
#include <begin_vertex>
#include <morphtarget_vertex>
#include <skinning_vertex>
// #include <project_vertex> COMMENTED CHUNK
#ifdef USE_RTE
/*
Source https://github.com/virtualglobebook/OpenGlobe/blob/master/Source/Examples/Chapter05/Jitter/GPURelativeToEyeDSFUN90/Shaders/VS.glsl
Note here, we're storing the high part of the position encoding inside three's default 'position' attribute buffer so we avoid redundancy
*/
vec3 t1 = position_low.xyz - uViewer_low;
vec3 e = t1 - position_low.xyz;
vec3 t2 = ((-uViewer_low - e) + (position_low.xyz - (t1 - e))) + position.xyz - uViewer_high;
vec3 highDifference = t1 + t2;
vec3 lowDifference = t2 - (highDifference - t1);
vec4 mvPosition = vec4(highDifference.xyz + lowDifference.xyz , 1.);
#else
vec4 mvPosition = vec4( transformed, 1.0 );
#endif
#ifdef USE_INSTANCING
mvPosition = instanceMatrix * mvPosition;
#endif
mvPosition = modelViewMatrix * mvPosition;
gl_Position = projectionMatrix * mvPosition;
#include <logdepthbuf_vertex>
#include <clipping_planes_vertex>
#include <worldpos_vertex>
#include <envmap_vertex>
#include <fog_vertex>
}
`