Skip to content

Commit

Permalink
Feat: support read/write mipmap data from textures and render target (g…
Browse files Browse the repository at this point in the history
…alacean#382)

* feat: support render to mip level

* feat: support reading from texture with mip level
  • Loading branch information
zhuxudong authored Oct 11, 2021
1 parent 0dc19c7 commit a751e6d
Show file tree
Hide file tree
Showing 18 changed files with 247 additions and 160 deletions.
10 changes: 8 additions & 2 deletions packages/core/src/Camera.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BoundingFrustum, MathUtil, Matrix, Ray, Vector2, Vector3, Vector4 } from "@oasis-engine/math";
import { Logger } from "./base";
import { deepClone, ignoreClone } from "./clone/CloneManager";
import { Component } from "./Component";
import { dependencies } from "./ComponentsDependencies";
Expand Down Expand Up @@ -414,8 +415,9 @@ export class Camera extends Component {
/**
* Manually call the rendering of the camera.
* @param cubeFace - Cube rendering surface collection
* @param mipLevel - Set mip level the data want to write, only take effect in webgl2.0
*/
render(cubeFace?: TextureCubeFace): void {
render(cubeFace?: TextureCubeFace, mipLevel: number = 0): void {
// compute cull frustum.
const context = this.engine._renderContext;
context._setContext(this);
Expand All @@ -434,7 +436,11 @@ export class Camera extends Component {
this._globalShaderMacro
);

this._renderPipeline.render(context, cubeFace);
if (mipLevel > 0 && !this.engine._hardwareRenderer.isWebGL2) {
mipLevel = 0;
Logger.error("mipLevel only take effect in WebGL2.0");
}
this._renderPipeline.render(context, cubeFace, mipLevel);
this._engine._renderCount++;
}

Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/RenderPipeline/BasicRenderPipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,9 @@ export class BasicRenderPipeline {
* Perform scene rendering.
* @param context - Render context
* @param cubeFace - Render surface of cube texture
* @param mipLevel - Set mip level the data want to write
*/
render(context: RenderContext, cubeFace?: TextureCubeFace) {
render(context: RenderContext, cubeFace?: TextureCubeFace, mipLevel?: number) {
const camera = this._camera;
const opaqueQueue = this._opaqueQueue;
const alphaTestQueue = this._alphaTestQueue;
Expand All @@ -154,20 +155,20 @@ export class BasicRenderPipeline {
transparentQueue.sort(RenderQueue._compareFromFarToNear);

for (let i = 0, len = this._renderPassArray.length; i < len; i++) {
this._drawRenderPass(this._renderPassArray[i], camera, cubeFace);
this._drawRenderPass(this._renderPassArray[i], camera, cubeFace, mipLevel);
}
}

private _drawRenderPass(pass: RenderPass, camera: Camera, cubeFace?: TextureCubeFace) {
private _drawRenderPass(pass: RenderPass, camera: Camera, cubeFace?: TextureCubeFace, mipLevel?: number) {
pass.preRender(camera, this._opaqueQueue, this._alphaTestQueue, this._transparentQueue);

if (pass.enabled) {
const { engine, scene } = camera;
const { background } = scene;
const rhi = engine._hardwareRenderer;
const renderTarget = camera.renderTarget || pass.renderTarget;
rhi.activeRenderTarget(renderTarget, camera);
renderTarget?._setRenderTargetFace(cubeFace);
rhi.activeRenderTarget(renderTarget, camera, mipLevel); // change viewport with mip level
renderTarget?._setRenderTargetInfo(cubeFace, mipLevel);
const clearFlags = pass.clearFlags ?? camera.clearFlags;
const color = pass.clearColor ?? background.solidColor;
if (clearFlags !== CameraClearFlags.None) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface IPlatformRenderColorTexture extends IPlatformTexture {
* @param y - Y coordinate of area start
* @param width - Area width
* @param height - Area height
* @param mipLevel - Set mip level the data want to get from
* @param out - Color buffer
*/
getPixelBuffer(
Expand All @@ -20,6 +21,7 @@ export interface IPlatformRenderColorTexture extends IPlatformTexture {
y: number,
width: number,
height: number,
mipLevel: number,
out: ArrayBufferView
): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { TextureCubeFace } from "../texture";
*/
export interface IPlatformRenderTarget {
/**
* Set which face of the cube texture to render to.
* Set which face and mipLevel of the cube texture to render to.
* @param faceIndex - Cube texture face
* @param mipLevel - Set mip level the data want to write
*/
setRenderTargetFace(faceIndex: TextureCubeFace): void;
setRenderTargetInfo(faceIndex: TextureCubeFace, mipLevel: number): void;

/**
* Blit FBO.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export interface IPlatformTexture2D extends IPlatformTexture {
* @param y - Y coordinate of area start
* @param width - Area width
* @param height - Area height
* @param mipLevel - Set mip level the data want to get from
* @param out - Color buffer
*/
getPixelBuffer(x: number, y: number, width: number, height: number, out: ArrayBufferView): void;
getPixelBuffer(x: number, y: number, width: number, height: number, mipLevel: number, out: ArrayBufferView): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface IPlatformTextureCubeMap extends IPlatformTexture {
* @param y - Y coordinate of area start
* @param width - Area width
* @param height - Area height
* @param mipLevel - Set mip level the data want to get from
* @param out - Color buffer
*/
getPixelBuffer(
Expand All @@ -61,6 +62,7 @@ export interface IPlatformTextureCubeMap extends IPlatformTexture {
y: number,
width: number,
height: number,
mipLevel: number,
out: ArrayBufferView
): void;
}
4 changes: 3 additions & 1 deletion packages/core/src/texture/RenderColorTexture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export class RenderColorTexture extends Texture {
* @param y - Y coordinate of area start
* @param width - Area width
* @param height - Area height
* @param mipLevel - Set mip level the data want to get from
* @param out - Color buffer
*/
public getPixelBuffer(
Expand All @@ -86,8 +87,9 @@ export class RenderColorTexture extends Texture {
y: number,
width: number,
height: number,
mipLevel: number = 0,
out: ArrayBufferView
): void {
(this._platformTexture as IPlatformRenderColorTexture).getPixelBuffer(face, x, y, width, height, out);
(this._platformTexture as IPlatformRenderColorTexture).getPixelBuffer(face, x, y, width, height, mipLevel, out);
}
}
4 changes: 2 additions & 2 deletions packages/core/src/texture/RenderTarget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ export class RenderTarget extends EngineObject {
/**
* @internal
*/
_setRenderTargetFace(faceIndex: TextureCubeFace): void {
this._platformRenderTarget.setRenderTargetFace(faceIndex);
_setRenderTargetInfo(faceIndex: TextureCubeFace, mipLevel: number): void {
this._platformRenderTarget.setRenderTargetInfo(faceIndex, mipLevel);
}

/**
Expand Down
74 changes: 72 additions & 2 deletions packages/core/src/texture/Texture2D.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ export class Texture2D extends Texture {
(this._platformTexture as IPlatformTexture2D).setImageSource(imageSource, mipLevel, flipY, premultiplyAlpha, x, y);
}

/**
* Get pixel color buffer.
* @param out - Color buffer
*/
getPixelBuffer(out: ArrayBufferView): void;

/**
* Get the pixel color buffer according to the specified mip level.
* @param mipLevel - Tet mip level want to get
* @param out - Color buffer
*/
getPixelBuffer(mipLevel: number, out: ArrayBufferView): void;

/**
* Get the pixel color buffer according to the specified area.
* @param x - X coordinate of area start
Expand All @@ -95,7 +108,64 @@ export class Texture2D extends Texture {
* @param height - Area height
* @param out - Color buffer
*/
getPixelBuffer(x: number, y: number, width: number, height: number, out: ArrayBufferView): void {
(this._platformTexture as IPlatformTexture2D).getPixelBuffer(x, y, width, height, out);
getPixelBuffer(x: number, y: number, width: number, height: number, out: ArrayBufferView): void;

/**
* Get the pixel color buffer according to the specified area and mip level.
* @param x - X coordinate of area start
* @param y - Y coordinate of area start
* @param width - Area width
* @param height - Area height
* @param mipLevel - Tet mip level want to get
* @param out - Color buffer
*/
getPixelBuffer(x: number, y: number, width: number, height: number, mipLevel: number, out: ArrayBufferView): void;

getPixelBuffer(
xOrMipLevelOrOut: number | ArrayBufferView,
yOrMipLevel?: number | ArrayBufferView,
width?: number,
height?: number,
mipLevelOrOut?: number | ArrayBufferView,
out?: ArrayBufferView
): void {
const argsLength = arguments.length;
if (argsLength === 1) {
(this._platformTexture as IPlatformTexture2D).getPixelBuffer(
0,
0,
this._width,
this._height,
0,
<ArrayBufferView>xOrMipLevelOrOut
);
} else if (argsLength === 2) {
(this._platformTexture as IPlatformTexture2D).getPixelBuffer(
0,
0,
this._width,
this._height,
<number>xOrMipLevelOrOut,
<ArrayBufferView>yOrMipLevel
);
} else if (argsLength === 5) {
(this._platformTexture as IPlatformTexture2D).getPixelBuffer(
<number>xOrMipLevelOrOut,
<number>yOrMipLevel,
width,
height,
0,
<ArrayBufferView>mipLevelOrOut
);
} else if (argsLength === 6) {
(this._platformTexture as IPlatformTexture2D).getPixelBuffer(
<number>xOrMipLevelOrOut,
<number>yOrMipLevel,
width,
height,
<number>mipLevelOrOut,
out
);
}
}
}
105 changes: 0 additions & 105 deletions packages/core/src/texture/Texture2DArray.ts

This file was deleted.

Loading

0 comments on commit a751e6d

Please sign in to comment.