diff --git a/src/core/QuadRenderer.ts b/src/core/QuadRenderer.ts index 5100b54..f662305 100644 --- a/src/core/QuadRenderer.ts +++ b/src/core/QuadRenderer.ts @@ -1,19 +1,19 @@ import { ByteType, + ClampToEdgeWrapping, ColorSpace, DataTexture, FloatType, HalfFloatType, IntType, LinearFilter, - LinearMipMapLinearFilter, LinearSRGBColorSpace, Material, Mesh, MeshBasicMaterial, OrthographicCamera, PlaneGeometry, - RepeatWrapping, + RenderTargetOptions, RGBAFormat, Scene, ShaderMaterial, @@ -26,6 +26,8 @@ import { WebGLRenderer, WebGLRenderTarget } from 'three' + +import { QuadRendererTextureOptions } from './types' /** * Utility Type that translates `three` texture types to their TypedArray counterparts. * @@ -42,6 +44,37 @@ export type TextureDataTypeToBufferType = TType extends typeof FloatType ? Float32Array : never +export type QuadRendererOptions = { + /** + * Width of the render target + */ + width: number + /** + * height of the renderTarget + */ + height: number + /** + * TextureDataType of the renderTarget + */ + type: TType + /** + * ColorSpace of the renderTarget + */ + colorSpace: ColorSpace + /** + * material to use for rendering + */ + material: TMaterial + /** + * Renderer instance to use + */ + renderer?: WebGLRenderer + /** + * Additional renderTarget options + */ + renderTargetOptions?: QuadRendererTextureOptions +} + const getBufferForType = (type: TextureDataType, width: number, height: number) => { let out: ArrayLike switch (type) { @@ -82,23 +115,13 @@ let _canReadPixelsResult: boolean | undefined * @param type * @param renderer * @param camera + * @param renderTargetOptions * @returns */ -const canReadPixels = (type: TextureDataType, renderer: WebGLRenderer, camera: OrthographicCamera) => { +const canReadPixels = (type: TextureDataType, renderer: WebGLRenderer, camera: OrthographicCamera, renderTargetOptions: RenderTargetOptions) => { if (_canReadPixelsResult !== undefined) return _canReadPixelsResult - const testRT = new WebGLRenderTarget(1, 1, { - type, - colorSpace: LinearSRGBColorSpace, - format: RGBAFormat, - magFilter: LinearFilter, - minFilter: LinearFilter, - wrapS: RepeatWrapping, - wrapT: RepeatWrapping, - depthBuffer: false, - stencilBuffer: false, - generateMipmaps: true - }) + const testRT = new WebGLRenderTarget(1, 1, renderTargetOptions) renderer.setRenderTarget(testRT) const mesh = new Mesh(new PlaneGeometry(), new MeshBasicMaterial({ color: 0xffffff })) @@ -138,15 +161,32 @@ export class QuadRenderer) { + this._width = options.width + this._height = options.height + this._type = options.type + this._colorSpace = options.colorSpace - this._material = material - if (renderer) { - this._renderer = renderer + const rtOptions: RenderTargetOptions = { + // fixed options + format: RGBAFormat, + depthBuffer: false, + stencilBuffer: false, + // user options + type: this._type, // set in class property + colorSpace: this._colorSpace, // set in class property + anisotropy: options.renderTargetOptions?.anisotropy !== undefined ? options.renderTargetOptions?.anisotropy : 1, + generateMipmaps: options.renderTargetOptions?.generateMipmaps !== undefined ? options.renderTargetOptions?.generateMipmaps : false, + magFilter: options.renderTargetOptions?.magFilter !== undefined ? options.renderTargetOptions?.magFilter : LinearFilter, + minFilter: options.renderTargetOptions?.minFilter !== undefined ? options.renderTargetOptions?.minFilter : LinearFilter, + samples: options.renderTargetOptions?.samples !== undefined ? options.renderTargetOptions?.samples : undefined, + wrapS: options.renderTargetOptions?.wrapS !== undefined ? options.renderTargetOptions?.wrapS : ClampToEdgeWrapping, + wrapT: options.renderTargetOptions?.wrapT !== undefined ? options.renderTargetOptions?.wrapT : ClampToEdgeWrapping + } + + this._material = options.material + if (options.renderer) { + this._renderer = options.renderer } else { this._renderer = QuadRenderer.instantiateRenderer() this._rendererIsDisposable = true @@ -161,7 +201,7 @@ export class QuadRenderer & { + /** + * @defaultValue {@link UVMapping} + */ + mapping?: Mapping, + /** + * @defaultValue 1 + */ + anisotropy?: number +} diff --git a/src/decode/decode.ts b/src/decode/decode.ts index 3e764ed..aaade5f 100644 --- a/src/decode/decode.ts +++ b/src/decode/decode.ts @@ -83,9 +83,19 @@ export const decode = (params: DecodeParameters): InstanceType extends Loader, TUrl> { private _renderer: WebGLRenderer + private _renderTargetOptions?: QuadRendererTextureOptions /** * @private */ @@ -36,6 +37,17 @@ export class LoaderBase extends Loader extends Loader { const dataTexture = getDataTexture(image) - const sdr = getSDRRendition(dataTexture, renderer, params.toneMapping) + const sdr = getSDRRendition(dataTexture, renderer, params.toneMapping, params.renderTargetOptions) const gainMapRenderer = getGainMap({ ...params, diff --git a/src/encode/find-texture-min-max.ts b/src/encode/find-texture-min-max.ts index f96263b..674589e 100644 --- a/src/encode/find-texture-min-max.ts +++ b/src/encode/find-texture-min-max.ts @@ -91,14 +91,14 @@ export const findTextureMinMax = (image: EXR | RGBE | LogLuv | DataTexture, mode let w = srcTex.image.width let h = srcTex.image.height - const quadRenderer = new QuadRenderer( - w, - h, - srcTex.type, - srcTex.colorSpace, - mat, + const quadRenderer = new QuadRenderer({ + width: w, + height: h, + type: srcTex.type, + colorSpace: srcTex.colorSpace, + material: mat, renderer - ) + }) const frameBuffers: WebGLRenderTarget[] = [] diff --git a/src/encode/get-gainmap.ts b/src/encode/get-gainmap.ts index 10a3911..911e1d3 100644 --- a/src/encode/get-gainmap.ts +++ b/src/encode/get-gainmap.ts @@ -25,14 +25,15 @@ export const getGainMap = (params: { sdr: InstanceType } & hdr: dataTexture }) - const quadRenderer = new QuadRenderer( - dataTexture.image.width, - dataTexture.image.height, - UnsignedByteType, - LinearSRGBColorSpace, + const quadRenderer = new QuadRenderer({ + width: dataTexture.image.width, + height: dataTexture.image.height, + type: UnsignedByteType, + colorSpace: LinearSRGBColorSpace, material, - renderer - ) + renderer, + renderTargetOptions: params.renderTargetOptions + }) try { quadRenderer.render() } catch (e) { diff --git a/src/encode/get-sdr-rendition.ts b/src/encode/get-sdr-rendition.ts index 0d3db4d..4ff39b7 100644 --- a/src/encode/get-sdr-rendition.ts +++ b/src/encode/get-sdr-rendition.ts @@ -7,6 +7,7 @@ import { } from 'three' import { QuadRenderer } from '../core/QuadRenderer' +import { QuadRendererTextureOptions } from '../decode' import { SDRMaterial } from './materials/SDRMaterial' /** @@ -18,18 +19,20 @@ import { SDRMaterial } from './materials/SDRMaterial' * @param hdrTexture The HDR image to be rendered * @param renderer (optional) WebGLRenderer to use during the rendering, a disposable renderer will be create and destroyed if this is not provided. * @param toneMapping (optional) Tone mapping to be applied to the SDR Rendition + * @param renderTargetOptions (optional) Options to use when creating the output renderTarget * @throws {Error} if the WebGLRenderer fails to render the SDR image */ -export const getSDRRendition = (hdrTexture: DataTexture, renderer?: WebGLRenderer, toneMapping?: ToneMapping): InstanceType>> => { +export const getSDRRendition = (hdrTexture: DataTexture, renderer?: WebGLRenderer, toneMapping?: ToneMapping, renderTargetOptions?: QuadRendererTextureOptions): InstanceType>> => { hdrTexture.needsUpdate = true - const quadRenderer = new QuadRenderer( - hdrTexture.image.width, - hdrTexture.image.height, - UnsignedByteType, - SRGBColorSpace, - new SDRMaterial({ map: hdrTexture, toneMapping }), - renderer - ) + const quadRenderer = new QuadRenderer({ + width: hdrTexture.image.width, + height: hdrTexture.image.height, + type: UnsignedByteType, + colorSpace: SRGBColorSpace, + material: new SDRMaterial({ map: hdrTexture, toneMapping }), + renderer, + renderTargetOptions + }) try { quadRenderer.render() } catch (e) { diff --git a/src/encode/types.ts b/src/encode/types.ts index e45a7d4..c0c3dfd 100644 --- a/src/encode/types.ts +++ b/src/encode/types.ts @@ -3,6 +3,7 @@ import { type EXR } from 'three/examples/jsm/loaders/EXRLoader' import { type LogLuv } from 'three/examples/jsm/loaders/LogLuvLoader' import { type RGBE } from 'three/examples/jsm/loaders/RGBELoader' +import { QuadRendererTextureOptions } from '../decode' import { WorkerInterfaceImplementation } from '../worker-types' /** @@ -85,6 +86,10 @@ export type EncodingParametersBase = GainmapEncodingParameters & { * @defaultValue `ACESFilmicToneMapping` */ toneMapping?: ToneMapping + /** + * Options to use when creating the output renderTarget + */ + renderTargetOptions?: QuadRendererTextureOptions } /**