UNPKG

@itwin/core-frontend

Version:
158 lines 6.71 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 { Vector3d } from "@itwin/core-geometry"; import { BatchUniforms } from "./BatchUniforms"; import { BranchUniforms } from "./BranchUniforms"; import { FrustumUniforms } from "./FrustumUniforms"; import { HiliteUniforms } from "./HiliteUniforms"; import { LightingUniforms } from "./LightingUniforms"; import { ShadowUniforms } from "./ShadowUniforms"; import { StyleUniforms } from "./StyleUniforms"; import { desync, sync } from "./Sync"; import { ThematicUniforms } from "./ThematicUniforms"; import { ViewRectUniforms } from "./ViewRectUniforms"; import { RealityModelUniforms } from "./RealityModelUniforms"; import { AtmosphereUniforms } from "./AtmosphereUniforms"; import { ContourUniforms } from "./ContourUniforms"; class PixelWidthFactor { /** The pixel width factor depends on both the frustum and the view rect. It also depends on the frustum scale associated with the current Branch. */ _rectSync = {}; _frustumSync = {}; _branchSync = {}; _factor = 0; syncKey = 0; bind(uniform, uniforms) { if (!sync(uniforms.frustum, this._frustumSync) || !sync(uniforms.viewRect, this._rectSync) || !sync(uniforms.branch, this._branchSync)) this.compute(uniforms.frustum, uniforms.viewRect.width, uniforms.viewRect.height, uniforms.branch.top.frustumScale); if (!sync(this, uniform)) uniform.setUniform1f(this._factor); } compute(frustumUniforms, width, height, scale) { desync(this); const frustumPlanes = frustumUniforms.planes; const top = frustumPlanes[0]; const bottom = frustumPlanes[1]; const left = frustumPlanes[2]; const right = frustumPlanes[3]; let halfPixelWidth; let halfPixelHeight; const frustum = frustumUniforms.frustum; if (2 /* FrustumUniformType.Perspective */ === frustumUniforms.type) { const inverseNear = 1.0 / frustum[0]; const tanTheta = top * inverseNear; halfPixelHeight = scale.x * tanTheta / height; halfPixelWidth = scale.y * tanTheta / width; } else { halfPixelWidth = scale.x * 0.5 * (right - left) / width; halfPixelHeight = scale.y * 0.5 * (top - bottom) / height; } this._factor = Math.sqrt(halfPixelWidth * halfPixelWidth + halfPixelHeight * halfPixelHeight); } } // Direction in view space used if solar shadows are disabled and LightSettings.useSolarLighting is false. const defaultSunDirectionView = new Vector3d(0.272166, 0.680414, 0.680414); class SunDirection { // Sun direction is passed to shader in view coords so depends upon frustum. syncToken; syncKey = 0; _haveWorldDir = false; _worldDir = Vector3d.unitZ(); _viewDir = defaultSunDirectionView.clone(); _viewDir32 = new Float32Array(3); _updated = true; update(sunDir) { const haveWorldDir = undefined !== sunDir; if (haveWorldDir !== this._haveWorldDir || (sunDir && !sunDir.isExactEqual(this._worldDir))) { this._updated = true; desync(this); this._haveWorldDir = haveWorldDir; if (sunDir) { sunDir.clone(this._worldDir); this._worldDir.normalizeInPlace(); } } } bind(uniform, uniforms) { if (!sync(uniforms.frustum, this) || this._updated) { if (this._haveWorldDir) { uniforms.frustum.viewMatrix.multiplyVector(this._worldDir, this._viewDir); this._viewDir.negate(this._viewDir); } else { defaultSunDirectionView.clone(this._viewDir); } this._viewDir.normalizeInPlace(); this._viewDir32[0] = this._viewDir.x; this._viewDir32[1] = this._viewDir.y; this._viewDir32[2] = this._viewDir.z; desync(this); this._updated = false; } if (!sync(this, uniform)) uniform.setUniform3fv(this._viewDir32); } } /** Holds state for commonly-used uniforms to avoid unnecessary recomputation, owned by a Target. * DO NOT directly modify exposed members of the objects exposed by this class. Use their APIs. * e.g., code like `target.uniforms.frustum.projectionMatrix.setFrom(someOtherMatrix)` or `target.uniforms.branch.top.setViewFlags(blah)` will cause bugs. * @internal */ export class TargetUniforms { frustum; viewRect = new ViewRectUniforms(); hilite = new HiliteUniforms(); style = new StyleUniforms(); lights = new LightingUniforms(); thematic = new ThematicUniforms(); contours = new ContourUniforms(); branch; batch; shadow; realityModel = new RealityModelUniforms(); atmosphere = new AtmosphereUniforms(); _pixelWidthFactor = new PixelWidthFactor(); _sunDirection = new SunDirection(); constructor(target) { this.frustum = new FrustumUniforms(); this.branch = new BranchUniforms(target); this.batch = new BatchUniforms(target, this.branch.createBatchState()); this.shadow = new ShadowUniforms(target); } getProjectionMatrix(forViewCoords) { return forViewCoords ? this.viewRect.projectionMatrix : this.frustum.projectionMatrix; } getProjectionMatrix32(forViewCoords) { return forViewCoords ? this.viewRect.projectionMatrix32 : this.frustum.projectionMatrix32; } bindProjectionMatrix(uniform, forViewCoords) { if (forViewCoords) this.viewRect.bindProjectionMatrix(uniform); else this.frustum.bindProjectionMatrix(uniform); } bindPixelWidthFactor(uniform) { this._pixelWidthFactor.bind(uniform, this); } bindSunDirection(uniform) { this._sunDirection.bind(uniform, this); } updateRenderPlan(plan) { this.style.update(plan); this.hilite.update(plan.hiliteSettings, plan.emphasisSettings); let sunDir; if (plan.lights) { this.lights.update(plan.lights); const useSunDir = plan.viewFlags.shadows || plan.lights.solar.alwaysEnabled; if (useSunDir) sunDir = plan.lights.solar.direction; } this._sunDirection.update(sunDir); } } //# sourceMappingURL=TargetUniforms.js.map