ThreeJS-off-screen rendering (thirty-five)

Off-screen rendering: In my understanding, two scenes A and B are rendered. If A is the main scene and B is the off-screen scene, the off-screen scene first caches the view rendering with the help of the main scene.

Code location:

      //off-screen rendering
      render.setClearColor(0x53868B);
      render.setRenderTarget(target);
      render.render(scene2, camera2);

Then switch back to the main scene, and render the perspective seen in the B scene to the main scene object in the form of a map texture

Code location:

    const meshMaterial = new THREE.MeshBasicMaterial({
        color: 0x8B8878,
        map: target.texture
    })

 render.setClearColor(0x6A5ACD);
      render.setRenderTarget(null);
      render.render(scene, camera);

logic:

The main scene is a plane, and the off-screen scene is a cube. Now the controller controls the off-screen scene camera, and renders the off-screen scene camera angle of view to the main scene plane. Therefore, the rendering we see below is not the effect produced by the main scene camera moving, but the effect produced by the off-screen camera change.

key code:

    //Create an orbit controller that can be dragged to control the camera
    const controls = new OrbitControls(camera2, render.domElement);
    //Set the control damping to make the controller have a more realistic effect
    controls.enableDamping = true;

Full code:

<template>
  <div id="three_div"></div>
</template>

<script>
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { RGBELoader } from "three/examples/jsm/loaders/RGBELoader";
import { Reflector } from "three/examples/jsm/objects/Reflector";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import gsap from "gsap";

export default {
  name: "HOME",
  components: {
    // vueQr,
    // glHome,
  },
  data() {
    return {};
  },
  mounted() {
 
    //1.离屏场景
    const scene2 = new THREE.Scene()
    const camera2 = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      20000
    );
    camera2.position.set(0, 0, 10);
    scene2.add(camera2);
    const meshGeometry2 = new THREE.BoxBufferGeometry(1, 1, 1);
    const meshMaterial2 = new THREE.MeshBasicMaterial({
        color: 0x8B7765,
        transparent: true,
        opacity: 0.4
    })
    const mesh2 = new THREE.Mesh(meshGeometry2, meshMaterial2);
    scene2.add(mesh2);
    const target = new THREE.WebGLRenderTarget(500, 500);
    

    
    //Main scene
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      20000
    );
    camera.position.set(0, 0, 10);
    scene.add(camera);
    const meshGeometry = new THREE.PlaneBufferGeometry(29,15); const meshMaterial = new
    THREE.MeshBasicMaterial({         color: 0x8B8878,         map: target.texture     })     const mesh = new THREE.Mesh(meshGeometry, meshMaterial);     scene.add(mesh);     //Initialize the renderer     const render = new THREE.WebGLRenderer({       //Set anti-aliasing, anti-distortion








      antialis: true,
      //对数深度缓冲区,防止模型闪烁
      logarithmicdepthbuffer: true,
    });
    /*设置场景渲染编码threejs将贴图的编码都默认设置为THREE.LinearEncoding,
     *导致图片色彩失真(色彩不像正常那么鲜艳,会灰蒙蒙的),所以务必将场景中的所有贴图的编码都调整为THREE.sRGBEncoding
     */
    render.outputEncoding = THREE.sRGBEncoding;
    //设置渲染器的尺寸
    render.setSize(window.innerWidth, window.innerHeight);
    //清除默认设置颜色
    render.setClearColor("#000");
    //设置曝光类型(电影类型、文本类型、游戏类型),电影类型
    render.toneMapping = THREE.ACESFilmicToneMapping;
    //曝光强度
    render.toneMappingExposure = 0.5;
    //开启物理灯光,使灯光效果更佳真实Correct(准确)
    render.physicallyCorrectLights = true;

    //Create an orbit controller that can be dragged, and controls the camera
    const controls = new OrbitControls(camera2, render.domElement);
    //Set control damping to make the controller have a more realistic effect
    controls.enableDamping = true;
    //Automatically rotate
    // controls.autoRotate = true;
    //Add the canvas content rendered by webgl to the body
    document.getElementById("three_ div").appendChild(render.domElement);

    //渲染下一帧的时候就会调用回调函数
    let renderFun = () => {
      //更新阻尼数据
      controls.update();
      //离屏渲染
      render.setClearColor(0x53868B);
      render.setRenderTarget(target);
      render.render(scene2, camera2);
      //需要重新绘制canvas画布.主场景
      render.setClearColor(0x6A5ACD);
      render.setRenderTarget(null);
      render.render(scene, camera);
      //监听屏幕刷新(60HZ,120HZ),每次刷新触发一次requestAnimationFrame回调函数
      //但是requestAnimationFrame的回调函数注册生命只有一次,因此需要循环注册,才能达到一直调用的效果
      window.requestAnimationFrame(renderFun);
    };
    // window.requestAnimationFrame(renderFun);
    renderFun();

    //画布全屏
    window.addEventListener("dblclick", () => {
      if (document.fullscreenElement) {
        document.exitFullscreen();
      } else {
        //document.documentElement.requestFullscreen();
        render.domElement.requestFullscreen();
      }
    });

    //Monitor screen changes, update the rendered screen, (adaptive size)
    window.addEventListener("resize", () => {       //Update the aspect ratio of the camera       camera.aspect = window.innerWidth / window.innerHeight;       //Update the projection matrix of the camera       camera.updateProjectionMatrix();       //Update the width and height of the renderer       render.setSize(window.innerWidth, window.inner Height);       //Set the pixel ratio of the renderer       render.setPixelRatio(window.devicePixelRatio);     });   },   methods: {}, }; </script>












<style scoped lang="scss">
* {
  margin: 0;
  padding: 0;
}

.home-content {
  position: fixed;
  top: 0;
  right: 20px;
}

.select-item-color {
  width: 50px;
  height: 50px;
  border: 1px solid #ccc;
  margin: 10px;
  display: inline-block;
  cursor: pointer;
  border-radius: 10px;
}
.select {
  display: flex;
}
</style>

Renderings:

Guess you like

Origin blog.csdn.net/sunboylife/article/details/130177563