浅谈Three.js源码-render之WebGLBackground.js

来源:互联网 发布:网络流行词大全 编辑:程序博客网 时间:2024/05/29 17:58
/** * @author mrdoob / http://mrdoob.com/ */import { BackSide } from '../../constants';import { OrthographicCamera } from '../../cameras/OrthographicCamera';import { PerspectiveCamera } from '../../cameras/PerspectiveCamera';import { BoxBufferGeometry } from '../../geometries/BoxGeometry';import { PlaneBufferGeometry } from '../../geometries/PlaneGeometry';import { MeshBasicMaterial } from '../../materials/MeshBasicMaterial';import { ShaderMaterial } from '../../materials/ShaderMaterial';import { Color } from '../../math/Color';import { Mesh } from '../../objects/Mesh';import { ShaderLib } from '../shaders/ShaderLib';//WebGLBackground为渲染场景的背景,用户可以将其设置为// 1.带有透明度的颜色(R,G,B,A)。// 2.天空盒贴图。// 3.正方形贴图。function WebGLBackground( renderer, state, objects, premultipliedAlpha ) {   var clearColor = new Color( 0x000000 );    //创建一个颜色对象,代表WebGL中的背景颜色   var clearAlpha = 0;                      //默认的不透明度   var planeCamera, planeMesh;   var boxCamera, boxMesh;   function render( scene, camera, forceClear ) {      /*下面是scene中background在官方文档中的解释:If not null, sets the background used when rendering the scene, and is always rendered first.      Can be set to a Color which sets the clear color, a Texture covering the canvas, or a CubeTexture. Default is null.       翻译一下:如果scene的background不为null,则在渲染场景时用来设置背景,并且通常是第一个被绘制。       (渲染顺序通常为,先远后近,注意,是通常。这里涉及到WebGL中的遮挡问题,以后再细细讲吧)       */      var background = scene.background;    //得到scene对象中的background对象      if ( background === null ) {         //如果用户没有进行对background的设置,则直接将背景设置为默认的颜色         setClear( clearColor, clearAlpha );      } else if ( background && background.isColor ) {//如果用户将background为一种颜色,则将北京设置为对应颜色,并强制刷新         setClear( background, 1 );         forceClear = true;      }      if ( renderer.autoClear || forceClear ) {//如果开启了renderer的自动刷新,或者程序检测到了需要强制刷新         renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );//清除了颜色缓冲、深度缓冲、模板缓冲      }      if ( background && background.isCubeTexture ) {//如果背景是一个天空盒(贴图的正方体)         if ( boxCamera === undefined ) {      //如果boxCamera为null,则进行创建,并新建一个小正方体的网格对象,用来贴背景图            boxCamera = new PerspectiveCamera();            boxMesh = new Mesh(               new BoxBufferGeometry( 5, 5, 5 ),               new ShaderMaterial( {                  uniforms: ShaderLib.cube.uniforms,                  vertexShader: ShaderLib.cube.vertexShader,                  fragmentShader: ShaderLib.cube.fragmentShader,                  side: BackSide,                  depthTest: false,                  depthWrite: false,                  fog: false               } )            );         }         boxCamera.projectionMatrix.copy( camera.projectionMatrix );//获取当前场景中摄像机的投影矩阵         boxCamera.matrixWorld.extractRotation( camera.matrixWorld );//获取当前场景中摄像机的旋转矩阵 并赋值给boxCamera         boxCamera.matrixWorldInverse.getInverse( boxCamera.matrixWorld ); //得到摄像机在世界坐标系下的逆矩阵         boxMesh.material.uniforms[ "tCube" ].value = background;//将背景图以uniforms的方式传入渲染管线中         boxMesh.modelViewMatrix.multiplyMatrices( boxCamera.matrixWorldInverse, boxMesh.matrixWorld );//?????         objects.update( boxMesh );//更新网格对象(因为修改了网格对象的材质,所以需要将传入的图片传入渲染管线中)                              //camera, fog, geometry, material, object, group         renderer.renderBufferDirect( boxCamera, null, boxMesh.geometry, boxMesh.material, boxMesh, null );         //Render a buffer geometry group using the camera and with the specified material.         //(根据字面翻译就是:使用摄像机和指定的材质,对几何对象缓存进行渲染)      } else if ( background && background.isTexture ) {//如果背景图是一张贴在正方体上的一张图片         if ( planeCamera === undefined ) {            planeCamera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );//创建一个正交投影摄像机            planeMesh = new Mesh(                             //创建一个正方形网格对象               new PlaneBufferGeometry( 2, 2 ),               new MeshBasicMaterial( { depthTest: false, depthWrite: false, fog: false } )            );         }         planeMesh.material.map = background;         //将传入的图片作为网格对象的贴图         objects.update( planeMesh );               //更新网格对象(因为修改了网格对象的材质,所以需要将传入的图片传入渲染管线中)         renderer.renderBufferDirect( planeCamera, null, planeMesh.geometry, planeMesh.material, planeMesh, null );      }   }   function setClear( color, alpha ) {      state.buffers.color.setClear( color.r, color.g, color.b, alpha, premultipliedAlpha );   }   return {      getClearColor: function () {//得到当前背景颜色         return clearColor;      },      setClearColor: function ( color, alpha ) {//设置当前背景颜色         clearColor.set( color );         clearAlpha = alpha !== undefined ? alpha : 1;         setClear( clearColor, clearAlpha );      },      getClearAlpha: function () {//设置当前背景透明度         return clearAlpha;      },      setClearAlpha: function ( alpha ) {//设置当前背景透明度         clearAlpha = alpha;         setClear( clearColor, clearAlpha );      },      render: render   };}export { WebGLBackground };