Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Camera support opaque texture #1989

Merged
merged 46 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
361670a
refactor: add temp code
GuoLei1990 Jan 31, 2024
cceb94f
refactor: opt comments
GuoLei1990 Jan 31, 2024
7be18e3
refactor: opt code
GuoLei1990 Jan 31, 2024
62ec7c5
refactor: opt code
GuoLei1990 Jan 31, 2024
77503bc
refactor: opt code
GuoLei1990 Jan 31, 2024
a49bcff
refactor: opt code
GuoLei1990 Jan 31, 2024
489befa
refactor: opt code
GuoLei1990 Jan 31, 2024
30aceb5
refactor: opt code
GuoLei1990 Jan 31, 2024
d2cbcdf
refactor: opt code
GuoLei1990 Jan 31, 2024
5a7afc1
refactor: opt code
GuoLei1990 Jan 31, 2024
941b87c
refactor: opt code
GuoLei1990 Jan 31, 2024
c987248
refactor: opt code
GuoLei1990 Feb 1, 2024
2067323
refactor: opt code
GuoLei1990 Feb 1, 2024
5b9d90b
refactor: opt code
GuoLei1990 Feb 2, 2024
be99a30
feat: Camera support `MSAASamples`
GuoLei1990 Feb 17, 2024
b1f9b52
refactor: opt API
GuoLei1990 Feb 18, 2024
bbf7cf2
refactor: opt webgl command count
GuoLei1990 Feb 18, 2024
f47db49
refactor: opt code
GuoLei1990 Feb 18, 2024
da706c9
refactor: opt code
GuoLei1990 Feb 18, 2024
931855c
refactor: opt code
GuoLei1990 Feb 18, 2024
72a95c4
refactor: opt API
GuoLei1990 Feb 19, 2024
9eda8c2
refactor: opt code
GuoLei1990 Feb 19, 2024
69904ac
refactor: deprecate `RenderBufferDepthFormat`
GuoLei1990 Feb 20, 2024
5e7f8fa
refactor: opt RenderTarget depth Texture
GuoLei1990 Feb 20, 2024
aad4a69
Merge branch 'dev/1.2' of github.com:galacean/engine into pr/camera-o…
GuoLei1990 Feb 20, 2024
baa5fda
refactor: fix lint
GuoLei1990 Feb 20, 2024
73cc6df
feat: add `opaqueTextureDownsampling`
GuoLei1990 Feb 22, 2024
ce7e908
refactor: support opaque texture downsample
GuoLei1990 Feb 22, 2024
38e80eb
refactor: blit support miplevel
GuoLei1990 Feb 22, 2024
a2b248f
refactor: opt shader property
GuoLei1990 Feb 23, 2024
2baef28
refactor: opt code and comments
GuoLei1990 Feb 23, 2024
b5229a8
refactor: opt code
GuoLei1990 Feb 23, 2024
71bf9dd
refactor: opt code
GuoLei1990 Feb 23, 2024
0fcf77d
refactor: clear code
GuoLei1990 Feb 26, 2024
ecb402a
Merge branch 'dev/1.2' into pr/camera-opaque-texture
GuoLei1990 Feb 26, 2024
73b8e81
test: add e2e test
GuoLei1990 Feb 26, 2024
04fcbd8
Merge branch 'dev/1.2' into pr/camera-opaque-texture
GuoLei1990 Feb 28, 2024
a5f7fd0
refactor: remove force clear color when blit
GuoLei1990 Feb 28, 2024
6d95d25
fix: opaque texture inverse Y
GuoLei1990 Feb 28, 2024
2e8346f
refactor: opt code
GuoLei1990 Mar 4, 2024
6d998b6
fix: renderTarget viewport when flip projection
GuoLei1990 Mar 4, 2024
b65c413
fix: textureCube render error
GuoLei1990 Mar 4, 2024
ab4e4e4
refactor: opt warnning
GuoLei1990 Mar 5, 2024
59b0cf1
fix: memory leak bug
GuoLei1990 Mar 5, 2024
18ba0f9
refactor: opt code
GuoLei1990 Mar 5, 2024
ddab8c9
refactor: opt code
GuoLei1990 Mar 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions e2e/case/camera-opaque-texture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* @title Opaque Texture
* @category Camera
*/
import {
Animator,
BaseMaterial,
Camera,
DirectLight,
Engine,
Entity,
GLTFResource,
Logger,
MeshRenderer,
PrimitiveMesh,
RenderFace,
Shader,
Vector3,
WebGLEngine
} from "@galacean/engine";
import { OrbitControl } from "@galacean/engine-toolkit";
import { initScreenshot, updateForE2E } from "./.mockForE2E";

Logger.enable();
WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
engine.canvas.resizeByClientSize(2);
const scene = engine.sceneManager.activeScene;
const rootEntity = scene.createRootEntity();

// camera
const cameraEntity = rootEntity.createChild("camera_node");
cameraEntity.transform.position = new Vector3(0, 1, 3);
const camera = cameraEntity.addComponent(Camera);
cameraEntity.addComponent(OrbitControl).target = new Vector3(0, 1, 0);
camera.opaqueTextureEnabled = true;

const lightNode = rootEntity.createChild("light_node");
lightNode.addComponent(DirectLight).intensity = 0.6;
lightNode.transform.lookAt(new Vector3(0, 0, 1));
lightNode.transform.rotate(new Vector3(0, 90, 0));

engine.resourceManager
.load<GLTFResource>("https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb")
.then((gltfResource) => {
const { defaultSceneRoot } = gltfResource;
rootEntity.addChild(defaultSceneRoot);
const animator = defaultSceneRoot.getComponent(Animator);
animator.play("agree");

showDepthPlane(engine, cameraEntity);


updateForE2E(engine);

initScreenshot(engine, camera);
});
});

function showDepthPlane(engine: Engine, camera: Entity): void {
const entity = camera.createChild("Plane");
entity.transform.setPosition(0, 0, -1);
entity.transform.rotate(new Vector3(-90, 0, 0));
const renderer = entity.addComponent(MeshRenderer);
renderer.mesh = PrimitiveMesh.createPlane(engine, 0.5, 0.5);

// Create material
const material = new BaseMaterial(engine, Shader.find("RenderOpaqueTexture"));
material.renderFace = RenderFace.Double;
material.isTransparent = true;
renderer.setMaterial(material);
}

const renderOpaqueVS = `
#include <common>
#include <common_vert>
#include <blendShape_input>
#include <uv_share>
#include <FogVertexDeclaration>

void main() {
#include <begin_position_vert>
#include <blendShape_vert>
#include <skinning_vert>
#include <uv_vert>
#include <position_vert>

#include <FogVertex>
}`;

const renderOpaqueFS = `
#include <common>
#include <uv_share>
#include <FogFragmentDeclaration>

uniform sampler2D camera_OpaqueTexture;

void main() {
vec4 baseColor = texture2D(camera_OpaqueTexture, v_uv);
#ifndef ENGINE_IS_COLORSPACE_GAMMA
baseColor = gammaToLinear(baseColor);
#endif

gl_FragColor = baseColor;

#ifndef MATERIAL_IS_TRANSPARENT
gl_FragColor.a = 1.0;
#endif

#include <FogFragment>

#ifndef ENGINE_IS_COLORSPACE_GAMMA
gl_FragColor = linearToGamma(gl_FragColor);
#endif
}`;

Shader.create("RenderOpaqueTexture", renderOpaqueVS, renderOpaqueFS);
7 changes: 7 additions & 0 deletions e2e/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,12 @@ export const E2E_CONFIG = {
caseFileName: "primitive-torus",
threshold: 0.1
}
},
Camera: {
opaqueTexture: {
category: "Camera",
caseFileName: "camera-opaque-texture",
threshold: 0.1
}
}
};
3 changes: 3 additions & 0 deletions e2e/fixtures/originImage/Camera_camera-opaque-texture.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion packages/core/src/2d/sprite/SpriteRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,12 @@ export class SpriteRenderer extends Renderer {
/**
* @internal
*/
protected override _updateShaderData(context: RenderContext): void {
override _updateShaderData(context: RenderContext, onlyMVP: boolean): void {
if (onlyMVP) {
// @ts-ignore
this._updateMVPShaderData(context, Matrix._identity);
return;
}
// @ts-ignore
this._updateTransformShaderData(context, Matrix._identity);
}
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/2d/text/TextRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,12 @@ export class TextRenderer extends Renderer {
/**
* @internal
*/
protected override _updateShaderData(context: RenderContext): void {
override _updateShaderData(context: RenderContext, onlyMVP: boolean): void {
if (onlyMVP) {
// @ts-ignore
this._updateMVPShaderData(context, Matrix._identity);
return;
}
// @ts-ignore
this._updateTransformShaderData(context, Matrix._identity);
}
Expand Down
52 changes: 52 additions & 0 deletions packages/core/src/BasicResources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Engine } from "./Engine";
import { Buffer } from "./graphic/Buffer";
import { VertexElement } from "./graphic/VertexElement";
import { BufferBindFlag } from "./graphic/enums/BufferBindFlag";
import { BufferUsage } from "./graphic/enums/BufferUsage";
import { MeshTopology } from "./graphic/enums/MeshTopology";
import { VertexElementFormat } from "./graphic/enums/VertexElementFormat";
import { Material } from "./material";
import { ModelMesh } from "./mesh";
import { Shader } from "./shader/Shader";

/**
* @internal
*/
export class BasicResources {
readonly blitMesh: ModelMesh;
readonly flipYBlitMesh: ModelMesh;
readonly blitMaterial: Material;

constructor(engine: Engine) {
// prettier-ignore
const vertices = new Float32Array([
-1, -1, 0, 1, // left-bottom
1, -1, 1, 1, // right-bottom
-1, 1, 0, 0, // left-top
1, 1, 1, 0]); // right-top

// prettier-ignore
const flipYVertices = new Float32Array([
1, -1, 1, 0, // right-bottom
-1, -1, 0, 0, // left-bottom
1, 1, 1, 1, // right-top
-1, 1, 0, 1]); // left-top

const blitMaterial = new Material(engine, Shader.find("blit"));
blitMaterial.renderState.depthState.enabled = false;
blitMaterial.renderState.depthState.writeEnabled = false;

this.blitMesh = this._createBlitMesh(engine, vertices);
this.flipYBlitMesh = this._createBlitMesh(engine, flipYVertices);
this.blitMaterial = blitMaterial;
}

private _createBlitMesh(engine: Engine, vertices: Float32Array): ModelMesh {
const mesh = new ModelMesh(engine);
mesh._addReferCount(1);
mesh.setVertexElements([new VertexElement("POSITION_UV", 0, VertexElementFormat.Vector4, 0)]);
mesh.setVertexBufferBinding(new Buffer(engine, BufferBindFlag.VertexBuffer, vertices, BufferUsage.Static), 16);
mesh.addSubMesh(0, 4, MeshTopology.TriangleStrip);
return mesh;
}
}
56 changes: 56 additions & 0 deletions packages/core/src/Camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { deepClone, ignoreClone } from "./clone/CloneManager";
import { CameraClearFlags } from "./enums/CameraClearFlags";
import { CameraType } from "./enums/CameraType";
import { DepthTextureMode } from "./enums/DepthTextureMode";
import { Downsampling } from "./enums/Downsampling";
import { MSAASamples } from "./enums/MSAASamples";
import { Shader } from "./shader/Shader";
import { ShaderData } from "./shader/ShaderData";
import { ShaderMacroCollection } from "./shader/ShaderMacroCollection";
Expand All @@ -35,6 +37,8 @@ class MathTemp {
export class Camera extends Component {
/** @internal */
static _cameraDepthTextureProperty = ShaderProperty.getByName("camera_DepthTexture");
/** @internal */
static _cameraOpaqueTextureProperty = ShaderProperty.getByName("camera_OpaqueTexture");

private static _inverseViewMatrixProperty = ShaderProperty.getByName("camera_ViewInvMat");
private static _cameraPositionProperty = ShaderProperty.getByName("camera_Position");
Expand All @@ -47,6 +51,7 @@ export class Camera extends Component {

/**
* Determining what to clear when rendering by a Camera.
*
* @defaultValue `CameraClearFlags.All`
*/
clearFlags: CameraClearFlags = CameraClearFlags.All;
Expand All @@ -59,10 +64,36 @@ export class Camera extends Component {

/**
* Depth texture mode.
* If `DepthTextureMode.PrePass` is used, the depth texture can be accessed in the shader using `camera_DepthTexture`.
*
* @defaultValue `DepthTextureMode.None`
*/
depthTextureMode: DepthTextureMode = DepthTextureMode.None;

/**
* Whether to enable opaque texture.
* If enabled, the opaque texture can be accessed in the shader using `camera_OpaqueTexture`.
*
* @defaultValue `false`
*
* @remarks If enabled, the `independentCanvasEnabled` property will be forced to be true.
*/
opaqueTextureEnabled: boolean = false;

/**
* Opacity texture down sampling.
*
* @defaultValue `Downsampling.TwoX`
*/
opaqueTextureDownsampling: Downsampling = Downsampling.TwoX;

/**
* Multi-sample anti-aliasing samples.
*
* @remarks The `opaqueTextureEnabled` property should be `true` to take effect, otherwise it will be invalid.
*/
msaaSamples: MSAASamples = MSAASamples.None;

/** @internal */
_cameraType: CameraType = CameraType.Normal;
/** @internal */
Expand Down Expand Up @@ -95,6 +126,7 @@ export class Camera extends Component {
private _customAspectRatio: number | undefined = undefined;
private _renderTarget: RenderTarget = null;
private _depthBufferParams: Vector4 = new Vector4();
private _customIndependentCanvas: boolean = false;

@ignoreClone
private _frustumChangeFlag: BoolUpdateFlag;
Expand All @@ -113,6 +145,26 @@ export class Camera extends Component {
@deepClone
private _invViewProjMat: Matrix = new Matrix();

/**
* Whether to use an independent canvas in viewport area.
*
* @remarks If true, the msaa in viewport can turn or off independently by `msaaSamples` property.
*/
get independentCanvasEnabled(): boolean {
const forceIndependent = this._forceUseInternalCanvas();
return forceIndependent || this._customIndependentCanvas;
}

set independentCanvasEnabled(value: boolean) {
const forceIndependent = this._forceUseInternalCanvas();
if (forceIndependent && !value) {
console.warn(
"The camera is forced to use the independent canvas because the opaqueTextureEnabled property is enabled."
);
}
this._customIndependentCanvas = value;
}

/**
* Shader data.
*/
Expand Down Expand Up @@ -716,6 +768,10 @@ export class Camera extends Component {
return this._inverseProjectionMatrix;
}

private _forceUseInternalCanvas(): boolean {
return !this._renderTarget && this.opaqueTextureEnabled;
}

@ignoreClone
private _onPixelViewportChanged(): void {
this._updatePixelViewport();
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { Color } from "@galacean/engine-math";
import { SpriteMaskInteraction } from "./2d";
import { Font } from "./2d/text/Font";
import { BasicResources } from "./BasicResources";
import { Camera } from "./Camera";
import { Canvas } from "./Canvas";
import { EngineSettings } from "./EngineSettings";
Expand Down Expand Up @@ -91,6 +92,8 @@ export class Engine extends EventDispatcher {
/* @internal */
_textRenderDataPool: ClassPool<TextRenderData> = new ClassPool(TextRenderData);

/* @internal */
_basicResources: BasicResources;
/* @internal */
_spriteDefaultMaterial: Material;
/** @internal */
Expand Down Expand Up @@ -298,6 +301,7 @@ export class Engine extends EventDispatcher {
colorSpace === ColorSpace.Gamma && this._macroCollection.enable(Engine._gammaMacro);
innerSettings.colorSpace = colorSpace;

this._basicResources = new BasicResources(this);
this._particleBufferUtils = new ParticleBufferUtils(this);
}

Expand Down
Loading
Loading