// TODO Should not derived from mesh?
import Mesh from '../Mesh';
import CubeGeometry from '../geometry/Cube';
import Shader from '../Shader';
import Material from '../Material';
import skyboxEssl from '../shader/source/skybox.glsl.js';
Shader.import(skyboxEssl);
/**
* @constructor clay.plugin.Skybox
*
* @example
* var skyTex = new clay.TextureCube();
* skyTex.load({
* 'px': 'assets/textures/sky/px.jpg',
* 'nx': 'assets/textures/sky/nx.jpg'
* 'py': 'assets/textures/sky/py.jpg'
* 'ny': 'assets/textures/sky/ny.jpg'
* 'pz': 'assets/textures/sky/pz.jpg'
* 'nz': 'assets/textures/sky/nz.jpg'
* });
* var skybox = new clay.plugin.Skybox({
* scene: scene
* });
* skybox.material.set('environmentMap', skyTex);
*/
var Skybox = Mesh.extend(function () {
var skyboxShader = new Shader({
vertex: Shader.source('clay.skybox.vertex'),
fragment: Shader.source('clay.skybox.fragment')
});
var material = new Material({
shader: skyboxShader,
depthMask: false
});
return {
/**
* @type {clay.Scene}
* @memberOf clay.plugin.Skybox.prototype
*/
scene: null,
geometry: new CubeGeometry(),
material: material,
environmentMap: null,
culling: false
};
}, function () {
var scene = this.scene;
Eif (scene) {
this.attachScene(scene);
}
Iif (this.environmentMap) {
this.setEnvironmentMap(this.environmentMap);
}
}, /** @lends clay.plugin.Skybox# */ {
/**
* Attach the skybox to the scene
* @param {clay.Scene} scene
*/
attachScene: function (scene) {
Eif (this.scene) {
this.detachScene();
}
scene.skybox = this;
this.scene = scene;
scene.on('beforerender', this._beforeRenderScene, this);
},
/**
* Detach from scene
*/
detachScene: function () {
Eif (this.scene) {
this.scene.off('beforerender', this._beforeRenderScene);
this.scene.skybox = null;
}
this.scene = null;
},
/**
* Dispose skybox
* @param {clay.Renderer} renderer
*/
dispose: function (renderer) {
this.detachScene();
this.geometry.dispose(renderer);
},
/**
* Set environment map
* @param {clay.TextureCube} envMap
*/
setEnvironmentMap: function (envMap) {
this.material.set('environmentMap', envMap);
},
/**
* Get environment map
* @return {clay.TextureCube}
*/
getEnvironmentMap: function () {
return this.material.get('environmentMap');
},
_beforeRenderScene: function(renderer, scene, camera) {
this.renderSkybox(renderer, camera);
},
renderSkybox: function (renderer, camera) {
this.position.copy(camera.getWorldPosition());
this.update();
// Don't remember to disable blend
renderer.gl.disable(renderer.gl.BLEND);
Iif (this.material.get('lod') > 0) {
this.material.define('fragment', 'LOD');
}
else {
this.material.undefine('fragment', 'LOD');
}
renderer.renderPass([this], camera);
}
});
export default Skybox;
|