import { RegisterComponent } from '@feng3d/ecs'; import { ColorRepresentation, textureEncodingNames, textureEncodingValues, Vector2, WebGLRenderer, WebGLRendererParameters } from '../../thirdparty/three/imports'; import { Camera3D } from '../cameras/Camera3D'; import { Component3D } from '../core/Component3D'; import { Scene3D } from '../scenes/Scene3D'; import { Texture3D } from '../textures/Texture3D'; import { WebGLShadowMap3D } from './webgl/WebGLShadowMap3D'; import { WebGLRenderTarget3D } from './WebGLRenderTarget3D'; declare module '@feng3d/ecs' { interface ComponentMap { WebGLRenderer3D: WebGLRenderer3D; } } /** * 3D渲染器,包装`three`中`WebGLRenderer` */ @RegisterComponent({ name: 'WebGLRenderer3D' }) export class WebGLRenderer3D extends Component3D { /** * @private */ _webGLRenderer: WebGLRenderer; get size() { this._webGLRenderer?.getSize(this._size); return this._size; } set size(v) { this._size.set(v.x, v.y); this._webGLRenderer?.setSize(this._size.width, this._size.height); } private _size = new Vector2(); get pixelRatio() { if (this._webGLRenderer) { this._pixelRatio = this._webGLRenderer.getPixelRatio(); } return this._pixelRatio; } set pixelRatio(v) { this._pixelRatio = v; this._webGLRenderer?.setPixelRatio(v); } private _pixelRatio: number; get domElement() { return this._webGLRenderer.domElement; } get outputEncoding() { return textureEncodingNames[this._webGLRenderer.outputEncoding]; } set outputEncoding(v) { this._webGLRenderer.outputEncoding = textureEncodingValues[v]; } get physicallyCorrectLights() { return this._webGLRenderer.physicallyCorrectLights; } set physicallyCorrectLights(v) { this._webGLRenderer.physicallyCorrectLights = v; } get shadowMap() { const webGLShadowMap3D = WebGLShadowMap3D.get(this._webGLRenderer.shadowMap); return webGLShadowMap3D; } set shadowMap(v) { this._webGLRenderer.shadowMap = v._webGLShadowMap; } get autoClear() { return this._webGLRenderer.autoClear; } set autoClear(v) { this._webGLRenderer.autoClear = v; } get clippingPlanes() { return this._webGLRenderer.clippingPlanes; } set clippingPlanes(v) { this._webGLRenderer.clippingPlanes = v; } get localClippingEnabled() { return this._webGLRenderer.localClippingEnabled; } set localClippingEnabled(v) { this._webGLRenderer.localClippingEnabled = v; } get capabilities() { return this._webGLRenderer.capabilities; } set capabilities(v) { this._webGLRenderer.capabilities = v; } get extensions() { return this._webGLRenderer.extensions; } set extensions(v) { this._webGLRenderer.extensions = v; } /** * WebGLRenderer初始参数。 * * 注:只在初始化时生效。 */ parameters?: WebGLRendererParameters; init() { super.init(); this._webGLRenderer = new WebGLRenderer(this.parameters); if (this._size.lengthSq() > 0) { this._webGLRenderer.setSize(this._size.width, this._size.height); } if (this._pixelRatio !== undefined) { this._webGLRenderer?.setPixelRatio(this._pixelRatio); } } destroy(): void { this._webGLRenderer = null; super.destroy(); } render(scene: Scene3D, camera: Camera3D) { // 修复渲染前更新摄像机矩阵数据 // @see https://github.com/mrdoob/three.js/blob/r149/src/renderers/WebGLRenderer.js#L963 camera.updateMatrixWorld(); // this._webGLRenderer.render(scene._scene, camera._camera); } clear() { this._webGLRenderer.clear(); } clearDepth() { this._webGLRenderer.clearDepth(); } setPixelRatio(value: number) { this._webGLRenderer.setPixelRatio(value); } setSize(width: number, height: number, updateStyle?: boolean) { this._webGLRenderer.setSize(width, height, updateStyle); } setViewport(x: number, y?: number, width?: number, height?: number) { this._webGLRenderer.setViewport(x, y, width, height); } setClearColor(color: ColorRepresentation, alpha?: number) { this._webGLRenderer.setClearColor(color, alpha); } setRenderTarget(renderTarget: WebGLRenderTarget3D, activeCubeFace?: number, activeMipmapLevel?: number) { this._webGLRenderer.setRenderTarget(renderTarget ? renderTarget._target : null, activeCubeFace, activeMipmapLevel); } clearStencil() { this._webGLRenderer.clearStencil(); } getPixelRatio() { return this._webGLRenderer.getPixelRatio(); } copyFramebufferToTexture(position: Vector2, texture: Texture3D, level?: number) { this._webGLRenderer.copyFramebufferToTexture(position, texture._texture, level); } }