face selection via shader, not multimat colors
This commit is contained in:
parent
df90158cb0
commit
da42c146bd
|
|
@ -12,8 +12,42 @@ export class SceneSync {
|
|||
|
||||
private _selectedFaceIds: Id[] = [];
|
||||
|
||||
private readonly baseMaterial = new THREE.MeshPhongMaterial({
|
||||
color: 0x4a7fc8, shininess: 40, specular: 0x223344, wireframe: false,
|
||||
private readonly baseMaterial = new THREE.ShaderMaterial({
|
||||
side: THREE.DoubleSide,
|
||||
transparent: true,
|
||||
depthWrite: false,
|
||||
uniforms: {
|
||||
frontColor: { value: new THREE.Color(0x88ccff) },
|
||||
frontOpacity: { value: 0.6 },
|
||||
backColor: { value: new THREE.Color(0xcc88ff) },
|
||||
backOpacity: { value: 0.2 },
|
||||
selected: { value: 0 },
|
||||
selectedOpacity: { value: 0.8 },
|
||||
},
|
||||
vertexShader: `
|
||||
varying vec3 vNormal;
|
||||
attribute float selected;
|
||||
varying float vSelected;
|
||||
void main() {
|
||||
vNormal = normalMatrix * normal;
|
||||
vSelected = selected;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||
}
|
||||
`,
|
||||
fragmentShader: `
|
||||
uniform vec3 frontColor;
|
||||
uniform float frontOpacity;
|
||||
uniform vec3 backColor;
|
||||
uniform float backOpacity;
|
||||
uniform float selectedOpacity;
|
||||
varying float vSelected;
|
||||
varying vec3 vNormal;
|
||||
void main() {
|
||||
float opacity = vSelected > 0.5 ? selectedOpacity : (gl_FrontFacing ? frontOpacity : backOpacity);
|
||||
vec3 color = gl_FrontFacing ? frontColor : backColor;
|
||||
gl_FragColor = vec4(color, opacity);
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
constructor(scene: THREE.Scene, cache: GeometryCache) {
|
||||
|
|
@ -53,7 +87,9 @@ export class SceneSync {
|
|||
return;
|
||||
|
||||
const geo = this.cache.getOrCreate(faceId, 0, dto);
|
||||
const mesh = new THREE.Mesh(geo, this.baseMaterial.clone());
|
||||
const geoVCount = geo.attributes.position.count;
|
||||
geo.setAttribute('selected', new THREE.BufferAttribute(new Float32Array(geoVCount), 1));
|
||||
const mesh = new THREE.Mesh(geo, this.baseMaterial);
|
||||
mesh.userData.faceId = faceId;
|
||||
mesh.userData.vertexIds = dto.vertexIds;
|
||||
mesh.userData.surfaceId = dto.surfaceId;
|
||||
|
|
@ -67,16 +103,9 @@ export class SceneSync {
|
|||
this._selectedFaceIds = faceIds;
|
||||
|
||||
for (const [sid, mesh] of Object.entries(this.meshByFace)) {
|
||||
const mat = mesh.material as THREE.MeshPhongMaterial;
|
||||
|
||||
if (faceIds.includes(sid)) {
|
||||
mat.color.setHex(0xf0a040);
|
||||
mat.emissive.setHex(0x221100);
|
||||
}
|
||||
else {
|
||||
mat.color.setHex(0x4a7fc8);
|
||||
mat.emissive.setHex(0x000000);
|
||||
}
|
||||
const attr = mesh.geometry.attributes.selected;
|
||||
attr.array.fill(faceIds.includes(sid) ? 1.0 : 0.0);
|
||||
attr.needsUpdate = true; // required!
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue