1、离屏渲染
从Three.js的角度阐述,渲染结果的RGBA像素数据存储到了WebGL渲染目标对象WebGLRenderTarget中,通过目标对象的纹理属性.texture可以获得渲染结果的RGBA像素数据,也就是一个Three.js的纹理对象THREE.Texture,可以作为材质对象颜色贴图属性map的属性值;即将一个场景的渲染结果作为另一个场景中模型的纹理。
2、完整源代码
import { PerspectiveCamera, Scene, Mesh, WebGLRenderer, BoxGeometry, MeshLambertMaterial, PointLight, AmbientLight, WebGLRenderTarget } from 'three';
export class LearnShader {
private scene!: Scene;
private scene2!: Scene;
private camera!: PerspectiveCamera;
private camera2!: PerspectiveCamera;
private webGLRenderer!: WebGLRenderer;
private target!: WebGLRenderTarget;
constructor() {
// 场景1
this.scene = new Scene();
var geometry = new BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
var material = new MeshLambertMaterial({
color: 0xffffff
}); //材质对象Material
var mesh = new Mesh(geometry, material); //网格模型对象Mesh
this.scene.add(mesh); //网格模型添加到场景中
//点光源
var point = new PointLight(0xffffff);
point.position.set(400, 200, 300); //点光源位置
this.scene.add(point); //点光源添加到场景中
//环境光
var ambient = new AmbientLight(0x444444);
this.scene.add(ambient);
this.camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000);
this.camera.position.set(100, 100, 200);
this.camera.lookAt(this.scene.position);
// 创建一个webgl渲染目标对象webGLRenderTarget
// 设置渲染结果(一帧图像)的像素为500*500
this.target = new WebGLRenderTarget(500, 500);
// 场景2
this.scene2 = new Scene();
var geometry2 = new BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
var material2 = new MeshLambertMaterial({
map:this.target.texture
}); //材质对象Material
var mesh2 = new Mesh(geometry2, material2); //网格模型对象Mesh
this.scene2.add(mesh2); //网格模型添加到场景中
//点光源
var point2 = new PointLight(0xffffff);
point2.position.set(400, 200, 300); //点光源位置
this.scene2.add(point2); //点光源添加到场景中
//环境光
var ambient2 = new AmbientLight(0x444444);
this.scene2.add(ambient2);
this.camera2 = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000);
this.camera2.position.set(100, 100, 200);
this.camera2.lookAt(this.scene2.position);
// 渲染器
this.webGLRenderer = new WebGLRenderer({ antialias: true });
this.webGLRenderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(this.webGLRenderer.domElement);
this.render();
}
private render() {
window.requestAnimationFrame(() => this.render());
// 离屏场景
this.webGLRenderer.setClearColor(0xff0000); //离屏渲染对象的纹理颜色 如何不写的话默认和场景颜色一致
this.webGLRenderer.setRenderTarget(this.target); //将接下来的渲染( this.webGLRenderer.render(this.scene, this.camera))在离屏上进行
this.webGLRenderer.render(this.scene, this.camera);
// 主场景
this.webGLRenderer.setRenderTarget(null);//恢复正常渲染
this.webGLRenderer.setClearColor(0x00ff00);//背景颜色
this.webGLRenderer.render(this.scene2, this.camera2);
}
}