UNPKG

@takram/three-atmosphere

Version:
145 lines (127 loc) 3.98 kB
import { GLSL3, Matrix4, Uniform, Vector2, type BufferGeometry, type Group, type Object3D, type OrthographicCamera, type PerspectiveCamera, type Scene, type WebGLRenderer } from 'three' import { define, resolveIncludes } from '@takram/three-geospatial' import { AtmosphereMaterialBase, atmosphereMaterialParametersBaseDefaults, type AtmosphereMaterialBaseParameters, type AtmosphereMaterialBaseUniforms } from './AtmosphereMaterialBase' import functions from './shaders/functions.glsl?raw' import parameters from './shaders/parameters.glsl?raw' import fragmentShader from './shaders/stars.frag?raw' import vertexShader from './shaders/stars.vert?raw' declare module 'three' { interface Camera { isPerspectiveCamera?: boolean } } export interface StarsMaterialParameters extends AtmosphereMaterialBaseParameters { pointSize?: number radianceScale?: number background?: boolean } export const starsMaterialParametersDefaults = { ...atmosphereMaterialParametersBaseDefaults, pointSize: 1, radianceScale: 1, background: true } satisfies StarsMaterialParameters export interface StarsMaterialUniforms { [key: string]: Uniform<unknown> projectionMatrix: Uniform<Matrix4> modelViewMatrix: Uniform<Matrix4> viewMatrix: Uniform<Matrix4> matrixWorld: Uniform<Matrix4> cameraFar: Uniform<number> pointSize: Uniform<number> magnitudeRange: Uniform<Vector2> radianceScale: Uniform<number> } export class StarsMaterial extends AtmosphereMaterialBase { declare uniforms: AtmosphereMaterialBaseUniforms & StarsMaterialUniforms pointSize: number constructor(params?: StarsMaterialParameters) { const { pointSize, radianceScale, background, ...others } = { ...starsMaterialParametersDefaults, ...params } super({ name: 'StarsMaterial', glslVersion: GLSL3, vertexShader: resolveIncludes(vertexShader, { parameters }), fragmentShader: resolveIncludes(fragmentShader, { parameters, functions }), ...others, uniforms: { projectionMatrix: new Uniform(new Matrix4()), modelViewMatrix: new Uniform(new Matrix4()), viewMatrix: new Uniform(new Matrix4()), matrixWorld: new Uniform(new Matrix4()), cameraFar: new Uniform(0), pointSize: new Uniform(0), magnitudeRange: new Uniform(new Vector2(-2, 8)), radianceScale: new Uniform(radianceScale), ...others.uniforms } satisfies StarsMaterialUniforms, defines: { PERSPECTIVE_CAMERA: '1' } }) this.pointSize = pointSize this.background = background } override onBeforeRender( renderer: WebGLRenderer, scene: Scene, camera: PerspectiveCamera | OrthographicCamera, geometry: BufferGeometry, object: Object3D, group: Group ): void { super.onBeforeRender(renderer, scene, camera, geometry, object, group) const uniforms = this.uniforms uniforms.projectionMatrix.value.copy(camera.projectionMatrix) uniforms.modelViewMatrix.value.copy(camera.modelViewMatrix) uniforms.viewMatrix.value.copy(camera.matrixWorldInverse) uniforms.matrixWorld.value.copy(object.matrixWorld) uniforms.cameraFar.value = camera.far uniforms.pointSize.value = this.pointSize * renderer.getPixelRatio() const isPerspectiveCamera = camera.isPerspectiveCamera === true if ((this.defines.PERSPECTIVE_CAMERA != null) !== isPerspectiveCamera) { if (isPerspectiveCamera) { this.defines.PERSPECTIVE_CAMERA = '1' } else { delete this.defines.PERSPECTIVE_CAMERA } this.needsUpdate = true } } get magnitudeRange(): Vector2 { return this.uniforms.magnitudeRange.value } get radianceScale(): number { return this.uniforms.radianceScale.value } set radianceScale(value: number) { this.uniforms.radianceScale.value = value } @define('BACKGROUND') background: boolean }