recomputeViewports: function() { var numViews = this._shadowMaps.length; var viewDivideY = numViews > 2 ? Math.sqrt(2 * Math.ceil(numViews / 2)) : numViews; var viewDivideX = viewDivideY; var mapSizeX = this._textureSize / viewDivideX; var mapSizeY = this._textureSize / viewDivideY; var numShadowWidth = this._textureSize / mapSizeX; var numShadowHeight = this._textureSize / mapSizeY; for (var i = 0; i < numViews; i++) { var shadowMap = this._shadowMaps[i]; var x = mapSizeX * (i % numShadowWidth); var y = mapSizeY * Math.floor(i / numShadowHeight); if (this._viewportDimension.length <= i) { this._viewportDimension.push(vec4.fromValues(x, y, mapSizeX, mapSizeY)); } else { vec4.set(this._viewportDimension[i], x, y, mapSizeX, mapSizeY); } this._texture.setLightShadowMapSize( this._lights[i].getLightNumber(), this._viewportDimension[i] ); shadowMap.dirty(); } },
return function(W, P, M) { // Where W = viewport, P = ProjectionMatrix, M = ModelViewMatrix // Comment from OSG: // pre adjust P00,P20,P23,P33 by multiplying them by the viewport window matrix. // here we do it in short hand with the knowledge of how the window matrix is formed // note P23,P33 are multiplied by an implicit 1 which would come from the window matrix. // scaling for horizontal pixels var P00 = P[0] * W.width() * 0.5; var P20_00 = P[8] * W.width() * 0.5 + P[11] * W.width() * 0.5; vec3.set( scale00, M[0] * P00 + M[2] * P20_00, M[4] * P00 + M[6] * P20_00, M[8] * P00 + M[10] * P20_00 ); // scaling for vertical pixels var P10 = P[5] * W.height() * 0.5; var P20_10 = P[9] * W.height() * 0.5 + P[11] * W.height() * 0.5; vec3.set( scale10, M[1] * P10 + M[2] * P20_10, M[5] * P10 + M[6] * P20_10, M[9] * P10 + M[10] * P20_10 ); var P23 = P[11]; var P33 = P[15]; var pixelSizeVector = vec4.fromValues( M[2] * P23, M[6] * P23, M[10] * P23, M[14] * P23 + M[15] * P33 ); var scaleRatio = 0.7071067811 / Math.sqrt(vec3.sqrLen(scale00) + vec3.sqrLen(scale10)); vec4.scale(pixelSizeVector, pixelSizeVector, scaleRatio); return pixelSizeVector; };
init: function() { RenderBin.prototype.init.call(this); this._clearDepth = 1.0; vec4.set(this._clearColor, 0.0, 0.0, 0.0, 1.0); /*jshint bitwise: false */ this._clearMask = Camera.COLOR_BUFFER_BIT | Camera.DEPTH_BUFFER_BIT; /*jshint bitwise: true */ this._camera = undefined; this._viewport = undefined; this._scissor = undefined; this._renderStage = this; RenderStage.prototype._initInternal.call(this); return this; },
var RenderStage = function() { RenderBin.call(this); this._clearColor = vec4.create(); this._clearDepth = undefined; this._clearMask = undefined; this._camera = undefined; this._viewport = undefined; this._scissor = undefined; this._preRenderList = []; this._postRenderList = []; // calling prototype to make sure // we call renderstage and not renderbin init RenderStage.prototype.init.call(this); };
var ShadowTextureAtlas = function() { Texture.call(this); this._uniforms = {}; this._lightNumberArray = []; // default for a valid cloneType this._viewMatrices = []; this._projectionMatrices = []; this._depthRanges = []; this._mapSizes = []; this._renderSize = vec4.create(); this._dirtyHash = true; this._hash = ''; };
var createCameraRtt = function(texture, projection) { var camera = new Camera(); camera.setName('rtt camera'); camera.setViewport(new Viewport(0.0, 0.0, texture.getWidth(), texture.getHeight())); camera.setProjectionMatrix(projection); camera.setClearColor(vec4.fromValues(0.3, 0.3, 0.3, 0.0)); camera.setRenderOrder(Camera.POST_RENDER, 0); camera.attachTexture(FrameBufferObject.COLOR_ATTACHMENT0, texture); camera.attachRenderBuffer( FrameBufferObject.DEPTH_ATTACHMENT, FrameBufferObject.DEPTH_COMPONENT16 ); camera.setReferenceFrame(Transform.ABSOLUTE_RF); return camera; };
var ShadowMapAtlas = function(settings) { this._lights = []; this._shadowMaps = []; this._viewportDimension = []; ShadowTechnique.apply(this, arguments); this._shadowSettings = settings; this._texture = new ShadowTextureAtlas(); this._textureUnitBase = 4; this._textureUnit = this._textureUnitBase; // see shadowSettings.js header for param explanations this._textureMagFilter = undefined; this._textureMinFilter = undefined; this._textureSize = 1024; this._shadowMapSize = 256; this._receivingStateset = undefined; this._shaderProcessor = undefined; if (settings) { this.setShadowSettings(settings); if (settings.atlasSize) this._textureSize = settings.atlasSize; if (settings.textureSize) this._shadowMapSize = settings.textureSize; } this._texelSizeUniform = Uniform.createFloat1(1.0 / this._textureSize, 'texelSize'); var unifRenderSize = Uniform.createFloat2('RenderSize'); this._renderSize = unifRenderSize.getInternalArray(); this._renderSize[0] = this._renderSize[1] = this._textureSize; this._numShadowWidth = this._textureSize / this._shadowMapSize; this._numShadowHeight = this._textureSize / this._shadowMapSize; this._cameraClear = new Camera(); this._cameraClear.setName('shadowAtlasCameraClear'); this._cameraClear.setRenderOrder(Camera.PRE_RENDER, 0); this._cameraClear.setClearColor(vec4.fromValues(1.0, 1.0, 1.0, 1.0)); this._cameraClear.setFrameBufferObject(new FrameBufferObject()); this._cameraClear.setClearMask(0x0); };
setClearColor: function(color) { vec4.copy(this._clearColor, color); },
return function(visitor) { if (visitor.getVisitorType() === NodeVisitor.CULL_VISITOR) { var width = visitor.getViewport().width(); var height = visitor.getViewport().height(); var projMat = visitor.getCurrentProjectionMatrix(); var modelViewMat = visitor.getCurrentModelViewMatrix(); var position = this._position; var doUpdate = this._firstTimeToInitEyePoint; if (!this._firstTimeToInitEyePoint) { if (width !== this._previousWidth || height !== this._previousHeight) { doUpdate = true; } else if (!mat4.exactEquals(projMat, this._previousProjection)) { doUpdate = true; } else if (!mat4.exactEquals(modelViewMat, this._previousModelView)) { doUpdate = true; } else if (!vec3.exactEquals(position, this._previousPosition)) { doUpdate = true; } } this._firstTimeToInitEyePoint = false; if (doUpdate) { if (this._autoScaleToScreen) { var viewport = visitor.getViewport(); var psvector = this.computePixelSizeVector( viewport, projMat, modelViewMat ); var v = vec4.fromValues( this._position[0], this._position[1], this._position[2], 1.0 ); var pixelSize = vec4.dot(v, psvector); pixelSize = 0.48 / pixelSize; var size = 1.0 / pixelSize; if (this._autoScaleTransitionWidthRatio > 0.0) { var c, b, a; if (this._minimumScale > 0.0) { var j = this._minimumScale; var i = this._maximumScale < Number.MAX_VALUE ? this._minimumScale + (this._maximumScale - this._minimumScale) * this._autoScaleTransitionWidthRatio : this._minimumScale * (1.0 + this._autoScaleTransitionWidthRatio); c = 1.0 / (4.0 * (i - j)); b = 1.0 - 2.0 * c * i; a = j + b * b / (4.0 * c); var k = -b / (2.0 * c); if (size < k) size = this._minimumScale; else if (size < i) size = a + b * size + c * (size * size); } if (this._maximumScale < Number.MAX_VALUE) { var n = this._maximumScale; var m = this._minimumScale > 0.0 ? this._maximumScale + (this._minimumScale - this._maximumScale) * this._autoScaleTransitionWidthRatio : this._maximumScale * (1.0 - this._autoScaleTransitionWidthRatio); c = 1.0 / (4.0 * (m - n)); b = 1.0 - 2.0 * c * m; a = n + b * b / (4.0 * c); var p = -b / (2.0 * c); if (size > p) size = this._maximumScale; else if (size > m) size = a + b * size + c * (size * size); } } this.setScale(size); } if (this._autoRotateToScreen) { var rotation = quat.create(); mat4.getRotation(rotation, modelViewMat); this.setRotation(quat.invert(rotation, rotation)); } this._previousWidth = width; this._previousHeight = height; vec3.copy(this._previousPosition, position); mat4.copy(this._previousProjection, projMat); mat4.copy(this._previousModelView, modelViewMat); } } Node.prototype.accept.call(this, visitor); };