import { Cartesian3, defined } from "../../Source/Cesium.js";
|
import { ComputeEngine } from "../../Source/Cesium.js";
|
import { Pass } from "../../Source/Cesium.js";
|
import { OctahedralProjectedCubeMap } from "../../Source/Cesium.js";
|
import createContext from "../createContext.js";
|
import createFrameState from "../createFrameState.js";
|
import pollToPromise from "../pollToPromise.js";
|
|
describe(
|
"Scene/OctahedralProjectedCubeMap",
|
function () {
|
var context;
|
var computeEngine;
|
var octahedralMap;
|
|
var environmentMapUrl =
|
"./Data/EnvironmentMap/kiara_6_afternoon_2k_ibl.ktx2";
|
var fsOctahedralMap =
|
"uniform sampler2D projectedMap;" +
|
"uniform vec2 textureSize;" +
|
"uniform vec3 direction;" +
|
"uniform float lod;" +
|
"uniform float maxLod;" +
|
"void main() {" +
|
" vec3 color = czm_sampleOctahedralProjection(projectedMap, textureSize, direction, lod, maxLod);" +
|
" gl_FragColor = vec4(color, 1.0);" +
|
"}";
|
|
var fsCubeMap =
|
"uniform samplerCube cubeMap;" +
|
"uniform vec3 direction;" +
|
"void main() {" +
|
" vec4 rgba = textureCube(cubeMap, direction);" +
|
" gl_FragColor = vec4(rgba.rgb, 1.0);" +
|
"}";
|
|
beforeAll(function () {
|
context = createContext();
|
computeEngine = new ComputeEngine(context);
|
});
|
|
afterAll(function () {
|
context.destroyForSpecs();
|
computeEngine.destroy();
|
});
|
|
afterEach(function () {
|
octahedralMap = octahedralMap && octahedralMap.destroy();
|
context.textureCache.destroyReleasedTextures();
|
});
|
|
function executeCommands(frameState) {
|
var length = frameState.commandList.length;
|
for (var i = 0; i < length; ++i) {
|
var command = frameState.commandList[i];
|
if (command.pass === Pass.COMPUTE) {
|
command.execute(computeEngine);
|
} else {
|
command.execute(context);
|
}
|
}
|
frameState.commandList.length = 0;
|
}
|
|
function sampleOctahedralMap(octahedralMap, direction, lod, callback) {
|
expect({
|
context: context,
|
fragmentShader: fsOctahedralMap,
|
uniformMap: {
|
projectedMap: function () {
|
return octahedralMap.texture;
|
},
|
textureSize: function () {
|
return octahedralMap.texture.dimensions;
|
},
|
direction: function () {
|
return direction;
|
},
|
lod: function () {
|
return lod;
|
},
|
maxLod: function () {
|
return octahedralMap.maximumMipmapLevel;
|
},
|
},
|
}).contextToRenderAndCall(callback);
|
}
|
|
function sampleCubeMap(cubeMap, direction, callback) {
|
expect({
|
context: context,
|
fragmentShader: fsCubeMap,
|
uniformMap: {
|
cubeMap: function () {
|
return cubeMap;
|
},
|
direction: function () {
|
return direction;
|
},
|
},
|
}).contextToRenderAndCall(callback);
|
}
|
|
function expectCubeMapAndOctahedralMapEqual(octahedralMap, direction, lod) {
|
return sampleCubeMap(octahedralMap._cubeMaps[lod], direction, function (
|
cubeMapColor
|
) {
|
var directionFlipY = direction.clone();
|
directionFlipY.y *= -1;
|
|
sampleOctahedralMap(octahedralMap, directionFlipY, lod, function (
|
octahedralMapColor
|
) {
|
return expect(cubeMapColor).toEqualEpsilon(octahedralMapColor, 6);
|
});
|
});
|
}
|
|
it("creates a packed texture with the right dimensions", function () {
|
if (!OctahedralProjectedCubeMap.isSupported(context)) {
|
return;
|
}
|
|
octahedralMap = new OctahedralProjectedCubeMap(environmentMapUrl);
|
var frameState = createFrameState(context);
|
|
return pollToPromise(function () {
|
octahedralMap.update(frameState);
|
return octahedralMap.ready;
|
}).then(function () {
|
expect(octahedralMap.texture.width).toEqual(770);
|
expect(octahedralMap.texture.height).toEqual(512);
|
expect(octahedralMap.maximumMipmapLevel).toEqual(5);
|
});
|
});
|
|
it("correctly projects the given cube map and all mip levels", function () {
|
if (!OctahedralProjectedCubeMap.isSupported(context)) {
|
return;
|
}
|
|
octahedralMap = new OctahedralProjectedCubeMap(environmentMapUrl);
|
var frameState = createFrameState(context);
|
|
return pollToPromise(function () {
|
// We manually call update and execute the commands
|
// because calling scene.renderForSpecs does not
|
// actually execute these commands, and we need
|
// to get the output of the texture.
|
octahedralMap.update(frameState);
|
executeCommands(frameState);
|
|
return octahedralMap.ready;
|
}).then(function () {
|
var directions = {
|
positiveX: new Cartesian3(1, 0, 0),
|
negativeX: new Cartesian3(-1, 0, 0),
|
positiveY: new Cartesian3(0, 1, 0),
|
negativeY: new Cartesian3(0, -1, 0),
|
positiveZ: new Cartesian3(0, 0, 1),
|
negativeZ: new Cartesian3(0, 0, -1),
|
};
|
|
for (
|
var mipLevel = 0;
|
mipLevel < octahedralMap.maximumMipmapLevel;
|
mipLevel++
|
) {
|
for (var key in directions) {
|
if (directions.hasOwnProperty(key)) {
|
var direction = directions[key];
|
|
expectCubeMapAndOctahedralMapEqual(
|
octahedralMap,
|
direction,
|
mipLevel
|
);
|
}
|
}
|
}
|
});
|
});
|
|
it("caches projected textures", function () {
|
if (!OctahedralProjectedCubeMap.isSupported(context)) {
|
return;
|
}
|
|
var projection = new OctahedralProjectedCubeMap(environmentMapUrl);
|
var frameState = createFrameState(context);
|
|
return pollToPromise(function () {
|
projection.update(frameState);
|
return projection.ready;
|
})
|
.then(function () {
|
var projection2 = new OctahedralProjectedCubeMap(environmentMapUrl);
|
projection2.update(frameState);
|
expect(projection2.ready).toEqual(true);
|
expect(projection.texture).toEqual(projection2.texture);
|
projection2.destroy();
|
})
|
.always(function () {
|
projection.destroy();
|
});
|
});
|
|
it("rejects when environment map fails to load.", function () {
|
if (!OctahedralProjectedCubeMap.isSupported(context)) {
|
return;
|
}
|
|
var projection = new OctahedralProjectedCubeMap("http://invalid.url");
|
var frameState = createFrameState(context);
|
var error;
|
|
projection.readyPromise
|
.then(function () {
|
fail("Should not resolve.");
|
})
|
.otherwise(function (e) {
|
error = e;
|
expect(error).toBeDefined();
|
expect(projection.ready).toEqual(false);
|
});
|
|
return pollToPromise(function () {
|
projection.update(frameState);
|
return defined(error);
|
});
|
});
|
},
|
"WebGL"
|
);
|