Cesium-Examples/examples/cesiumEx/skyBoxOnGround.js
2025-03-11 17:51:04 +08:00

245 lines
7.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//以下代码复制自Cesium源码的SkyBox然后做了一点点修改。
//SkyBoxOnGround.js
// const Cesium = window.Cesium;
const BoxGeometry = Cesium.BoxGeometry;
const Cartesian3 = Cesium.Cartesian3;
const defaultValue = Cesium.defaultValue;
const defined = Cesium.defined;
const destroyObject = Cesium.destroyObject;
const DeveloperError = Cesium.DeveloperError;
const GeometryPipeline = Cesium.GeometryPipeline;
const Matrix3 = Cesium.Matrix3;
const Matrix4 = Cesium.Matrix4;
const Transforms = Cesium.Transforms;
const VertexFormat = Cesium.VertexFormat;
const BufferUsage = Cesium.BufferUsage;
const CubeMap = Cesium.CubeMap;
const DrawCommand = Cesium.DrawCommand;
const loadCubeMap = Cesium.loadCubeMap;
const RenderState = Cesium.RenderState;
const VertexArray = Cesium.VertexArray;
const BlendingState = Cesium.BlendingState;
const SceneMode = Cesium.SceneMode;
const ShaderProgram = Cesium.ShaderProgram;
const ShaderSource = Cesium.ShaderSource;
const skyboxMatrix3 = new Matrix3();
/**
* @class DEUGlobe.Scene.SkyBoxOnGround
* @category 场景
* @classdesc 近景天空盒
* @param {Object} options - 参数。
* @param {Object} options.sources - 近地天空盒来源。
*/
class SkyBoxOnGround {
constructor(options) {
/**
* 为了兼容高版本的Cesium因为新版cesium中getRotation被移除
*/
if (!Cesium.defined(Cesium.Matrix4.getRotation)) {
Cesium.Matrix4.getRotation = Cesium.Matrix4.getMatrix3;
}
this.sources = options.sources;
this._sources = undefined;
this.show = defaultValue(options.show, true);
this._command = new DrawCommand({
modelMatrix: Matrix4.clone(Matrix4.IDENTITY),
owner: this,
});
this._cubeMap = undefined;
this._attributeLocations = undefined;
this._useHdr = undefined;
}
update(frameState, useHdr) {
const that = this;
//片元着色器,直接从源码复制
// -------------- requestWebgl1: true,--------------
// const SkyBoxFS =
// "uniform samplerCube u_cubeMap;\n\
// varying vec3 v_texCoord;\n\
// void main()\n\
// {\n\
// vec4 color = textureCube(u_cubeMap, normalize(v_texCoord));\n\
// gl_FragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime);\n\
// }\n\
// ";
const SkyBoxFS = `precision highp float;
uniform samplerCube u_cubeMap;
in vec3 v_texCoord;
out vec4 fragColor;
void main() {
vec4 color = texture(u_cubeMap, normalize(v_texCoord));
fragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime);
}`;
//顶点着色器有修改,主要是乘了一个旋转矩阵
// -------------- requestWebgl1: true,--------------
// const SkyBoxVS =
// "attribute vec3 position;\n\
// varying vec3 v_texCoord;\n\
// uniform mat3 u_rotateMatrix;\n\
// void main()\n\
// {\n\
// vec3 p = czm_viewRotation * u_rotateMatrix * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));\n\
// gl_Position = czm_projection * vec4(p, 1.0);\n\
// v_texCoord = position.xyz;\n\
// }\n\
// ";
const SkyBoxVS = `#version 300 es
precision highp float;
in vec3 position;
out vec3 v_texCoord;
uniform mat3 u_rotateMatrix;
void main() {
vec3 p = czm_viewRotation * u_rotateMatrix * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));
gl_Position = czm_projection * vec4(p, 1.0);
v_texCoord = position;
}
`;
if (!this.show) {
return undefined;
}
if (
frameState.mode !== SceneMode.SCENE3D &&
frameState.mode !== SceneMode.MORPHING
) {
return undefined;
}
if (!frameState.passes.render) {
return undefined;
}
const context = frameState.context;
if (this._sources !== this.sources) {
this._sources = this.sources;
const sources = this.sources;
if (
!defined(sources.positiveX) ||
!defined(sources.negativeX) ||
!defined(sources.positiveY) ||
!defined(sources.negativeY) ||
!defined(sources.positiveZ) ||
!defined(sources.negativeZ)
) {
throw new DeveloperError(
"this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties."
);
}
if (
typeof sources.positiveX !== typeof sources.negativeX ||
typeof sources.positiveX !== typeof sources.positiveY ||
typeof sources.positiveX !== typeof sources.negativeY ||
typeof sources.positiveX !== typeof sources.positiveZ ||
typeof sources.positiveX !== typeof sources.negativeZ
) {
throw new DeveloperError(
"this.sources properties must all be the same type."
);
}
if (typeof sources.positiveX === "string") {
// Given urls for cube-map images. Load them.
loadCubeMap(context, this._sources).then(function (cubeMap) {
that._cubeMap = that._cubeMap && that._cubeMap.destroy();
that._cubeMap = cubeMap;
});
} else {
this._cubeMap = this._cubeMap && this._cubeMap.destroy();
this._cubeMap = new CubeMap({
context: context,
source: sources,
});
}
}
const command = this._command;
command.modelMatrix = Transforms.eastNorthUpToFixedFrame(
frameState.camera._positionWC
);
if (!defined(command.vertexArray)) {
command.uniformMap = {
u_cubeMap: function () {
return that._cubeMap;
},
u_rotateMatrix: function () {
return Matrix4.getRotation(command.modelMatrix, skyboxMatrix3);
},
};
const geometry = BoxGeometry.createGeometry(
BoxGeometry.fromDimensions({
dimensions: new Cartesian3(2.0, 2.0, 2.0),
vertexFormat: VertexFormat.POSITION_ONLY,
})
);
const attributeLocations = (this._attributeLocations =
GeometryPipeline.createAttributeLocations(geometry));
command.vertexArray = VertexArray.fromGeometry({
context: context,
geometry: geometry,
attributeLocations: attributeLocations,
bufferUsage: BufferUsage._DRAW,
});
command.renderState = RenderState.fromCache({
blending: BlendingState.ALPHA_BLEND,
});
}
if (!defined(command.shaderProgram) || this._useHdr !== useHdr) {
const fs = new ShaderSource({
defines: [useHdr ? "HDR" : ""],
sources: [SkyBoxFS],
});
command.shaderProgram = ShaderProgram.fromCache({
context: context,
vertexShaderSource: SkyBoxVS,
fragmentShaderSource: fs,
attributeLocations: this._attributeLocations,
});
this._useHdr = useHdr;
}
if (!defined(this._cubeMap)) {
return undefined;
}
return command;
}
isDestroyed() {
return false;
}
destroy() {
const command = this._command;
command.vertexArray = command.vertexArray && command.vertexArray.destroy();
command.shaderProgram =
command.shaderProgram && command.shaderProgram.destroy();
this._cubeMap = this._cubeMap && this._cubeMap.destroy();
return destroyObject(this);
}
}