Переглянути джерело

添加自定义天空盒

tags/1.15.1
Caven Chen 4 роки тому
джерело
коміт
d8c69b50d9
3 змінених файлів з 200 додано та 1 видалено
  1. 4
    1
      src/core/Loader.js
  2. 190
    0
      src/core/exts/SkyBox.js
  3. 6
    0
      src/core/exts/index.js

+ 4
- 1
src/core/Loader.js Переглянути файл

@@ -44,6 +44,8 @@ import {
parabola
} from './math'

import { SkyBox } from './exts'

const { Cesium } = DC.Namespace

Cesium.Math.area = area
@@ -80,7 +82,8 @@ const core = {
Polygon,
Model,
Tileset,
Math: Cesium.Math
Math: Cesium.Math,
SkyBox
}

DC.mixin(core)

+ 190
- 0
src/core/exts/SkyBox.js Переглянути файл

@@ -0,0 +1,190 @@
/**
* @Author: Caven
* @Date: 2021-02-21 17:50:31
*/

const { Cesium } = DC.Namespace

const {
BoxGeometry,
Cartesian3,
defined,
DeveloperError,
GeometryPipeline,
Matrix3,
Matrix4,
Transforms,
VertexFormat,
BufferUsage,
CubeMap,
loadCubeMap,
RenderState,
VertexArray,
BlendingState,
SceneMode,
ShaderProgram,
ShaderSource
} = Cesium

const SkyBoxFS = `
uniform samplerCube u_cubeMap;
varying vec3 v_texCoord;
void main()
{
vec4 color = textureCube(u_cubeMap, normalize(v_texCoord));
gl_FragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime);
}
`

const SkyBoxVS = `
attribute vec3 position;
varying 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.xyz;
}
`

class SkyBox extends Cesium.SkyBox {
constructor(options = {}) {
super(options)
this.offsetAngle = options?.offsetAngle || 90
}

update(frameState, useHdr) {
const that = this

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 (this.offsetAngle !== 0) {
Matrix4.multiply(
command.modelMatrix,
Matrix4.fromRotationTranslation(
Matrix3.fromRotationZ((this.offsetAngle / 180) * Math.PI)
),
command.modelMatrix
)
}

if (!defined(command.vertexArray)) {
command.uniformMap = {
u_cubeMap: function() {
return that._cubeMap
},
u_rotateMatrix: function() {
return Matrix4.getMatrix3(command.modelMatrix, new Matrix3())
}
}

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
}
}

export default SkyBox

+ 6
- 0
src/core/exts/index.js Переглянути файл

@@ -0,0 +1,6 @@
/**
* @Author: Caven
* @Date: 2021-02-21 17:51:00
*/

export { default as SkyBox } from './SkyBox'

Завантаження…
Відмінити
Зберегти