UNPKG

@itwin/core-frontend

Version:
108 lines (105 loc) 4.77 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module WebGL */ import { assert } from "@itwin/core-bentley"; import { AttributeMap } from "../AttributeMap"; import { ProgramBuilder } from "../ShaderBuilder"; import { addUniformHiliter } from "./FeatureSymbology"; import { addColorPlanarClassifier, addFeaturePlanarClassifier, addHilitePlanarClassifier } from "./PlanarClassification"; import { addModelViewProjectionMatrix } from "./Vertex"; import { addViewportTransformation } from "./Viewport"; import { addThematicDisplay } from "./Thematic"; import { addTexture } from "./Surface"; import { assignFragColor } from "./Fragment"; // Revert components if color format is BGR instead of RGB. const computeColor = ` return u_pointCloud.y == 1.0 ? vec4(a_color.b, a_color.g, a_color.r, 1.0) : vec4(a_color, 1.0); `; const computeBaseColor = "return v_color;"; // Round the point unless drawing square points. const roundPointDiscard = ` if (u_pointCloudSettings.w == 1.0) return false; vec2 pointXY = (2.0 * gl_PointCoord - 1.0); return dot(pointXY, pointXY) > 1.0; `; const checkForClassifiedDiscard = "return baseColor.a == 0.0;"; const computePosition = ` gl_PointSize = 1.0; vec4 pos = MAT_MVP * rawPos; if (u_pointCloudSettings.x > 0.0) { // Size is specified in pixels. gl_PointSize = u_pointCloudSettings.x; return pos; } // Point size is in meters (voxel size). if (pos.w <= 0.0) { // Cannot perform perspective divide below. return pos; } // Convert voxel size in meters into pixel size, then compute pixel size, taking perspective into account. mat4 toView = u_viewportTransformation * MAT_MVP; float scale = length(toView[0].xyz); gl_PointSize = -u_pointCloudSettings.x * clamp(u_pointCloud.x * scale / pos.w, u_pointCloudSettings.y, u_pointCloudSettings.z); return pos; `; function createBuilder() { const builder = new ProgramBuilder(AttributeMap.findAttributeMap(2 /* TechniqueId.PointCloud */, false)); const vert = builder.vert; addViewportTransformation(vert); vert.set(10 /* VertexShaderComponent.ComputePosition */, computePosition); addModelViewProjectionMatrix(vert); builder.frag.set(0 /* FragmentShaderComponent.CheckForEarlyDiscard */, roundPointDiscard); // Uniforms based on the PointCloudDisplaySettings. builder.addUniform("u_pointCloudSettings", 5 /* VariableType.Vec4 */, (prog) => { prog.addGraphicUniform("u_pointCloudSettings", (uniform, params) => { params.target.uniforms.realityModel.pointCloud.bind(uniform); }); }); // Uniforms based on the PointCloudGeometry. builder.vert.addUniform("u_pointCloud", 3 /* VariableType.Vec2 */, (prog) => { prog.addGraphicUniform("u_pointCloud", (uniform, params) => { assert(params.geometry.asPointCloud !== undefined); scratchPointCloud[0] = params.geometry.asPointCloud.voxelSize; scratchPointCloud[1] = params.geometry.asPointCloud.colorIsBgr ? 1 : 0; uniform.setUniform2fv(scratchPointCloud); }); }); return builder; } const scratchPointCloud = new Float32Array([0, 0]); /** @internal */ export function createPointCloudBuilder(classified, featureMode, thematic) { const builder = createBuilder(); builder.addVarying("v_color", 5 /* VariableType.Vec4 */); builder.vert.set(5 /* VertexShaderComponent.ComputeBaseColor */, computeColor); builder.frag.set(1 /* FragmentShaderComponent.ComputeBaseColor */, computeBaseColor); if (classified) { addColorPlanarClassifier(builder, false, thematic); builder.frag.set(4 /* FragmentShaderComponent.CheckForDiscard */, checkForClassifiedDiscard); if (0 /* FeatureMode.None */ !== featureMode) addFeaturePlanarClassifier(builder); } if (1 /* IsThematic.Yes */ === thematic) { addThematicDisplay(builder, true); addTexture(builder, 0 /* IsAnimated.No */, 1 /* IsThematic.Yes */, true, false, false); } return builder; } /** @internal */ export function createPointCloudHiliter(classified) { const builder = createBuilder(); if (classified) { addHilitePlanarClassifier(builder, false); builder.frag.set(18 /* FragmentShaderComponent.AssignFragData */, assignFragColor); } else { addUniformHiliter(builder); } return builder; } //# sourceMappingURL=PointCloud.js.map