827 Added RTE to points and point clouds. Fixed an issue with point coulds where if the object had a render material with a black diffuse color it would make all the point cloud black, regardless of the vertex colors.

This commit is contained in:
AlexandruPopovici
2022-08-10 14:33:20 +03:00
parent 24a2f20973
commit 03defca1a8
6 changed files with 200 additions and 74 deletions
+1 -4
View File
@@ -40,7 +40,4 @@ sandbox.makeGenericUI()
sandbox.makeSceneUI()
sandbox.makeFilteringUI()
// Load demo object
sandbox.loadUrl(
// 'https://speckle.xyz/streams/17b0b76d13/commits/1ba20ba64b?c=%5B700048.95339,5709850.71008,148.503,699898.46699,5710107.01323,-147.5969,0,1%5D'
'https://latest.speckle.dev/streams/444bfbd6e4/commits/ee4fcfba43'
)
sandbox.loadUrl('https://latest.speckle.dev/streams/ca0378725b/commits/e5a66562cc')
@@ -36,7 +36,7 @@ export default class Batcher {
...Array.from(new Set(rendeViews.map((value) => value.renderMaterialHash)))
]
// console.warn(materialHashes)
console.warn(materialHashes)
// console.warn(rendeViews)
for (let i = 0; i < materialHashes.length; i++) {
@@ -80,7 +80,7 @@ export default class Batcher {
this.batches[batchID].setBatchMaterial(material)
this.batches[batchID].buildBatch()
// console.warn(batch)
console.warn(batch)
}
}
@@ -6,6 +6,7 @@ import {
Points,
WebGLRenderer
} from 'three'
import { Geometry } from '../converter/Geometry'
import { NodeRenderView } from '../tree/NodeRenderView'
import { World } from '../World'
import { Batch, BatchUpdateRange, HideAllBatchUpdateRange } from './Batch'
@@ -190,7 +191,7 @@ export default class PointBatch implements Batch {
const attributeCount = this.renderViews.flatMap(
(val: NodeRenderView) => val.renderData.geometry.attributes.POSITION
).length
const position = new Float32Array(attributeCount)
const position = new Float64Array(attributeCount)
const color = new Float32Array(attributeCount).fill(1)
let offset = 0
for (let k = 0; k < this.renderViews.length; k++) {
@@ -221,11 +222,8 @@ export default class PointBatch implements Batch {
}
}
/**
* DUPLICATE from Geometry. Will unify in the future
*/
private makePointGeometry(
position: Float32Array,
position: Float64Array,
color: Float32Array
): BufferGeometry {
this.geometry = new BufferGeometry()
@@ -238,6 +236,7 @@ export default class PointBatch implements Batch {
this.geometry.computeBoundingBox()
World.expandWorld(this.geometry.boundingBox)
Geometry.updateRTEGeometry(this.geometry, position)
return this.geometry
}
@@ -134,30 +134,39 @@ export default class Materials {
;(<SpeckleLineMaterial>this.lineColoredMaterial).pixelThreshold = 0.5
;(<SpeckleLineMaterial>this.lineColoredMaterial).resolution = new Vector2()
this.pointCloudHighlightMaterial = new SpecklePointMaterial({
color: 0xff0000,
vertexColors: true,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
})
this.pointCloudHighlightMaterial = new SpecklePointMaterial(
{
color: 0xff0000,
vertexColors: true,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
},
['USE_RTE']
)
this.pointHighlightMaterial = new SpecklePointMaterial({
color: 0xff0000,
vertexColors: false,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
})
this.pointHighlightMaterial = new SpecklePointMaterial(
{
color: 0xff0000,
vertexColors: false,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
},
['USE_RTE']
)
this.pointGhostMaterial = new SpecklePointMaterial({
color: 0xffffff,
vertexColors: false,
size: 2,
opacity: 0.01,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
})
this.pointGhostMaterial = new SpecklePointMaterial(
{
color: 0xffffff,
vertexColors: false,
size: 2,
opacity: 0.01,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
},
['USE_RTE']
)
this.meshGhostMaterial = new SpeckleStandardMaterial(
{
@@ -265,29 +274,38 @@ export default class Materials {
;(<SpeckleLineMaterial>this.materialMap[hash]).pixelThreshold = 0.5
;(<SpeckleLineMaterial>this.materialMap[hash]).resolution = new Vector2()
this.materialMap[NodeRenderView.NullPointMaterialHash] = new SpecklePointMaterial({
color: 0x7f7f7f,
vertexColors: false,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
})
this.materialMap[NodeRenderView.NullPointCloudVertexColorsMaterialHash] =
new SpecklePointMaterial({
color: 0xffffff,
vertexColors: true,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
})
this.materialMap[NodeRenderView.NullPointCloudMaterialHash] =
new SpecklePointMaterial({
color: 0xffffff,
this.materialMap[NodeRenderView.NullPointMaterialHash] = new SpecklePointMaterial(
{
color: 0x7f7f7f,
vertexColors: false,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
})
},
['USE_RTE']
)
this.materialMap[NodeRenderView.NullPointCloudVertexColorsMaterialHash] =
new SpecklePointMaterial(
{
color: 0xffffff,
vertexColors: true,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
},
['USE_RTE']
)
this.materialMap[NodeRenderView.NullPointCloudMaterialHash] =
new SpecklePointMaterial(
{
color: 0xffffff,
vertexColors: false,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
},
['USE_RTE']
)
}
private makeMeshMaterial(materialData: RenderMaterial): Material {
@@ -330,14 +348,29 @@ export default class Materials {
}
private makePointMaterial(materialData: RenderMaterial): Material {
const mat = new SpecklePointMaterial({
color: materialData.color,
opacity: materialData.opacity,
vertexColors: false,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
})
/** There's an issue with how the data is being sent. Some point clouds
* have render materials with 0x000000 as the base color + vertex colors
* By default three.js modulates the base color with the vertex colors
* But since the base color is black, the result is also black. We'll have
* to avoid this
*/
const isBaseColorBlack = materialData.color === -16777216 // 0xff000000 (black)
const safeColor = materialData.vertexColors
? isBaseColorBlack
? 0xffffff
: materialData.color
: materialData.color
const mat = new SpecklePointMaterial(
{
color: safeColor,
opacity: materialData.opacity,
vertexColors: materialData.vertexColors,
size: 2,
sizeAttenuation: false
// clippingPlanes: this.viewer.sectionBox.planes
},
['USE_RTE']
)
mat.transparent = mat.opacity < 1 ? true : false
mat.depthWrite = mat.transparent ? false : true
mat.color.convertSRGBToLinear()
@@ -472,19 +505,25 @@ export default class Materials {
return mat
}
case GeometryType.POINT:
return new SpecklePointMaterial({
color,
vertexColors: false,
size: 2,
sizeAttenuation: false
})
return new SpecklePointMaterial(
{
color,
vertexColors: false,
size: 2,
sizeAttenuation: false
},
['USE_RTE']
)
case GeometryType.POINT_CLOUD:
return new SpecklePointMaterial({
color,
vertexColors: true,
size: 2,
sizeAttenuation: false
})
return new SpecklePointMaterial(
{
color,
vertexColors: true,
size: 2,
sizeAttenuation: false
},
['USE_RTE']
)
}
}
@@ -1,16 +1,42 @@
/* eslint-disable camelcase */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { specklePointVert } from './shaders/speckle-point-vert'
import { specklePointFrag } from './shaders/speckle-point-frag'
import { PointsMaterial } from 'three'
import { Matrix4, PointsMaterial, ShaderLib, UniformsUtils, Vector3 } from 'three'
import { Geometry } from '../converter/Geometry'
class SpecklePointMaterial extends PointsMaterial {
private static readonly matBuff: Matrix4 = new Matrix4()
private static readonly vecBuff0: Vector3 = new Vector3()
private static readonly vecBuff1: Vector3 = new Vector3()
private static readonly vecBuff2: Vector3 = new Vector3()
constructor(parameters, defines = []) {
super(parameters)
this.userData.uViewer_high = {
value: new Vector3()
}
this.userData.uViewer_low = {
value: new Vector3()
}
;(this as any).vertProgram = specklePointVert
;(this as any).fragProgram = specklePointFrag
;(this as any).uniforms = UniformsUtils.merge([
ShaderLib.standard.uniforms,
{
uViewer_high: {
value: this.userData.uViewer_high.value
},
uViewer_low: {
value: this.userData.uViewer_low.value
}
}
])
this.onBeforeCompile = function (shader) {
shader.uniforms.uViewer_high = this.userData.uViewer_high
shader.uniforms.uViewer_low = this.userData.uViewer_low
shader.vertexShader = this.vertProgram
shader.fragmentShader = this.fragProgram
}
@@ -26,8 +52,43 @@ class SpecklePointMaterial extends PointsMaterial {
copy(source) {
super.copy(source)
this.userData = {}
this.userData.uViewer_high = {
value: new Vector3()
}
this.userData.uViewer_low = {
value: new Vector3()
}
this.defines['USE_RTE'] = ' '
return this
}
onBeforeRender(_this, scene, camera, geometry, object, group) {
SpecklePointMaterial.matBuff.copy(camera.matrixWorldInverse)
SpecklePointMaterial.matBuff.elements[12] = 0
SpecklePointMaterial.matBuff.elements[13] = 0
SpecklePointMaterial.matBuff.elements[14] = 0
SpecklePointMaterial.matBuff.multiply(object.matrixWorld)
object.modelViewMatrix.copy(SpecklePointMaterial.matBuff)
SpecklePointMaterial.vecBuff0.set(
camera.matrixWorld.elements[12],
camera.matrixWorld.elements[13],
camera.matrixWorld.elements[14]
)
Geometry.DoubleToHighLowVector(
SpecklePointMaterial.vecBuff0,
SpecklePointMaterial.vecBuff1,
SpecklePointMaterial.vecBuff2
)
this.userData.uViewer_low.value.copy(SpecklePointMaterial.vecBuff1)
this.userData.uViewer_high.value.copy(SpecklePointMaterial.vecBuff2)
this.needsUpdate = true
}
}
export default SpecklePointMaterial
@@ -9,13 +9,43 @@ uniform float scale;
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
#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
void main() {
#include <color_vertex>
#include <morphcolor_vertex>
#include <begin_vertex>
#include <morphtarget_vertex>
#include <project_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;
gl_PointSize = size;