You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
322 lines
10 KiB
JavaScript
322 lines
10 KiB
JavaScript
import { BoundingRectangle } from "../../Source/Cesium.js";
|
|
import { Cartesian3 } from "../../Source/Cesium.js";
|
|
import { Color } from "../../Source/Cesium.js";
|
|
import { defined } from "../../Source/Cesium.js";
|
|
import { HeadingPitchRange } from "../../Source/Cesium.js";
|
|
import { Matrix4 } from "../../Source/Cesium.js";
|
|
import { PixelFormat } from "../../Source/Cesium.js";
|
|
import { Transforms } from "../../Source/Cesium.js";
|
|
import { PixelDatatype } from "../../Source/Cesium.js";
|
|
import { Model } from "../../Source/Cesium.js";
|
|
import { PostProcessStage } from "../../Source/Cesium.js";
|
|
import { PostProcessStageSampleMode } from "../../Source/Cesium.js";
|
|
import createScene from "../createScene.js";
|
|
import pollToPromise from "../pollToPromise.js";
|
|
import { when } from "../../Source/Cesium.js";
|
|
|
|
describe(
|
|
"Scene/PostProcessStage",
|
|
function () {
|
|
var scene;
|
|
|
|
beforeAll(function () {
|
|
scene = createScene();
|
|
scene.postProcessStages.fxaa.enabled = false;
|
|
});
|
|
|
|
afterAll(function () {
|
|
scene.destroyForSpecs();
|
|
});
|
|
|
|
afterEach(function () {
|
|
scene.postProcessStages.removeAll();
|
|
scene.primitives.removeAll();
|
|
});
|
|
|
|
it("constructs", function () {
|
|
var fragmentShader =
|
|
"uniform vec4 color; void main() { gl_FragColor = color; }";
|
|
var uniforms = { color: Color.clone(Color.RED) };
|
|
var textureScale = 0.5;
|
|
var forcePowerOfTwo = true;
|
|
var sampleMode = PostProcessStageSampleMode.LINEAR;
|
|
var pixelFormat = PixelFormat.RGB;
|
|
var pixelDatatype = PixelDatatype.UNSIGNED_INT;
|
|
var clearColor = Color.clone(Color.BLUE);
|
|
var scissorRectangle = new BoundingRectangle(0, 0, 5, 5);
|
|
var name = "wonka vision";
|
|
|
|
var stage = new PostProcessStage({
|
|
fragmentShader: fragmentShader,
|
|
uniforms: uniforms,
|
|
textureScale: textureScale,
|
|
forcePowerOfTwo: forcePowerOfTwo,
|
|
sampleMode: sampleMode,
|
|
pixelFormat: pixelFormat,
|
|
pixelDatatype: pixelDatatype,
|
|
clearColor: clearColor,
|
|
scissorRectangle: scissorRectangle,
|
|
name: name,
|
|
});
|
|
expect(stage.fragmentShader).toEqual(fragmentShader);
|
|
expect(stage.uniforms.color).toBeDefined();
|
|
expect(stage.textureScale).toEqual(textureScale);
|
|
expect(stage.forcePowerOfTwo).toEqual(forcePowerOfTwo);
|
|
expect(stage.sampleMode).toEqual(sampleMode);
|
|
expect(stage.pixelFormat).toEqual(stage.pixelFormat);
|
|
expect(stage.pixelDatatype).toEqual(pixelDatatype);
|
|
expect(stage.clearColor).toEqual(clearColor);
|
|
expect(stage.scissorRectangle).toEqual(scissorRectangle);
|
|
expect(stage.name).toEqual(name);
|
|
expect(stage.outputTexture).not.toBeDefined();
|
|
});
|
|
|
|
it("default constructs", function () {
|
|
var fragmentShader = "void main() { gl_FragColor = vec4(1.0); }";
|
|
|
|
var stage = new PostProcessStage({
|
|
fragmentShader: fragmentShader,
|
|
});
|
|
expect(stage.fragmentShader).toEqual(fragmentShader);
|
|
expect(stage.uniforms).not.toBeDefined();
|
|
expect(stage.textureScale).toEqual(1.0);
|
|
expect(stage.forcePowerOfTwo).toEqual(false);
|
|
expect(stage.sampleMode).toEqual(PostProcessStageSampleMode.NEAREST);
|
|
expect(stage.pixelFormat).toEqual(PixelFormat.RGBA);
|
|
expect(stage.pixelDatatype).toEqual(PixelDatatype.UNSIGNED_BYTE);
|
|
expect(stage.clearColor).toEqual(Color.BLACK);
|
|
expect(stage.scissorRectangle).toEqual(new BoundingRectangle());
|
|
expect(stage.name).toBeDefined();
|
|
expect(stage.outputTexture).not.toBeDefined();
|
|
});
|
|
|
|
it("throws without fragment shader", function () {
|
|
expect(function () {
|
|
return new PostProcessStage();
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws with invalid texture scale", function () {
|
|
var fs = "void main() { gl_FragColor = vec4(1.0); }";
|
|
expect(function () {
|
|
return new PostProcessStage({
|
|
fragmentShader: fs,
|
|
textureScale: -1.0,
|
|
});
|
|
}).toThrowDeveloperError();
|
|
expect(function () {
|
|
return new PostProcessStage({
|
|
fragmentShader: fs,
|
|
textureScale: 2.0,
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("throws if pixel format is not a color format", function () {
|
|
expect(function () {
|
|
return new PostProcessStage({
|
|
fragmentShader: "void main() { gl_FragColor = vec4(1.0); }",
|
|
pixelFormat: PixelFormat.DEPTH_STENCIL,
|
|
});
|
|
}).toThrowDeveloperError();
|
|
});
|
|
|
|
it("executes", function () {
|
|
expect(scene).toRender([0, 0, 0, 255]);
|
|
scene.postProcessStages.add(
|
|
new PostProcessStage({
|
|
fragmentShader:
|
|
"void main() { gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); }",
|
|
})
|
|
);
|
|
scene.renderForSpecs(); // render one frame so the stage is ready
|
|
expect(scene).toRender([255, 255, 0, 255]);
|
|
});
|
|
|
|
it("can use a texture uniform", function () {
|
|
expect(scene).toRender([0, 0, 0, 255]);
|
|
var stage = scene.postProcessStages.add(
|
|
new PostProcessStage({
|
|
fragmentShader:
|
|
"uniform sampler2D texture; varying vec2 v_textureCoordinates; void main() { gl_FragColor = texture2D(texture, v_textureCoordinates); }",
|
|
uniforms: {
|
|
texture: "./Data/Images/Green2x2.png",
|
|
},
|
|
})
|
|
);
|
|
return pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
return stage.ready;
|
|
}).then(function () {
|
|
expect(scene).toRender([0, 255, 0, 255]);
|
|
stage.uniforms.texture = "./Data/Images/Blue2x2.png";
|
|
return pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
return stage.ready;
|
|
}).then(function () {
|
|
expect(scene).toRender([0, 0, 255, 255]);
|
|
});
|
|
});
|
|
});
|
|
|
|
it("can use a image uniform", function () {
|
|
var ready = false;
|
|
var image = new Image();
|
|
image.src = "./Data/Images/Blue2x2.png";
|
|
image.onload = function () {
|
|
ready = true;
|
|
};
|
|
|
|
return pollToPromise(function () {
|
|
return ready;
|
|
}).then(function () {
|
|
expect(scene).toRender([0, 0, 0, 255]);
|
|
var stage = scene.postProcessStages.add(
|
|
new PostProcessStage({
|
|
fragmentShader:
|
|
"uniform sampler2D texture; void main() { gl_FragColor = texture2D(texture, vec2(0.5)); }",
|
|
uniforms: {
|
|
texture: image,
|
|
},
|
|
})
|
|
);
|
|
return pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
return stage.ready;
|
|
}).then(function () {
|
|
expect(scene).toRender([0, 0, 255, 255]);
|
|
});
|
|
});
|
|
});
|
|
|
|
it("does not run a stage that requires depth textures when depth textures are not supported", function () {
|
|
var s = createScene();
|
|
s.context._depthTexture = false;
|
|
|
|
if (defined(s._view.globeDepth)) {
|
|
s._view.globeDepth.destroy();
|
|
s._view.globeDepth = undefined;
|
|
if (defined(s._view.oit)) {
|
|
s._view.oit.destroy();
|
|
s._view.oit = undefined;
|
|
}
|
|
}
|
|
|
|
expect(s).toRender([0, 0, 0, 255]);
|
|
// Dummy Stage
|
|
var bgColor = 51; // Choose a factor of 255 to make sure there aren't rounding issues
|
|
s.postProcessStages.add(
|
|
new PostProcessStage({
|
|
fragmentShader:
|
|
"void main() { gl_FragColor = vec4(vec3(" +
|
|
bgColor / 255 +
|
|
"), 1.0); }",
|
|
})
|
|
);
|
|
|
|
var stage = s.postProcessStages.add(
|
|
new PostProcessStage({
|
|
fragmentShader:
|
|
"uniform sampler2D depthTexture; void main() { gl_FragColor = vec4(1.0); }",
|
|
})
|
|
);
|
|
return pollToPromise(function () {
|
|
s.renderForSpecs();
|
|
return stage.ready;
|
|
})
|
|
.then(function () {
|
|
expect(s).toRender([bgColor, bgColor, bgColor, 255]);
|
|
})
|
|
.always(function (e) {
|
|
s.destroyForSpecs();
|
|
if (e) {
|
|
return when.reject(e);
|
|
}
|
|
});
|
|
});
|
|
|
|
var model;
|
|
|
|
function loadModel(url) {
|
|
model = scene.primitives.add(
|
|
Model.fromGltf({
|
|
modelMatrix: Transforms.eastNorthUpToFixedFrame(
|
|
Cartesian3.fromDegrees(0.0, 0.0, 100.0)
|
|
),
|
|
url: url,
|
|
})
|
|
);
|
|
model.zoomTo = function () {
|
|
var camera = scene.camera;
|
|
var center = Matrix4.multiplyByPoint(
|
|
model.modelMatrix,
|
|
model.boundingSphere.center,
|
|
new Cartesian3()
|
|
);
|
|
var r =
|
|
4.0 * Math.max(model.boundingSphere.radius, camera.frustum.near);
|
|
camera.lookAt(center, new HeadingPitchRange(0.0, 0.0, r));
|
|
};
|
|
|
|
return pollToPromise(
|
|
function () {
|
|
// Render scene to progressively load the model
|
|
scene.renderForSpecs();
|
|
return model.ready;
|
|
},
|
|
{ timeout: 10000 }
|
|
)
|
|
.then(function () {
|
|
return model;
|
|
})
|
|
.otherwise(function () {
|
|
return when.reject(model);
|
|
});
|
|
}
|
|
|
|
it("per-feature post process stage", function () {
|
|
return loadModel("./Data/Models/Box/CesiumBoxTest.gltf").then(
|
|
function () {
|
|
model.zoomTo();
|
|
var fs =
|
|
"uniform sampler2D colorTexture; \n" +
|
|
"varying vec2 v_textureCoordinates; \n" +
|
|
"void main() { \n" +
|
|
" if (czm_selected(v_textureCoordinates)) { \n" +
|
|
" gl_FragColor = texture2D(colorTexture, v_textureCoordinates); \n" +
|
|
" } else { \n" +
|
|
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" +
|
|
" } \n" +
|
|
"} \n";
|
|
var stage = scene.postProcessStages.add(
|
|
new PostProcessStage({
|
|
fragmentShader: fs,
|
|
})
|
|
);
|
|
stage.selected = [];
|
|
return pollToPromise(function () {
|
|
scene.renderForSpecs();
|
|
return stage.ready;
|
|
}).then(function () {
|
|
expect(scene).toRender([255, 0, 0, 255]);
|
|
stage.selected = [model];
|
|
expect(scene).toRenderAndCall(function (rgba) {
|
|
expect(rgba).not.toEqual([255, 0, 0, 255]);
|
|
});
|
|
});
|
|
}
|
|
);
|
|
});
|
|
|
|
it("destroys", function () {
|
|
var stage = new PostProcessStage({
|
|
fragmentShader: "void main() { gl_FragColor = vec4(1.0); }",
|
|
});
|
|
expect(stage.isDestroyed()).toEqual(false);
|
|
stage.destroy();
|
|
expect(stage.isDestroyed()).toEqual(true);
|
|
});
|
|
},
|
|
"WebGL"
|
|
);
|