UNPKG

@itwin/frontend-devtools

Version:

Debug menu and supporting UI widgets

110 lines (108 loc) 5.25 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Effects */ Object.defineProperty(exports, "__esModule", { value: true }); exports.LensDistortionConfig = exports.LensDistortionEffect = void 0; const core_bentley_1 = require("@itwin/core-bentley"); const core_frontend_1 = require("@itwin/core-frontend"); const EffectTools_1 = require("./EffectTools"); const parseArgs_1 = require("../tools/parseArgs"); /** Adds a screen-space effect to the selected [[Viewport]] to simulate the lens distortion produced by real-world cameras with very wide fields of view. * Based on https://www.decarpentier.nl/lens-distortion * The effect is improved considerably by enabling anti-aliasing (e.g., via [RenderSystem.Options.antialiasSamples]($frontend) at startup, or using the `fdt aasamples` key-in`). * @note Because this effect applies a non-linear transform to each pixel, operations like snapping to geometry will not work properly. Element locate will work however - @see [ScreenSpaceEffectSource.sampleSourcePixel]($frontend). * @beta */ class LensDistortionEffect extends EffectTools_1.AddEffectTool { static toolId = "LensDistortionEffect"; get effectName() { return "lensdistortion"; } get textureCoordFromPosition() { return true; } get source() { return { vertex: ` void effectMain(vec4 position) { vec2 uv = textureCoordFromPosition(position); float scaledHeight = strength * height; float cylAspectRatio = aspectRatio * cylindricalRatio; float aspectDiagSq = aspectRatio * aspectRatio + 1.0; float diagSq = scaledHeight * scaledHeight * aspectDiagSq; vec2 signedUV = (2.0 * uv + vec2(-1.0, -1.0)); float z = 0.5 * sqrt(diagSq + 1.0) + 0.5; float ny = (z - 1.0) / (cylAspectRatio * cylAspectRatio + 1.0); vUVDot = sqrt(ny) * vec2(cylAspectRatio, 1.0) * signedUV; vUV = vec3(0.5, 0.5, 1.0) * z + vec3(-0.5, -0.5, 0.0); vUV.xy += uv; }`, // We simply shift pixels - we don't alter their colors. fragment: ` vec4 effectMain() { return sampleSourcePixel(); }`, // Because we're moving pixels around, we must tell the render system where the source pixel was originally located - otherwise // element locate will not work correctly. sampleSourcePixel: ` vec3 uv = dot(vUVDot, vUVDot) * vec3(-0.5, -0.5, -1.0) + vUV; return TEXTURE_PROJ(u_diffuse, uv); `, }; } defineEffect(builder) { // Lens distortion is only applicable to views with the camera enabled. builder.shouldApply = (context) => context.viewport.isCameraOn; builder.addVarying("vUV", core_frontend_1.VaryingType.Vec3); builder.addVarying("vUVDot", core_frontend_1.VaryingType.Vec2); builder.addUniform({ name: "strength", type: core_frontend_1.UniformType.Float, bind: (uniform) => uniform.setUniform1f(LensDistortionConfig.strength), }); builder.addUniform({ name: "cylindricalRatio", type: core_frontend_1.UniformType.Float, bind: (uniform) => uniform.setUniform1f(LensDistortionConfig.cylindricalRatio), }); builder.addUniform({ name: "aspectRatio", type: core_frontend_1.UniformType.Float, bind: (uniform, context) => uniform.setUniform1f(context.viewport.viewRect.aspect), }); builder.addUniform({ name: "height", type: core_frontend_1.UniformType.Float, bind: (uniform, context) => { (0, core_bentley_1.assert)(context.viewport.view.is3d() && context.viewport.view.isCameraOn); const fov = context.viewport.view.camera.lens.radians; const height = Math.tan(fov / 2) / context.viewport.viewRect.aspect; uniform.setUniform1f(height); }, }); } } exports.LensDistortionEffect = LensDistortionEffect; /** Configures the [[LensDistortionEffect]]. * @beta */ class LensDistortionConfig extends core_frontend_1.Tool { static toolId = "LensDistortionConfig"; static get minArgs() { return 0; } static get maxArgs() { return 2; } static strength = 0.5; static cylindricalRatio = 0.5; async run(strength, ratio) { LensDistortionConfig.strength = strength ?? 0.5; LensDistortionConfig.cylindricalRatio = ratio ?? 0.5; (0, EffectTools_1.refreshViewportsForEffect)("fdt lensdistortion"); return true; } async parseAndRun(...input) { const args = (0, parseArgs_1.parseArgs)(input); return this.run(args.getFloat("s"), args.getFloat("r")); } } exports.LensDistortionConfig = LensDistortionConfig; //# sourceMappingURL=LensDistortion.js.map