| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- import * as THREE from "../../libs/three.js/build/three.module.js";
- import {PointCloudSM} from "../utils/PointCloudSM.js";
- import {EyeDomeLightingMaterial} from "../materials/EyeDomeLightingMaterial.js";
- import {SphereVolume} from "../utils/Volume.js";
- import {Utils} from "../utils.js";
- export class EDLRenderer{//old
- constructor(viewer){
- this.viewer = viewer;
- this.edlMaterial = null;
- this.rtRegular;
- this.rtEDL;
- this.gl = viewer.renderer.getContext();
- this.shadowMap = new PointCloudSM(this.viewer.pRenderer);
- }
- initEDL(){
- if (this.edlMaterial != null) {
- return;
- }
- this.edlMaterial = new EyeDomeLightingMaterial();
- this.edlMaterial.depthTest = true;
- this.edlMaterial.depthWrite = true;
- this.edlMaterial.transparent = true;
- this.rtEDL = new THREE.WebGLRenderTarget(1024, 1024, {
- minFilter: THREE.NearestFilter,
- magFilter: THREE.NearestFilter,
- format: THREE.RGBAFormat,
- type: THREE.FloatType,
- depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
- });
- this.rtRegular = new THREE.WebGLRenderTarget(1024, 1024, {
- minFilter: THREE.NearestFilter,
- magFilter: THREE.NearestFilter,
- format: THREE.RGBAFormat,
- depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
- });
- };
- resize(width, height){
- if(this.screenshot){
- width = this.screenshot.target.width;
- height = this.screenshot.target.height;
- }
- this.rtEDL.setSize(width , height);
- this.rtRegular.setSize(width , height);
- }
- makeScreenshot(camera, size, callback){
- if(camera === undefined || camera === null){
- camera = this.viewer.scene.getActiveCamera();
- }
- if(size === undefined || size === null){
- size = this.viewer.renderer.getSize(new THREE.Vector2());
- }
- let {width, height} = size;
- //let maxTextureSize = viewer.renderer.capabilities.maxTextureSize;
- //if(width * 4 <
- width = 2 * width;
- height = 2 * height;
- let target = new THREE.WebGLRenderTarget(width, height, {
- format: THREE.RGBAFormat,
- });
- this.screenshot = {
- target: target
- };
- // HACK? removed because of error, was this important?
- //this.viewer.renderer.clearTarget(target, true, true, true);
- this.render();
- let pixelCount = width * height;
- let buffer = new Uint8Array(4 * pixelCount);
- this.viewer.renderer.readRenderTargetPixels(target, 0, 0, width, height, buffer);
- // flip vertically
- let bytesPerLine = width * 4;
- for(let i = 0; i < parseInt(height / 2); i++){
- let j = height - i - 1;
- let lineI = buffer.slice(i * bytesPerLine, i * bytesPerLine + bytesPerLine);
- let lineJ = buffer.slice(j * bytesPerLine, j * bytesPerLine + bytesPerLine);
- buffer.set(lineJ, i * bytesPerLine);
- buffer.set(lineI, j * bytesPerLine);
- }
- this.screenshot.target.dispose();
- delete this.screenshot;
- return {
- width: width,
- height: height,
- buffer: buffer
- };
- }
- clearTargets(){
- const viewer = this.viewer;
- const {renderer} = viewer;
- const oldTarget = renderer.getRenderTarget();
- renderer.setRenderTarget( this.rtEDL );
- renderer.clear( true, true, true );
- renderer.setRenderTarget( this.rtRegular );
- renderer.clear( true, true, false );
- renderer.setRenderTarget(oldTarget);
- }
- clear(){
- this.initEDL();
- const viewer = this.viewer;
- const {renderer, background} = viewer;
- if(background === "skybox"){
- renderer.setClearColor(0x000000, 0);
- } else if (background === 'gradient') {
- renderer.setClearColor(0x000000, 0);
- } else if (background === 'black') {
- renderer.setClearColor(0x000000, 1);
- } else if (background === 'white') {
- renderer.setClearColor(0xFFFFFF, 1);
- } else {
- renderer.setClearColor(0x000000, 0);
- }
-
- renderer.clear();
- this.clearTargets();
- }
- renderShadowMap(visiblePointClouds, camera, lights){
- const {viewer} = this;
- const doShadows = lights.length > 0 && !(lights[0].disableShadowUpdates);
- if(doShadows){
- let light = lights[0];
- this.shadowMap.setLight(light);
- let originalAttributes = new Map();
- for(let pointcloud of viewer.scene.pointclouds){
- // TODO IMPORTANT !!! check
- originalAttributes.set(pointcloud, pointcloud.material.activeAttributeName);
- pointcloud.material.disableEvents();
- pointcloud.material.activeAttributeName = "depth";
- //pointcloud.material.pointColorType = PointColorType.DEPTH;
- }
- this.shadowMap.render(viewer.scene.scenePointCloud, camera);
- for(let pointcloud of visiblePointClouds){
- let originalAttribute = originalAttributes.get(pointcloud);
- // TODO IMPORTANT !!! check
- pointcloud.material.activeAttributeName = originalAttribute;
- pointcloud.material.enableEvents();
- }
- viewer.shadowTestCam.updateMatrixWorld();
- viewer.shadowTestCam.matrixWorldInverse.copy(viewer.shadowTestCam.matrixWorld).invert();
- viewer.shadowTestCam.updateProjectionMatrix();
- }
- }
- render(params){
- this.initEDL();
- const viewer = this.viewer;
- let camera = params.camera ? params.camera : viewer.scene.getActiveCamera();
- const {width, height} = this.viewer.renderer.getSize(new THREE.Vector2());
- viewer.dispatchEvent({type: "render.pass.begin",viewer: viewer});
-
- this.resize(width, height);
- const visiblePointClouds = viewer.scene.pointclouds.filter(pc => pc.visible);
- if(this.screenshot){
- let oldBudget = Potree.pointBudget;
- Potree.pointBudget = Math.max(10 * 1000 * 1000, 2 * oldBudget);
- let result = Potree.updatePointClouds(
- viewer.scene.pointclouds,
- camera,
- viewer.renderer);
- Potree.pointBudget = oldBudget;
- }
- let lights = [];
- viewer.scene.scene.traverse(node => {
- if(node.type === "SpotLight"){
- lights.push(node);
- }
- });
- if(viewer.background === "skybox"){
- viewer.skybox.camera.rotation.copy(viewer.scene.cameraP.rotation);
- viewer.skybox.camera.fov = viewer.scene.cameraP.fov;
- viewer.skybox.camera.aspect = viewer.scene.cameraP.aspect;
- viewer.skybox.parent.rotation.x = 0;
- viewer.skybox.parent.updateMatrixWorld();
- viewer.skybox.camera.updateProjectionMatrix();
- viewer.renderer.render(viewer.skybox.scene, viewer.skybox.camera);
- } else if (viewer.background === 'gradient') {
- viewer.renderer.render(viewer.scene.sceneBG, viewer.scene.cameraBG);
- }
- //TODO adapt to multiple lights
- this.renderShadowMap(visiblePointClouds, camera, lights);
- { // COLOR & DEPTH PASS
- for (let pointcloud of visiblePointClouds) {
- let octreeSize = pointcloud.pcoGeometry.boundingBox.getSize(new THREE.Vector3()).x;
- let material = pointcloud.material;
- material.weighted = false;
- material.useLogarithmicDepthBuffer = false;
- material.useEDL = true;
- material.screenWidth = width;
- material.screenHeight = height;
- material.uniforms.visibleNodes.value = pointcloud.material.visibleNodesTexture;
- material.uniforms.octreeSize.value = octreeSize;
- material.spacing = pointcloud.pcoGeometry.spacing; // * Math.max(pointcloud.scale.x, pointcloud.scale.y, pointcloud.scale.z);
- }
-
- // TODO adapt to multiple lights
- viewer.renderer.setRenderTarget(this.rtEDL);
-
- if(lights.length > 0){
- viewer.pRenderer.render(viewer.scene.scenePointCloud, camera, this.rtEDL, {
- clipSpheres: viewer.scene.volumes.filter(v => (v instanceof SphereVolume)),
- shadowMaps: [this.shadowMap],
- transparent: false,
- });
- }else{
-
- // let test = camera.clone();
- // test.matrixAutoUpdate = false;
- // //test.updateMatrixWorld = () => {};
- // let mat = new THREE.Matrix4().set(
- // 1, 0, 0, 0,
- // 0, 0, 1, 0,
- // 0, -1, 0, 0,
- // 0, 0, 0, 1,
- // );
- // mat.invert()
- // test.matrix.multiplyMatrices(mat, test.matrix);
- // test.updateMatrixWorld();
- //test.matrixWorld.multiplyMatrices(mat, test.matrixWorld);
- //test.matrixWorld.multiply(mat);
- //test.matrixWorldInverse.invert(test.matrixWorld);
- //test.matrixWorldInverse.multiplyMatrices(test.matrixWorldInverse, mat);
-
- viewer.pRenderer.render(viewer.scene.scenePointCloud, camera, this.rtEDL, {
- clipSpheres: viewer.scene.volumes.filter(v => (v instanceof SphereVolume)),
- transparent: false,
- });
- }
-
- }
- viewer.dispatchEvent({type: "render.pass.scene", viewer: viewer, renderTarget: this.rtRegular});
- viewer.renderer.setRenderTarget(null);
- viewer.renderer.render(viewer.scene.scene, camera);
- { // EDL PASS
- const uniforms = this.edlMaterial.uniforms;
- uniforms.screenWidth.value = width;
- uniforms.screenHeight.value = height;
- let proj = camera.projectionMatrix;
- let projArray = new Float32Array(16);
- projArray.set(proj.elements);
- uniforms.uNear.value = camera.near;
- uniforms.uFar.value = camera.far;
- uniforms.uEDLColor.value = this.rtEDL.texture;
- uniforms.uEDLDepth.value = this.rtEDL.depthTexture;
- uniforms.uProj.value = projArray;
- uniforms.edlStrength.value = viewer.edlStrength;
- uniforms.radius.value = viewer.edlRadius;
- uniforms.opacity.value = viewer.edlOpacity; // HACK
-
- Utils.screenPass.render(viewer.renderer, this.edlMaterial);
- if(this.screenshot){
- Utils.screenPass.render(viewer.renderer, this.edlMaterial, this.screenshot.target);
- }
- }
- viewer.dispatchEvent({type: "render.pass.scene", viewer: viewer});
- viewer.renderer.clearDepth();
- viewer.transformationTool.update();
- viewer.dispatchEvent({type: "render.pass.perspective_overlay",viewer: viewer});
- viewer.renderer.render(viewer.controls.sceneControls, camera);
- viewer.renderer.render(viewer.clippingTool.sceneVolume, camera);
- viewer.renderer.render(viewer.transformationTool.scene, camera);
-
- viewer.dispatchEvent({type: "render.pass.end",viewer: viewer});
- }
- }
|