DSDSWeb/static/js/Cesium-1.53/Specs/Scene/MultifrustumSpec.js

377 lines
12 KiB
JavaScript
Raw Normal View History

2024-07-11 18:02:47 +08:00
defineSuite([
'Core/BoundingSphere',
'Core/BoxGeometry',
'Core/Cartesian2',
'Core/Cartesian3',
'Core/Color',
'Core/defaultValue',
'Core/defined',
'Core/destroyObject',
'Core/GeometryPipeline',
'Core/Math',
'Core/Matrix4',
'Core/Resource',
'Renderer/BufferUsage',
'Renderer/DrawCommand',
'Renderer/Pass',
'Renderer/RenderState',
'Renderer/Sampler',
'Renderer/ShaderProgram',
'Renderer/TextureMagnificationFilter',
'Renderer/TextureMinificationFilter',
'Renderer/VertexArray',
'Scene/BillboardCollection',
'Scene/BlendingState',
'Scene/TextureAtlas',
'Specs/createScene',
'ThirdParty/when'
], 'Scene/Multifrustum', function(
BoundingSphere,
BoxGeometry,
Cartesian2,
Cartesian3,
Color,
defaultValue,
defined,
destroyObject,
GeometryPipeline,
CesiumMath,
Matrix4,
Resource,
BufferUsage,
DrawCommand,
Pass,
RenderState,
Sampler,
ShaderProgram,
TextureMagnificationFilter,
TextureMinificationFilter,
VertexArray,
BillboardCollection,
BlendingState,
TextureAtlas,
createScene,
when) {
'use strict';
var scene;
var context;
var primitives;
var atlas;
var greenImage;
var blueImage;
var whiteImage;
var logDepth;
beforeAll(function() {
scene = createScene();
logDepth = scene.logarithmicDepthBuffer;
scene.destroyForSpecs();
return when.join(
Resource.fetchImage('./Data/Images/Green.png').then(function(image) {
greenImage = image;
}),
Resource.fetchImage('./Data/Images/Blue.png').then(function(image) {
blueImage = image;
}),
Resource.fetchImage('./Data/Images/White.png').then(function(image) {
whiteImage = image;
}));
});
beforeEach(function() {
scene = createScene();
context = scene.context;
primitives = scene.primitives;
scene.logarithmicDepthBuffer = false;
var camera = scene.camera;
camera.position = new Cartesian3();
camera.direction = Cartesian3.negate(Cartesian3.UNIT_Z, new Cartesian3());
camera.up = Cartesian3.clone(Cartesian3.UNIT_Y);
camera.right = Cartesian3.clone(Cartesian3.UNIT_X);
camera.frustum.near = 1.0;
camera.frustum.far = 1000000000.0;
camera.frustum.fov = CesiumMath.toRadians(60.0);
camera.frustum.aspectRatio = 1.0;
});
afterEach(function() {
atlas = atlas && atlas.destroy();
scene.destroyForSpecs();
});
var billboard0;
var billboard1;
var billboard2;
function createBillboards() {
atlas = new TextureAtlas({
context : context,
borderWidthInPixels : 1,
initialSize : new Cartesian2(3, 3)
});
// ANGLE Workaround
atlas.texture.sampler = new Sampler({
minificationFilter : TextureMinificationFilter.NEAREST,
magnificationFilter : TextureMagnificationFilter.NEAREST
});
var billboards = new BillboardCollection();
billboards.textureAtlas = atlas;
billboards.destroyTextureAtlas = false;
billboard0 = billboards.add({
position : new Cartesian3(0.0, 0.0, -50.0),
image : greenImage
});
primitives.add(billboards);
billboards = new BillboardCollection();
billboards.textureAtlas = atlas;
billboards.destroyTextureAtlas = false;
billboard1 = billboards.add({
position : new Cartesian3(0.0, 0.0, -50000.0),
image : blueImage
});
primitives.add(billboards);
billboards = new BillboardCollection();
billboards.textureAtlas = atlas;
billboards.destroyTextureAtlas = false;
billboard2 = billboards.add({
position : new Cartesian3(0.0, 0.0, -50000000.0),
image : whiteImage
});
primitives.add(billboards);
return billboards;
}
it('renders primitive in closest frustum', function() {
createBillboards();
expect(scene).toRenderAndCall(function(rgba) {
expect(rgba[0]).toEqual(0);
expect(rgba[1]).not.toEqual(0);
expect(rgba[2]).toEqual(0);
expect(rgba[3]).toEqual(255);
});
expect(scene).toRenderAndCall(function(rgba) {
expect(rgba[0]).toEqual(0);
expect(rgba[1]).not.toEqual(0);
expect(rgba[2]).toEqual(0);
expect(rgba[3]).toEqual(255);
});
});
it('renders primitive in middle frustum', function() {
createBillboards();
billboard0.color = new Color(1.0, 1.0, 1.0, 0.0);
expect(scene).toRender([0, 0, 255, 255]);
expect(scene).toRender([0, 0, 255, 255]);
});
it('renders primitive in last frustum', function() {
createBillboards();
var color = new Color(1.0, 1.0, 1.0, 0.0);
billboard0.color = color;
billboard1.color = color;
expect(scene).toRender([255, 255, 255, 255]);
expect(scene).toRender([255, 255, 255, 255]);
});
it('renders primitive in last frustum with debugShowFrustums', function() {
createBillboards();
var color = new Color(1.0, 1.0, 1.0, 1.0);
billboard0.color = color;
billboard1.color = color;
spyOn(DrawCommand.prototype, 'execute');
scene.debugShowFrustums = true;
scene.renderForSpecs();
expect(DrawCommand.prototype.execute).toHaveBeenCalled();
var calls = DrawCommand.prototype.execute.calls.all();
var billboardCall;
var i;
for (i = 0; i < calls.length; ++i) {
if (calls[i].object.owner instanceof BillboardCollection) {
billboardCall = calls[i];
break;
}
}
expect(billboardCall).toBeDefined();
expect(billboardCall.args.length).toEqual(2);
var found = false;
var sources = billboardCall.object.shaderProgram.fragmentShaderSource.sources;
for (var j = 0; j < sources.length; ++j) {
if (sources[i].indexOf('czm_Debug_main') !== -1) {
found = true;
break;
}
}
expect(found).toBe(true);
});
function createPrimitive(bounded, closestFrustum) {
bounded = defaultValue(bounded, true);
closestFrustum = defaultValue(closestFrustum, false);
function Primitive() {
this._va = undefined;
this._sp = undefined;
this._rs = undefined;
this._modelMatrix = Matrix4.fromTranslation(new Cartesian3(0.0, 0.0, -50000.0), new Matrix4());
this.color = new Color(1.0, 1.0, 0.0, 1.0);
var that = this;
this._um = {
u_color : function() {
return that.color;
},
u_model : function() {
return that._modelMatrix;
}
};
}
Primitive.prototype.update = function(frameState) {
if (!defined(this._sp)) {
var vs = '';
vs += 'attribute vec4 position;';
vs += 'void main()';
vs += '{';
vs += ' gl_Position = czm_modelViewProjection * position;';
vs += closestFrustum ? ' gl_Position.z = clamp(gl_Position.z, gl_DepthRange.near, gl_DepthRange.far);' : '';
vs += '}';
var fs = '';
fs += 'uniform vec4 u_color;';
fs += 'void main()';
fs += '{';
fs += ' gl_FragColor = u_color;';
fs += '}';
var dimensions = new Cartesian3(500000.0, 500000.0, 500000.0);
var maximum = Cartesian3.multiplyByScalar(dimensions, 0.5, new Cartesian3());
var minimum = Cartesian3.negate(maximum, new Cartesian3());
var geometry = BoxGeometry.createGeometry(new BoxGeometry({
minimum : minimum,
maximum : maximum
}));
var attributeLocations = GeometryPipeline.createAttributeLocations(geometry);
this._va = VertexArray.fromGeometry({
context : frameState.context,
geometry : geometry,
attributeLocations : attributeLocations,
bufferUsage : BufferUsage.STATIC_DRAW
});
this._sp = ShaderProgram.fromCache({
context : frameState.context,
vertexShaderSource : vs,
fragmentShaderSource : fs,
attributeLocations : attributeLocations
});
this._rs = RenderState.fromCache({
blending : BlendingState.ALPHA_BLEND
});
}
frameState.commandList.push(new DrawCommand({
renderState : this._rs,
shaderProgram : this._sp,
vertexArray : this._va,
uniformMap : this._um,
modelMatrix : this._modelMatrix,
executeInClosestFrustum : closestFrustum,
boundingVolume : bounded ? new BoundingSphere(Cartesian3.clone(Cartesian3.ZERO), 500000.0) : undefined,
pass : Pass.OPAQUE
}));
};
Primitive.prototype.destroy = function() {
this._va = this._va && this._va.destroy();
this._sp = this._sp && this._sp.destroy();
return destroyObject(this);
};
return new Primitive();
}
it('renders primitive with undefined bounding volume', function() {
var primitive = createPrimitive(false);
primitives.add(primitive);
expect(scene).toRender([255, 255, 0, 255]);
expect(scene).toRender([255, 255, 0, 255]);
});
it('renders only in the closest frustum', function() {
createBillboards();
var color = new Color(1.0, 1.0, 1.0, 0.0);
billboard0.color = color;
billboard1.color = color;
billboard2.color = color;
var primitive = createPrimitive(true, true);
primitive.color = new Color(1.0, 1.0, 0.0, 0.5);
primitives.add(primitive);
expect(scene).toRenderAndCall(function(rgba) {
expect(rgba[0]).not.toEqual(0);
expect(rgba[1]).not.toEqual(0);
expect(rgba[2]).toEqual(0);
expect(rgba[3]).toEqual(255);
});
expect(scene).toRenderAndCall(function(rgba) {
expect(rgba[0]).not.toEqual(0);
expect(rgba[1]).not.toEqual(0);
expect(rgba[2]).toEqual(0);
expect(rgba[3]).toEqual(255);
});
});
it('render without a central body or any primitives', function() {
scene.renderForSpecs();
});
it('does not crash when near plane is greater than or equal to the far plane', function() {
var camera = scene.camera;
camera.frustum.far = 1000.0;
camera.position = new Cartesian3(0.0, 0.0, 1e12);
createBillboards();
scene.renderForSpecs();
});
it('log depth uses less frustums', function() {
if (!logDepth) {
return;
}
createBillboards();
scene.render();
expect(scene.frustumCommandsList.length).toEqual(3);
scene.logarithmicDepthBuffer = true;
scene.render();
expect(scene.frustumCommandsList.length).toEqual(1);
});
}, 'WebGL');