Camera setReplacementShader support ReplacementFailureStrategy when failed (#2172)

* feat: camera `setReplacementShader` support  `ReplacementFailureStrategy ` when failed
This commit is contained in:
AZhan
2024-07-15 12:54:59 +08:00
committed by GitHub
parent b8850dc1c6
commit 33c4370146
6 changed files with 56 additions and 6 deletions

View File

@@ -15,6 +15,7 @@ import { CameraType } from "./enums/CameraType";
import { DepthTextureMode } from "./enums/DepthTextureMode";
import { Downsampling } from "./enums/Downsampling";
import { MSAASamples } from "./enums/MSAASamples";
import { ReplacementFailureStrategy } from "./enums/ReplacementFailureStrategy";
import { Shader } from "./shader/Shader";
import { ShaderData } from "./shader/ShaderData";
import { ShaderMacroCollection } from "./shader/ShaderMacroCollection";
@@ -104,6 +105,8 @@ export class Camera extends Component {
/** @internal */
_replacementSubShaderTag: ShaderTagKey = null;
/** @internal */
_replacementFailureStrategy: ReplacementFailureStrategy = null;
/** @internal */
@ignoreClone
_cameraIndex: number = -1;
@@ -610,6 +613,7 @@ export class Camera extends Component {
context.virtualCamera = virtualCamera;
context.replacementShader = this._replacementShader;
context.replacementTag = this._replacementSubShaderTag;
context.replacementFailureStrategy = this._replacementFailureStrategy;
// compute cull frustum.
if (this.enableFrustumCulling && this._frustumChangeFlag.flag) {
@@ -642,28 +646,35 @@ export class Camera extends Component {
* Set the replacement shader.
* @param shader - Replacement shader
* @param replacementTagName - Sub shader tag name
* @param failureStrategy - Replacement failure strategy, @defaultValue `ReplacementFailureStrategy.KeepOriginalShader`
*
* @remarks
* If replacementTagName is not specified, the first sub shader will be replaced.
* If replacementTagName is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey.
* If replacementTagName is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. If failed to find the sub shader, the strategy will be determined by failureStrategy.
*/
setReplacementShader(shader: Shader, replacementTagName?: string);
setReplacementShader(shader: Shader, replacementTagName?: string, failureStrategy?: ReplacementFailureStrategy);
/**
* Set the replacement shader.
* @param shader - Replacement shader
* @param replacementTag - Sub shader tag
* @param failureStrategy - Replacement failure strategy, @defaultValue `ReplacementFailureStrategy.KeepOriginalShader`
*
* @remarks
* If replacementTag is not specified, the first sub shader will be replaced.
* If replacementTag is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey.
* If replacementTag is specified, the replacement shader will find the first sub shader which has the same tag value get by replacementTagKey. If failed to find the sub shader, the strategy will be determined by failureStrategy.
*/
setReplacementShader(shader: Shader, replacementTag?: ShaderTagKey);
setReplacementShader(shader: Shader, replacementTag?: ShaderTagKey, failureStrategy?: ReplacementFailureStrategy);
setReplacementShader(shader: Shader, replacementTag?: string | ShaderTagKey): void {
setReplacementShader(
shader: Shader,
replacementTag?: string | ShaderTagKey,
failureStrategy: ReplacementFailureStrategy = ReplacementFailureStrategy.KeepOriginalShader
): void {
this._replacementShader = shader;
this._replacementSubShaderTag =
typeof replacementTag === "string" ? ShaderTagKey.getByName(replacementTag) : replacementTag;
this._replacementFailureStrategy = failureStrategy;
}
/**
@@ -672,6 +683,7 @@ export class Camera extends Component {
resetReplacementShader(): void {
this._replacementShader = null;
this._replacementSubShaderTag = null;
this._replacementFailureStrategy = null;
}
/**

View File

@@ -6,6 +6,7 @@ import { BackgroundMode } from "../enums/BackgroundMode";
import { BackgroundTextureFillMode } from "../enums/BackgroundTextureFillMode";
import { CameraClearFlags } from "../enums/CameraClearFlags";
import { DepthTextureMode } from "../enums/DepthTextureMode";
import { ReplacementFailureStrategy } from "../enums/ReplacementFailureStrategy";
import { Shader } from "../shader/Shader";
import { ShaderPass } from "../shader/ShaderPass";
import { RenderQueueType } from "../shader/enums/RenderQueueType";
@@ -239,6 +240,8 @@ export class BasicRenderPipeline {
break;
}
}
context.replacementFailureStrategy === ReplacementFailureStrategy.KeepOriginalShader &&
this.pushRenderElementByType(renderElement, subRenderElement, materialSubShader.passes, renderStates);
} else {
this.pushRenderElementByType(renderElement, subRenderElement, replacementSubShaders[0].passes, renderStates);
}

View File

@@ -1,6 +1,7 @@
import { Matrix, Vector4 } from "@galacean/engine-math";
import { Camera } from "../Camera";
import { VirtualCamera } from "../VirtualCamera";
import { ReplacementFailureStrategy } from "../enums/ReplacementFailureStrategy";
import { Shader, ShaderProperty } from "../shader";
import { ShaderTagKey } from "../shader/ShaderTagKey";
@@ -27,6 +28,7 @@ export class RenderContext {
replacementShader: Shader;
replacementTag: ShaderTagKey;
replacementFailureStrategy: ReplacementFailureStrategy;
flipProjection = false;
viewMatrix: Matrix;

View File

@@ -0,0 +1,9 @@
/**
* The strategy to use when a shader replacement fails.
*/
export enum ReplacementFailureStrategy {
/** Keep the original shader. */
KeepOriginalShader,
/** Do not render. */
DoNotRender
}

View File

@@ -36,6 +36,7 @@ export { FogMode } from "./enums/FogMode";
export { CameraClearFlags } from "./enums/CameraClearFlags";
export { CameraType } from "./enums/CameraType";
export { MSAASamples } from "./enums/MSAASamples";
export { ReplacementFailureStrategy } from "./enums/ReplacementFailureStrategy";
export { Downsampling } from "./enums/Downsampling";
export { ColorSpace } from "./enums/ColorSpace";
export { BackgroundTextureFillMode } from "./enums/BackgroundTextureFillMode";

View File

@@ -1,4 +1,4 @@
import { Camera, CameraClearFlags, Entity, Layer } from "@galacean/engine-core";
import { Camera, CameraClearFlags, Entity, Layer, ReplacementFailureStrategy, Shader } from "@galacean/engine-core";
import { Matrix, Ray, Vector2, Vector3, Vector4 } from "@galacean/engine-math";
import { WebGLEngine } from "@galacean/engine-rhi-webgl";
import { expect } from "chai";
@@ -78,11 +78,34 @@ describe("camera test", function () {
camera.orthographicSize = expectedOrthographicSize;
expect(camera.orthographicSize).to.eq(expectedOrthographicSize);
camera.orthographicSize = orthographicSize;
const testVS = `
void main() {
gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
}`;
const testFS = `
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
`;
const shader = Shader.create("TestReplaceShader", testVS, testFS);
// Test ReplacementShader
camera.setReplacementShader(shader, "CanReplace");
expect(camera["_replacementShader"]).to.eq(shader);
expect(camera["_replacementSubShaderTag"].name).to.eq("CanReplace");
expect(camera["_replacementFailureStrategy"]).to.eq(ReplacementFailureStrategy.KeepOriginalShader);
camera.setReplacementShader(shader, "CanReplace", ReplacementFailureStrategy.DoNotRender);
expect(camera["_replacementShader"]).to.eq(shader);
expect(camera["_replacementSubShaderTag"].name).to.eq("CanReplace");
expect(camera["_replacementFailureStrategy"]).to.eq(ReplacementFailureStrategy.DoNotRender);
camera.resetReplacementShader();
expect(camera["_replacementShader"]).to.eq(null);
expect(camera["_replacementSubShaderTag"]).to.eq(null);
expect(camera["_replacementFailureStrategy"]).to.eq(null);
});
it("static void function", () => {