Przeglądaj źródła

Implement RenderManager.clearColor, add support for blending and transparent in RenderManager.blit, Add generic return type in RenderTargetManager.getTempTarget

master
Palash Bansal 3 lat temu
rodzic
commit
f595dd7ddb
No account linked to committer's email address

+ 104
- 26
src/rendering/RenderManager.ts Wyświetl plik

import { import {
Blending,
Color,
HalfFloatType, HalfFloatType,
IUniform, IUniform,
NoBlending,
NoColorSpace, NoColorSpace,
NormalBlending,
NoToneMapping, NoToneMapping,
PCFShadowMap, PCFShadowMap,
ShaderMaterial, ShaderMaterial,
return string return string
} }


renderTargetToBuffer(target: WebGLRenderTarget): Uint8Array|Uint16Array {
const buffer = target.texture.type === HalfFloatType ?
new Uint16Array(target.width * target.height * 4) :
new Uint8Array(target.width * target.height * 4)
this._renderer.readRenderTargetPixels(target, 0, 0, target.width, target.height, buffer)
return buffer
}


// endregion // endregion


get totalFrameCount(): number { get totalFrameCount(): number {
return this._totalFrameCount return this._totalFrameCount
} }
resetTotalFrameCount(): void {
this._totalFrameCount = 0
}
set pipeline(value: IPassID[]) { set pipeline(value: IPassID[]) {
this._pipeline = value this._pipeline = value
if (this.autoBuildPipeline) { if (this.autoBuildPipeline) {
// / TODO // / TODO





blit(destination: IRenderTarget|undefined|null, {source, viewport, material, clear = true, respectColorSpace = false}: {source?: Texture, viewport?: Vector4, material?: ShaderMaterial, clear?: boolean, respectColorSpace?: boolean} = {}): void {
/**
*
* @param destination - destination target, or screen if undefined or null
* @param source - source Texture
* @param viewport - viewport and scissor
* @param material - override material
* @param clear - clear before blit
* @param respectColorSpace - does color space conversion when reading and writing to the target
* @param blending - Note - Set to NormalBlending if transparent is set to false
* @param transparent
*/
blit(destination: IRenderTarget|undefined|null, {source, viewport, material, clear = true, respectColorSpace = false, blending = NoBlending, transparent = true}: {source?: Texture, viewport?: Vector4, material?: ShaderMaterial, clear?: boolean, respectColorSpace?: boolean, blending?: Blending, transparent?: boolean} = {}): void {
const copyPass = !respectColorSpace ? this._composer.copyPass : this._composer.copyPass2 const copyPass = !respectColorSpace ? this._composer.copyPass : this._composer.copyPass2
const {renderToScreen, material: oldMaterial, uniforms: oldUniforms, clear: oldClear} = copyPass const {renderToScreen, material: oldMaterial, uniforms: oldUniforms, clear: oldClear} = copyPass
if (material) { if (material) {
copyPass.material = material copyPass.material = material
} }
const oldViewport = this._renderer.getViewport(new Vector4())
const oldScissor = this._renderer.getScissor(new Vector4())
const oldScissorTest = this._renderer.getScissorTest()
const oldTransparent = copyPass.material.transparent
const oldViewport = !destination ? this._renderer.getViewport(new Vector4()) : destination.viewport.clone()
const oldScissor = !destination ? this._renderer.getScissor(new Vector4()) : destination.scissor.clone()
const oldScissorTest = !destination ? this._renderer.getScissorTest() : destination.scissorTest
const oldAutoClear = this._renderer.autoClear const oldAutoClear = this._renderer.autoClear
const oldTarget = this._renderer.getRenderTarget() const oldTarget = this._renderer.getRenderTarget()
if (viewport) this._renderer.setViewport(viewport)
if (viewport) this._renderer.setScissor(viewport)
if (viewport) this._renderer.setScissorTest(true)
const oldBlending = copyPass.material.blending

if (viewport) {
if (!destination) {
this._renderer.setViewport(viewport)
this._renderer.setScissor(viewport)
this._renderer.setScissorTest(true)
} else {
destination.viewport.copy(viewport)
destination.scissor.copy(viewport)
destination.scissorTest = true
}
}
this._renderer.autoClear = false this._renderer.autoClear = false
copyPass.material.blending = !transparent ? NormalBlending : blending
copyPass.uniforms = copyPass.material.uniforms copyPass.uniforms = copyPass.material.uniforms
copyPass.renderToScreen = false copyPass.renderToScreen = false
copyPass.clear = clear copyPass.clear = clear
copyPass.material.transparent = transparent
copyPass.material.needsUpdate = true

this._renderer.renderWithModes({ this._renderer.renderWithModes({
sceneRender: true, sceneRender: true,
opaqueRender: true, opaqueRender: true,
copyPass.clear = oldClear copyPass.clear = oldClear
copyPass.material = oldMaterial copyPass.material = oldMaterial
copyPass.uniforms = oldUniforms copyPass.uniforms = oldUniforms
copyPass.material.blending = oldBlending
copyPass.material.transparent = oldTransparent
this._renderer.autoClear = oldAutoClear this._renderer.autoClear = oldAutoClear
if (viewport) this._renderer.setViewport(oldViewport)
if (viewport) this._renderer.setScissor(oldScissor)
if (viewport) this._renderer.setScissorTest(oldScissorTest)
if (viewport) {
if (!destination) {
this._renderer.setViewport(oldViewport)
this._renderer.setScissor(oldScissor)
this._renderer.setScissorTest(oldScissorTest)
} else {
destination.viewport.copy(oldViewport)
destination.scissor.copy(oldScissor)
destination.scissorTest = oldScissorTest
}
}
this._renderer.setRenderTarget(oldTarget) // todo: active cubeface etc this._renderer.setRenderTarget(oldTarget) // todo: active cubeface etc
} }


// clearColor({r, g, b, a, target, depth = true, stencil = true}:
// {r?: number, g?: number, b?: number, a?: number, target?: IRenderTarget, depth?: boolean, stencil?: boolean}): void {
// const color = this._renderer.getClearColor(new Color())
// const alpha = this._renderer.getClearAlpha()
// this._renderer.setClearAlpha(a ?? alpha)
// this._renderer.setClearColor(new Color(r ?? color.r, g ?? color.g, b ?? color.b))
// const lastTarget = this._renderer.getRenderTarget()
// const activeCubeFace = this._renderer.getActiveCubeFace()
// const activeMipLevel = this._renderer.getActiveMipmapLevel()
// this._renderer.setRenderTarget((target as WebGLRenderTarget) ?? null)
// this._renderer.clear(true, depth, stencil)
// this._renderer.setRenderTarget(lastTarget, activeCubeFace, activeMipLevel)
// this._renderer.setClearColor(color)
// this._renderer.setClearAlpha(alpha)
// }
clearColor({r, g, b, a, target, depth = true, stencil = true, viewport}:
{r?: number, g?: number, b?: number, a?: number, target?: IRenderTarget, depth?: boolean, stencil?: boolean, viewport?: Vector4}): void {
const color = this._renderer.getClearColor(new Color())
const alpha = this._renderer.getClearAlpha()
this._renderer.setClearAlpha(a ?? alpha)
this._renderer.setClearColor(new Color(r ?? color.r, g ?? color.g, b ?? color.b))
const lastTarget = this._renderer.getRenderTarget()
const activeCubeFace = this._renderer.getActiveCubeFace()
const activeMipLevel = this._renderer.getActiveMipmapLevel()

const oldViewport = !target ? this._renderer.getViewport(new Vector4()) : target.viewport.clone()
const oldScissor = !target ? this._renderer.getScissor(new Vector4()) : target.scissor.clone()
const oldScissorTest = !target ? this._renderer.getScissorTest() : target.scissorTest
if (viewport) {
if (!target) {
this._renderer.setViewport(viewport)
this._renderer.setScissor(viewport)
this._renderer.setScissorTest(true)
} else {
target.viewport.copy(viewport)
target.scissor.copy(viewport)
target.scissorTest = true
}
}

this._renderer.setRenderTarget((target as WebGLRenderTarget) ?? null)
this._renderer.clear(true, depth, stencil)

if (viewport) {
if (!target) {
this._renderer.setViewport(oldViewport)
this._renderer.setScissor(oldScissor)
this._renderer.setScissorTest(oldScissorTest)
} else {
target.viewport.copy(oldViewport)
target.scissor.copy(oldScissor)
target.scissorTest = oldScissorTest
}
}

this._renderer.setRenderTarget(lastTarget, activeCubeFace, activeMipLevel)
this._renderer.setClearColor(color)
this._renderer.setClearAlpha(alpha)
}




/** /**

+ 31
- 2
src/rendering/RenderTarget.ts Wyświetl plik

Texture, Texture,
TextureDataType, TextureDataType,
} from 'three' } from 'three'
import {Vector4} from 'three/src/math/Vector4'
import {DepthTexture} from 'three/src/textures/DepthTexture'


export interface IRenderTarget extends EventDispatcher { export interface IRenderTarget extends EventDispatcher {
texture: Texture | Texture[] texture: Texture | Texture[]
clone(trackTarget?: boolean): this clone(trackTarget?: boolean): this
setSize(width: number, height: number, depth?: number): void; setSize(width: number, height: number, depth?: number): void;
dispose(): void; dispose(): void;
samples: number

scissor: Vector4;
/**
* @default false
*/
scissorTest: boolean;
viewport: Vector4;

/**
* @default true
*/
depthBuffer: boolean;

/**
* @default true
*/
stencilBuffer: boolean;

/**
* @default null
*/
depthTexture: DepthTexture;
/**
* Defines the count of MSAA samples. Can only be used with WebGL 2. Default is **0**.
* @default 0
*/
samples: number;

} }


export interface CreateRenderTargetOptions { export interface CreateRenderTargetOptions {


export function createRenderTargetKey(op: CreateRenderTargetOptions = {}): string { export function createRenderTargetKey(op: CreateRenderTargetOptions = {}): string {
// colorSpace is in key because of ext_sRGB // colorSpace is in key because of ext_sRGB
return [op.sizeMultiplier, op.samples, op.colorSpace, op.type, op.format, op.depthBuffer, op.depthTexture, op.size?.width, op.size?.height].join(';')
return [op.sizeMultiplier, op.samples, op.colorSpace, op.type, op.format, op.depthBuffer, op.depthTexture, op.textureCount, op.size?.width, op.size?.height].join(';')
} }

+ 4
- 4
src/rendering/RenderTargetManager.ts Wyświetl plik

target.dispose() target.dispose()
} }


getTempTarget(op: CreateRenderTargetOptions = {}): IRenderTarget {
getTempTarget<T extends IRenderTarget = IRenderTarget>(op: CreateRenderTargetOptions = {}): T {
const key = createRenderTargetKey(op) const key = createRenderTargetKey(op)
let target: IRenderTarget | undefined
if (this._releasedTempTargets[key]?.length) target = this._releasedTempTargets[key].pop()
let target: T | undefined
if (this._releasedTempTargets[key]?.length) target = this._releasedTempTargets[key].pop() as T
if (!target) { if (!target) {
target = this.createTarget(op)
target = this.createTarget<T>(op)
this._processNewTempTarget(target, key) this._processNewTempTarget(target, key)
} else { } else {
this._setTargetOptions(target, op) this._setTargetOptions(target, op)

Ładowanie…
Anuluj
Zapisz