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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user