UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

194 lines (191 loc) 6.12 kB
import { Color } from '../../core/math/color.js'; import { math } from '../../core/math/math.js'; import { PIXELFORMAT_111110F, PIXELFORMAT_RGBA16F, PIXELFORMAT_RGBA32F } from '../../platform/graphics/constants.js'; import { SSAOTYPE_NONE } from './constants.js'; import { CameraFrameOptions, RenderPassCameraFrame } from './render-pass-camera-frame.js'; class CameraFrame { constructor(app, cameraComponent){ this._enabled = true; this.rendering = { renderFormats: [ PIXELFORMAT_111110F, PIXELFORMAT_RGBA16F, PIXELFORMAT_RGBA32F ], stencil: false, renderTargetScale: 1.0, samples: 1, sceneColorMap: false, sceneDepthMap: false, toneMapping: 0, sharpness: 0.0 }; this.ssao = { type: SSAOTYPE_NONE, blurEnabled: true, randomize: false, intensity: 0.5, radius: 30, samples: 12, power: 6, minAngle: 10, scale: 1 }; this.bloom = { intensity: 0, blurLevel: 16 }; this.grading = { enabled: false, brightness: 1, contrast: 1, saturation: 1, tint: new Color(1, 1, 1, 1) }; this.colorLUT = { texture: null, intensity: 1 }; this.vignette = { intensity: 0, inner: 0.5, outer: 1, curvature: 0.5 }; this.taa = { enabled: false, jitter: 1 }; this.fringing = { intensity: 0 }; this.dof = { enabled: false, nearBlur: false, focusDistance: 100, focusRange: 10, blurRadius: 3, blurRings: 4, blurRingPoints: 5, highQuality: true }; this.debug = null; this.options = new CameraFrameOptions(); this.renderPassCamera = null; this.app = app; this.cameraComponent = cameraComponent; this.updateOptions(); this.enable(); this.cameraLayersChanged = cameraComponent.on('set:layers', ()=>{ if (this.renderPassCamera) this.renderPassCamera.layersDirty = true; }); } destroy() { this.disable(); this.cameraLayersChanged.off(); } enable() { this.renderPassCamera = this.createRenderPass(); this.cameraComponent.renderPasses = [ this.renderPassCamera ]; } disable() { const cameraComponent = this.cameraComponent; cameraComponent.renderPasses?.forEach((renderPass)=>{ renderPass.destroy(); }); cameraComponent.renderPasses = []; cameraComponent.rendering = null; cameraComponent.jitter = 0; cameraComponent.shaderParams.ssaoEnabled = false; this.renderPassCamera = null; } createRenderPass() { return new RenderPassCameraFrame(this.app, this, this.cameraComponent, this.options); } set enabled(value) { if (this._enabled !== value) { if (value) { this.enable(); } else { this.disable(); } this._enabled = value; } } get enabled() { return this._enabled; } updateOptions() { const { options, rendering, bloom, taa, ssao } = this; options.stencil = rendering.stencil; options.samples = rendering.samples; options.sceneColorMap = rendering.sceneColorMap; options.prepassEnabled = rendering.sceneDepthMap; options.bloomEnabled = bloom.intensity > 0; options.taaEnabled = taa.enabled; options.ssaoType = ssao.type; options.ssaoBlurEnabled = ssao.blurEnabled; options.formats = rendering.renderFormats.slice(); options.dofEnabled = this.dof.enabled; options.dofNearBlur = this.dof.nearBlur; options.dofHighQuality = this.dof.highQuality; } update() { if (!this._enabled) return; const cameraComponent = this.cameraComponent; const { options, renderPassCamera, rendering, bloom, grading, vignette, fringing, taa, ssao } = this; this.updateOptions(); renderPassCamera.update(options); const { composePass, bloomPass, ssaoPass, dofPass } = renderPassCamera; renderPassCamera.renderTargetScale = math.clamp(rendering.renderTargetScale, 0.1, 1); composePass.toneMapping = rendering.toneMapping; composePass.sharpness = rendering.sharpness; if (options.bloomEnabled && bloomPass) { composePass.bloomIntensity = bloom.intensity; bloomPass.blurLevel = bloom.blurLevel; } if (options.dofEnabled) { dofPass.focusDistance = this.dof.focusDistance; dofPass.focusRange = this.dof.focusRange; dofPass.blurRadius = this.dof.blurRadius; dofPass.blurRings = this.dof.blurRings; dofPass.blurRingPoints = this.dof.blurRingPoints; } if (options.ssaoType !== SSAOTYPE_NONE) { ssaoPass.intensity = ssao.intensity; ssaoPass.power = ssao.power; ssaoPass.radius = ssao.radius; ssaoPass.sampleCount = ssao.samples; ssaoPass.minAngle = ssao.minAngle; ssaoPass.scale = ssao.scale; ssaoPass.randomize = ssao.randomize; } composePass.gradingEnabled = grading.enabled; if (grading.enabled) { composePass.gradingSaturation = grading.saturation; composePass.gradingBrightness = grading.brightness; composePass.gradingContrast = grading.contrast; composePass.gradingTint = grading.tint; } composePass.colorLUT = this.colorLUT.texture; composePass.colorLUTIntensity = this.colorLUT.intensity; composePass.vignetteEnabled = vignette.intensity > 0; if (composePass.vignetteEnabled) { composePass.vignetteInner = vignette.inner; composePass.vignetteOuter = vignette.outer; composePass.vignetteCurvature = vignette.curvature; composePass.vignetteIntensity = vignette.intensity; } composePass.fringingEnabled = fringing.intensity > 0; if (composePass.fringingEnabled) { composePass.fringingIntensity = fringing.intensity; } cameraComponent.jitter = taa.enabled ? taa.jitter : 0; composePass.debug = this.debug; if (composePass.debug === 'ssao' && options.ssaoType === SSAOTYPE_NONE) composePass.debug = null; if (composePass.debug === 'vignette' && !composePass.vignetteEnabled) composePass.debug = null; } } export { CameraFrame };