UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

127 lines (126 loc) 4.41 kB
"use strict"; import { WebGLRenderTarget, NearestFilter, RGBAFormat, FloatType, WebGLRenderer, Scene, NoToneMapping, NoColorSpace, DepthTexture, UnsignedInt248Type } from "three"; import { coreGetDefaultCamera } from "./CoreGetDefautCamera"; import { setupDepthReadScene, updateDepthSetup } from "./DepthRead"; export function coreCursorToUv(cursor, target) { target.x = 0.5 * (cursor.x + 1); target.y = 0.5 * (1 - cursor.y); } function _createDepthTexture() { const texture = new DepthTexture(1, 1); texture.type = UnsignedInt248Type; return texture; } export class RenderPixelController { constructor() { // Note for this to work on iOS: // The materials used for picking should have their transparency OFF. // This could potentially be done automatically by traversing the scene first. this._colorWriteRenderTarget = new WebGLRenderTarget(1, 1, { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat, type: FloatType, colorSpace: NoColorSpace, depthTexture: _createDepthTexture() }); this._depthReadRenderTarget = new WebGLRenderTarget(1, 1, { minFilter: NearestFilter, magFilter: NearestFilter, format: RGBAFormat, type: FloatType, colorSpace: NoColorSpace }); this._renderScene = new Scene(); this._depthReadSetup = setupDepthReadScene(); this._restoreContext = { object: { parent: null }, // scene: { // overrideMaterial: null, // }, renderer: { toneMapping: NoToneMapping, outputColorSpace: NoColorSpace } }; this._read = new Float32Array(4); } renderColor(scene, object3D, material, camera, backgroundColor, uv, target) { this._doRender(scene, object3D, camera, material, backgroundColor, uv, target, false); return target; } renderDepth(scene, object3D, camera, backgroundColor, uv, target) { this._doRender(scene, object3D, camera, null, backgroundColor, uv, target, true); return target; } _doRender(scene, object3D, camera, material, backgroundColor, uv, target, renderDepth) { const renderer = scene.renderersRegister.lastRegisteredRenderer(); if (!renderer) { return target; } if (!(renderer instanceof WebGLRenderer)) { console.log("renderPixel: renderer found is not WebGLRenderer"); return target; } if (camera == null) { camera = coreGetDefaultCamera(scene); } this._prepare(object3D, material, backgroundColor, renderer); this._render(uv, camera, renderer, target, renderDepth); this._restore(object3D, renderer); return target; } _prepare(object3D, material, backgroundColor, renderer) { this._restoreContext.renderer.outputColorSpace = renderer.outputColorSpace; this._restoreContext.renderer.toneMapping = renderer.toneMapping; this._restoreContext.object.parent = object3D.parent; this._renderScene.background = backgroundColor; this._renderScene.overrideMaterial = material || null; this._renderScene.attach(object3D); renderer.toneMapping = NoToneMapping; renderer.outputColorSpace = NoColorSpace; } _render(uv, camera, renderer, target, readDepth) { camera.setViewOffset( renderer.domElement.width, renderer.domElement.height, uv.x * renderer.domElement.width, uv.y * renderer.domElement.height, 1, 1 ); renderer.setRenderTarget(this._colorWriteRenderTarget); renderer.clear(); renderer.render(this._renderScene, camera); if (readDepth) { updateDepthSetup(this._depthReadSetup, camera, this._colorWriteRenderTarget); renderer.setRenderTarget(this._depthReadRenderTarget); renderer.render(this._depthReadSetup.scene, this._depthReadSetup.camera); renderer.readRenderTargetPixels(this._depthReadRenderTarget, 0, 0, 1, 1, this._read); } else { renderer.readRenderTargetPixels(this._colorWriteRenderTarget, 0, 0, 1, 1, this._read); } renderer.setRenderTarget(null); camera.clearViewOffset(); target.fromArray(this._read); } _restore(object3D, renderer) { var _a; renderer.outputColorSpace = this._restoreContext.renderer.outputColorSpace; renderer.toneMapping = this._restoreContext.renderer.toneMapping; (_a = this._restoreContext.object.parent) == null ? void 0 : _a.attach(object3D); } }