1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | 1× 1× 2× 2× 2× 2× 2× 2× 2× 2× 2× 2× 42× 1× 1× 1× 1× 1× 1× 6× 6× 6× 6× 6× 6× 6× 6× 6× 6× 6× 1× | import Base from '../core/Base'; import Vector3 from '../math/Vector3'; import PerspectiveCamera from '../camera/Perspective'; import FrameBuffer from '../FrameBuffer'; var targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz']; /** * Pass rendering scene to a environment cube map * * @constructor clay.prePass.EnvironmentMap * @extends clay.core.Base * @example * // Example of car reflection * var envMap = new clay.TextureCube({ * width: 256, * height: 256 * }); * var envPass = new clay.prePass.EnvironmentMap({ * position: car.position, * texture: envMap * }); * var carBody = car.getChildByName('body'); * carBody.material.enableTexture('environmentMap'); * carBody.material.set('environmentMap', envMap); * ... * animation.on('frame', function(frameTime) { * envPass.render(renderer, scene); * renderer.render(scene, camera); * }); */ var EnvironmentMapPass = Base.extend(function() { var ret = /** @lends clay.prePass.EnvironmentMap# */ { /** * Camera position * @type {clay.Vector3} * @memberOf clay.prePass.EnvironmentMap# */ position: new Vector3(), /** * Camera far plane * @type {number} * @memberOf clay.prePass.EnvironmentMap# */ far: 1000, /** * Camera near plane * @type {number} * @memberOf clay.prePass.EnvironmentMap# */ near: 0.1, /** * Environment cube map * @type {clay.TextureCube} * @memberOf clay.prePass.EnvironmentMap# */ texture: null, /** * Used if you wan't have shadow in environment map * @type {clay.prePass.ShadowMap} */ shadowMapPass: null, }; var cameras = ret._cameras = { px: new PerspectiveCamera({ fov: 90 }), nx: new PerspectiveCamera({ fov: 90 }), py: new PerspectiveCamera({ fov: 90 }), ny: new PerspectiveCamera({ fov: 90 }), pz: new PerspectiveCamera({ fov: 90 }), nz: new PerspectiveCamera({ fov: 90 }) }; cameras.px.lookAt(Vector3.POSITIVE_X, Vector3.NEGATIVE_Y); cameras.nx.lookAt(Vector3.NEGATIVE_X, Vector3.NEGATIVE_Y); cameras.py.lookAt(Vector3.POSITIVE_Y, Vector3.POSITIVE_Z); cameras.ny.lookAt(Vector3.NEGATIVE_Y, Vector3.NEGATIVE_Z); cameras.pz.lookAt(Vector3.POSITIVE_Z, Vector3.NEGATIVE_Y); cameras.nz.lookAt(Vector3.NEGATIVE_Z, Vector3.NEGATIVE_Y); // FIXME In windows, use one framebuffer only renders one side of cubemap ret._frameBuffer = new FrameBuffer(); return ret; }, /** @lends clay.prePass.EnvironmentMap# */ { /** * @param {string} target * @return {clay.Camera} */ getCamera: function (target) { return this._cameras[target]; }, /** * @param {clay.Renderer} renderer * @param {clay.Scene} scene * @param {boolean} [notUpdateScene=false] */ render: function(renderer, scene, notUpdateScene) { var _gl = renderer.gl; Eif (!notUpdateScene) { scene.update(); } // Tweak fov // http://the-witness.net/news/2012/02/seamless-cube-map-filtering/ var n = this.texture.width; var fov = 2 * Math.atan(n / (n - 0.5)) / Math.PI * 180; for (var i = 0; i < 6; i++) { var target = targets[i]; var camera = this._cameras[target]; Vector3.copy(camera.position, this.position); camera.far = this.far; camera.near = this.near; camera.fov = fov; Iif (this.shadowMapPass) { camera.update(); // update boundingBoxLastFrame var bbox = scene.getBoundingBox(); bbox.applyTransform(camera.viewMatrix); scene.viewBoundingBoxLastFrame.copy(bbox); this.shadowMapPass.render(renderer, scene, camera, true); } this._frameBuffer.attach( this.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i ); this._frameBuffer.bind(renderer); renderer.render(scene, camera, true); this._frameBuffer.unbind(renderer); } }, /** * @param {clay.Renderer} renderer */ dispose: function (renderer) { this._frameBuffer.dispose(renderer); } }); export default EnvironmentMapPass; |