Skip to content
Open
Show file tree
Hide file tree
Changes from 90 commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
96aeda6
feat(core): add GPU instancing auto-batching with UBO-based per-insta…
GuoLei1990 Apr 7, 2026
3279bb6
fix: static init order for _gpuInstanceMacro and prettier formatting
GuoLei1990 Apr 7, 2026
2318007
style: remove extra blank lines
GuoLei1990 Apr 7, 2026
94ef055
revert: restore original shader files, instancing UBO injection handl…
GuoLei1990 Apr 7, 2026
128b16e
fix: restore non-Layer shader improvements that were over-reverted
GuoLei1990 Apr 7, 2026
4d8f2b7
refactor: revert _getMacroCachePool rename back to _getShaderProgramPool
GuoLei1990 Apr 7, 2026
75a1ba2
feat(instancing): fix batch reuse bug and optimize ModelMat to affine…
GuoLei1990 Apr 7, 2026
9d015d6
feat(gpu-instancing): load ambient light and clone ducks for instancing
GuoLei1990 Apr 8, 2026
7b49335
fix(instancing): keep renderer_NormalMat as mat4 for shader compatibi…
GuoLei1990 Apr 8, 2026
73c19fa
refactor: rename batch to packer for consistency with InstanceDataPacker
GuoLei1990 Apr 8, 2026
4a55540
refactor: clarify _canBatch/_batch parameter semantics
GuoLei1990 Apr 8, 2026
9002cb4
refactor: move gpuInstanceMacro to InstanceDataPacker and cleanup
GuoLei1990 Apr 8, 2026
fdc380a
refactor: defer instancing layout computation to render phase
GuoLei1990 Apr 8, 2026
c40a679
refactor: replace InstanceDataPackerPool with single shared packer
GuoLei1990 Apr 8, 2026
b8935e3
refactor: move batcherManager declaration to first usage
GuoLei1990 Apr 8, 2026
002d7ab
refactor: rename InstanceDataPacker to InstanceBatch
GuoLei1990 Apr 8, 2026
f984867
refactor: rename MacroCachePool to MacroMap
GuoLei1990 Apr 8, 2026
1fc3f4f
refactor: rename shaderProgramPool(s) variables to shaderProgramMap(s)
GuoLei1990 Apr 8, 2026
53a9a9f
refactor: simplify bindUniformBufferBase - remove unnecessary null check
GuoLei1990 Apr 8, 2026
c63b83b
refactor: simplify InstanceBatch - store layout directly, rename fields
GuoLei1990 Apr 11, 2026
b9f4168
refactor: clean up InstanceBatch upload method
GuoLei1990 Apr 11, 2026
8c704a7
refactor: clean up RenderQueue instancing render loop
GuoLei1990 Apr 11, 2026
d75acb7
style: fix prettier formatting in RenderQueue
GuoLei1990 Apr 11, 2026
82c0d60
chore: upgrade lint-staged to v16 and fix glob pattern
GuoLei1990 Apr 11, 2026
baeaa3d
chore: upgrade eslint and @typescript-eslint to support TS 5.6
GuoLei1990 Apr 11, 2026
99ec5d1
refactor: null out instancedRenderers in dispose
GuoLei1990 Apr 11, 2026
fd747eb
refactor: store InstanceLayout on ShaderProgram during compilation
GuoLei1990 Apr 11, 2026
910b8cc
refactor: inline _buildMacroMap into _compileShaderLabSource
GuoLei1990 Apr 11, 2026
891d2c2
refactor: rename isGpuInstance to isGPUInstance
GuoLei1990 Apr 11, 2026
5d02bbe
refactor: inline _compilePlatformSource into _getCanonicalShaderProgram
GuoLei1990 Apr 11, 2026
6a01018
refactor: rename _getCanonicalShaderProgram to _compileShaderProgram
GuoLei1990 Apr 11, 2026
967fc6b
refactor: move bindUniformBlocks next to other public methods
GuoLei1990 Apr 11, 2026
b420f61
refactor: remove empty SubShader._destroy
GuoLei1990 Apr 11, 2026
1d84610
refactor: inline single-use subShader variable
GuoLei1990 Apr 11, 2026
a850200
refactor: remove unused GLSLIfdefResolver
GuoLei1990 Apr 11, 2026
34d5570
refactor: move InstanceFieldInfo and InstanceLayout after ShaderFacto…
GuoLei1990 Apr 11, 2026
a629292
refactor: remove default value from isGPUInstance parameter
GuoLei1990 Apr 11, 2026
f7ad877
refactor: reorder ShaderFactory - group static fields before methods
GuoLei1990 Apr 11, 2026
76b23a0
refactor: clean up ShaderFactory naming and visibility
GuoLei1990 Apr 11, 2026
9a82af5
refactor: optimize ShaderFactory - merge pack functions, extract cons…
GuoLei1990 Apr 11, 2026
4f76b6b
refactor: replace mat4_affine with mat3x4, clean up ShaderFactory det…
GuoLei1990 Apr 11, 2026
1052411
refactor: simplify UBO injection and skip UBO members in uniform refl…
GuoLei1990 Apr 11, 2026
7ba4137
refactor: extract InstancePackFunc type alias
GuoLei1990 Apr 11, 2026
f06aa39
fix: update test references from _getCanonicalShaderProgram to _compi…
GuoLei1990 Apr 11, 2026
c1195f8
Merge remote-tracking branch 'origin/dev/2.0' into feat/gpu-instancing
GuoLei1990 Apr 11, 2026
3c58dd8
fix: resolve shader compile errors and add missing matrix uniform types
GuoLei1990 Apr 11, 2026
74cbb0e
feat: add GPU instancing e2e tests and complete matrix uniform support
GuoLei1990 Apr 11, 2026
6ab1b9c
feat: convert GPU instancing examples to animated benchmarks with Stats
GuoLei1990 Apr 11, 2026
86f3e5b
refactor: sort opaque objects by material/primitive instead of distance
GuoLei1990 Apr 11, 2026
ec70753
refactor: unroll mat3x4 pack loop and precompute field offset
GuoLei1990 Apr 11, 2026
38239ed
test: update e2e baseline images for opaque sorting change
GuoLei1990 Apr 11, 2026
1566c69
test: adjust e2e diff threshold for gpu-instancing-auto-batch
GuoLei1990 Apr 11, 2026
0c0373d
refactor: update auto-batch example with Avocado model and 5000 insta…
GuoLei1990 Apr 12, 2026
9533e2e
refactor: rename MacroMap to ShaderProgramMap and remove generic abst…
GuoLei1990 Apr 12, 2026
d58aaa3
feat: add macro collection equality check to _canBatch
GuoLei1990 Apr 12, 2026
761bec4
refactor: remove unused renderer_LocalMat and renderer_MVInvMat
GuoLei1990 Apr 12, 2026
91e2ce2
refactor: make ShaderProgramMap constructor engine param required
GuoLei1990 Apr 12, 2026
ee3aa61
refactor: detect array uniforms in instancing and use Record for buil…
GuoLei1990 Apr 12, 2026
266c346
refactor: reorder types in ShaderFactory, remove unnecessary @internal
GuoLei1990 Apr 15, 2026
de638a3
refactor: clean up redundant comments in ShaderFactory
GuoLei1990 Apr 15, 2026
db80ad5
refactor: use template literal for _derivedDefines in ShaderFactory
GuoLei1990 Apr 15, 2026
bfa32df
refactor: cache maxUniformBlockSize and bind UBO at link time
GuoLei1990 Apr 15, 2026
2c46325
fix: avoid circular dependency in ShaderProgram UBO binding
GuoLei1990 Apr 15, 2026
875ff92
refactor: move uniformBlockBindingMap from InstanceBatch to ShaderFac…
GuoLei1990 Apr 15, 2026
454727b
fix: add missing camera_VPMat declaration in Transform.glsl
GuoLei1990 Apr 15, 2026
4b49ec8
test: remove PrecompileBenchmark that conflicts with deep source imports
GuoLei1990 Apr 15, 2026
e12a5c1
refactor: sort at RenderElement level to improve batch quality
GuoLei1990 Apr 15, 2026
607c5a3
refactor: remove unused batched field and simplify transform update
GuoLei1990 Apr 16, 2026
06759e6
refactor: rename InstanceBatch to InstanceBuffer and InstanceLayout t…
GuoLei1990 Apr 16, 2026
a367d12
refactor: rename BatchUtils to VertexMergeBatcher and clean up Render…
GuoLei1990 Apr 18, 2026
9e4dde4
Merge remote-tracking branch 'origin/dev/2.0' into feat/gpu-instancing
GuoLei1990 Apr 18, 2026
2956730
fix(shader): scan instance uniforms with macro awareness for raw GLSL
GuoLei1990 Apr 23, 2026
c406024
fix(ui): update UIRenderer to use renamed VertexMergeBatcher
GuoLei1990 Apr 25, 2026
d4fb81f
perf(ui): canvas-internal batching with visual-layering driven sort
GuoLei1990 Apr 26, 2026
e30dd3e
docs(e2e): clarify ui-batch-order is a regression guard
GuoLei1990 Apr 26, 2026
6619612
Merge remote-tracking branch 'origin/dev/2.0' into feat/gpu-instancing
GuoLei1990 Apr 26, 2026
72e079e
test(e2e): update particle shape-transform baseline for gpu-instancin…
GuoLei1990 Apr 26, 2026
fb9561e
test(e2e): switch ui-batch-order to ScreenSpaceCamera and add baseline
GuoLei1990 Apr 26, 2026
25bef75
test(examples): upgrade ui-batch-massive with atlas icons & gradient …
GuoLei1990 Apr 26, 2026
1c2b7f2
test(examples): bump ui-batch-massive to 9216 buttons (18432 sub-elem…
GuoLei1990 Apr 26, 2026
1b4dd6b
Merge remote-tracking branch 'origin/dev/2.0' into feat/gpu-instancing
GuoLei1990 May 11, 2026
bc4493f
fix(shader): drop duplicate camera_ProjectionParams from Transform.glsl
GuoLei1990 May 11, 2026
086dff0
fix(shader): declare camera matrices when instance UBO rewrites deriv…
GuoLei1990 May 11, 2026
a87acc8
test(e2e,examples): rewrite gpu-instancing cases as ShaderLab
GuoLei1990 May 11, 2026
50f9281
fix(shader): force-inject renderer_ModelMat into instance UBO and dec…
GuoLei1990 May 11, 2026
41bca94
chore(examples): wire Shader.create after WebGLEngine.create and add …
GuoLei1990 May 11, 2026
7ac1913
refactor(ui): move UIBatchSorter from core to ui
GuoLei1990 May 12, 2026
884cb97
fix(instancing): pack the renderer's transform-source matrix, not ent…
GuoLei1990 May 12, 2026
bd96c42
chore(ui): type UICanvas render element arrays and release them on di…
GuoLei1990 May 12, 2026
00b4462
feat(instancing): support bool / bvec uniform types in instance UBO
GuoLei1990 May 12, 2026
04ac8b3
fix(instancing): always run inject path so derived built-ins keep com…
GuoLei1990 May 13, 2026
9606bf3
fix(ui): skip re-batching of canvas-internal leaders in main pipeline
GuoLei1990 May 13, 2026
a25abab
refactor(shader): drop dead macro-aware uniform scan in instance UBO …
GuoLei1990 May 13, 2026
5b82d69
chore(batcher): drop dead leader guard in VertexMergeBatcher
GuoLei1990 May 13, 2026
3b3d091
Merge remote-tracking branch 'origin/dev/2.0' into feat/gpu-instancing
GuoLei1990 May 13, 2026
10b9265
fix(instancing): reject unsupported uniform types at scan time
GuoLei1990 May 13, 2026
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
1 change: 0 additions & 1 deletion docs/en/graphics/material/examples/shader-05-advance.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ gl_FragColor = vec4(lighting, 1.0);

The engine provides a rich set of built-in variables that can be used directly, such as transformation matrix variables:
```glsl
mat4 renderer_LocalMat; // Local transformation matrix
mat4 renderer_ModelMat; // Model matrix
mat4 renderer_MVMat; // Model-view matrix
mat4 renderer_MVPMat; // MVP matrix
Expand Down
1 change: 0 additions & 1 deletion docs/en/graphics/material/shaderAPI.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ vec4 fog(vec4 color, vec3 positionVS);
Provides system variables for model space, view space, world space, and camera coordinates:

```glsl
mat4 renderer_LocalMat;
mat4 renderer_ModelMat;
mat4 camera_ViewMat;
mat4 camera_ProjMat;
Expand Down
1 change: 0 additions & 1 deletion docs/en/graphics/material/variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ Below are the engine's built-in variables for reference when writing Shaders:

| Name | Type | Description |
| :---------------- | :--- | :--------------------------- |
| renderer_LocalMat | mat4 | Model local coordinate matrix |
| renderer_ModelMat | mat4 | Model world coordinate matrix |
| renderer_MVMat | mat4 | Model view matrix |
| renderer_MVPMat | mat4 | Model view projection matrix |
Expand Down
1 change: 0 additions & 1 deletion docs/zh/graphics/material/examples/shader-05-advance.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ void frag() {

引擎提供了丰富的内置变量,直接声明使用即可,比如变换矩阵相关变量:
```glsl
mat4 renderer_LocalMat; // 本地变换矩阵
mat4 renderer_ModelMat; // 模型矩阵
mat4 renderer_MVMat; // 模型视图矩阵
mat4 renderer_MVPMat; // MVP矩阵
Expand Down
1 change: 0 additions & 1 deletion docs/zh/graphics/material/shaderAPI.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ vec4 fog(vec4 color, vec3 positionVS);
提供了模型空间、视图空间、世界空间、相机坐标等[系统变量](/docs/graphics/material/variables/):

```glsl
mat4 renderer_LocalMat;
mat4 renderer_ModelMat;
mat4 camera_ViewMat;
mat4 camera_ProjMat;
Expand Down
1 change: 0 additions & 1 deletion docs/zh/graphics/material/variables.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ Shader 代码中会经常用到内置变量,一种是**逐顶点**的 `attribu

| 名字 | 类型 | 解释 |
| :----------------- | :--- | ------------------ |
| renderer_LocalMat | mat4 | 模型本地坐标系矩阵 |
| renderer_ModelMat | mat4 | 模型世界坐标系矩阵 |
| renderer_MVMat | mat4 | 模型视口矩阵 |
| renderer_MVPMat | mat4 | 模型视口投影矩阵 |
Expand Down
1 change: 0 additions & 1 deletion e2e/case/animator-customBlendShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
cameraEntity.transform.position = new Vector3(0, 0, 5);
const camera = cameraEntity.addComponent(Camera);


const meshEntity = rootEntity.createChild("meshEntity");
const skinnedMeshRenderer = meshEntity.addComponent(SkinnedMeshRenderer);
const modelMesh = new ModelMesh(engine);
Expand Down
2 changes: 1 addition & 1 deletion e2e/case/gltf-blendshape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ WebGLEngine.create({ canvas: "canvas" }).then((engine) => {

initScreenshot(engine, camera);
});
});
});
68 changes: 68 additions & 0 deletions e2e/case/gpu-instancing-auto-batch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/**
* @title GPU Instancing Auto Batch
* @category Mesh
*/
import {
AmbientLight,
AssetType,
Camera,
Color,
DirectLight,
GLTFResource,
Logger,
Vector3,
WebGLEngine
} from "@galacean/engine";
import { initScreenshot, updateForE2E } from "./.mockForE2E";

Logger.enable();
WebGLEngine.create({ canvas: "canvas" }).then(async (engine) => {
engine.canvas.resizeByClientSize(2);

const scene = engine.sceneManager.activeScene;
const rootEntity = scene.createRootEntity("Root");

// Camera
const cameraEntity = rootEntity.createChild("Camera");
cameraEntity.transform.setPosition(0, 10, 80);
cameraEntity.transform.lookAt(new Vector3(0, 0, 0));
const camera = cameraEntity.addComponent(Camera);
camera.farClipPlane = 300;

// Light
const lightEntity = rootEntity.createChild("Light");
lightEntity.transform.setRotation(-45, -45, 0);
lightEntity.addComponent(DirectLight).color = new Color(1, 1, 1, 1);

// Load Duck model and ambient light
const [glTF, ambientLight] = await Promise.all([
engine.resourceManager.load<GLTFResource>({
url: "https://gw.alipayobjects.com/os/bmw-prod/6cb8f543-285c-491a-8cfd-57a1160dc9ab.glb",
type: AssetType.GLTF
}),
engine.resourceManager.load<AmbientLight>({
url: "https://mdn.alipayobjects.com/oasis_be/afts/file/A*eRJ8QKzf5zAAAAAAgBAAAAgAekp5AQ/ambient.ambLight",
type: AssetType.AmbientLight
})
]);
scene.ambientLight = ambientLight;

// Clone ducks with fixed seed positions for deterministic output
const count = 500;
const spread = 50;
for (let i = 0; i < count; i++) {
const duck = glTF.instantiateSceneRoot();
// Use deterministic positions based on index
const t = i / count;
duck.transform.setPosition(
Math.sin(t * 137.5) * spread * 0.5,
Math.cos(t * 97.3) * spread * 0.5,
Math.sin(t * 59.1) * spread * 0.5
);
duck.transform.setRotation(t * 360, t * 720, t * 1080);
rootEntity.addChild(duck);
}

updateForE2E(engine);
initScreenshot(engine, camera);
});
112 changes: 112 additions & 0 deletions e2e/case/gpu-instancing-custom-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**
* @title GPU Instancing Custom Data
* @category Mesh
*/
import {
Camera,
Color,
DirectLight,
Logger,
Material,
MeshRenderer,
PrimitiveMesh,
Shader,
ShaderProperty,
Vector3,
Vector4,
WebGLEngine
} from "@galacean/engine";
import { ShaderCompiler } from "@galacean/engine-shader-compiler";
import { initScreenshot, updateForE2E } from "./.mockForE2E";

Logger.enable();

const shaderCompiler = new ShaderCompiler();

// Custom shader: uses renderer_CustomColor (per-instance) for fragment output
const customInstanceShaderSource = `Shader "CustomInstanceShader" {
SubShader "Default" {
Pass "Forward" {
struct Attributes {
vec3 POSITION;
vec3 NORMAL;
};

struct Varyings {
vec3 v_normal;
};

mat4 renderer_MVPMat;
mat4 renderer_NormalMat;
vec4 renderer_CustomColor;

VertexShader = vert;
FragmentShader = frag;

Varyings vert(Attributes attr) {
Varyings v;
gl_Position = renderer_MVPMat * vec4(attr.POSITION, 1.0);
v.v_normal = normalize((renderer_NormalMat * vec4(attr.NORMAL, 0.0)).xyz);
return v;
}

vec4 frag(Varyings v) {
vec3 lightDir = normalize(vec3(1.0, 1.0, 1.0));
float NdotL = max(dot(v.v_normal, lightDir), 0.2);
return vec4(renderer_CustomColor.rgb * NdotL, 1.0);
}
}
}
}`;

WebGLEngine.create({ canvas: "canvas", shaderCompiler }).then((engine) => {
Shader.create(customInstanceShaderSource);
engine.canvas.resizeByClientSize(2);

const scene = engine.sceneManager.activeScene;
const rootEntity = scene.createRootEntity("Root");

// Camera
const cameraEntity = rootEntity.createChild("Camera");
cameraEntity.transform.setPosition(0, 10, 80);
cameraEntity.transform.lookAt(new Vector3(0, 0, 0));
const camera = cameraEntity.addComponent(Camera);
camera.farClipPlane = 300;

// Light
const lightEntity = rootEntity.createChild("Light");
lightEntity.transform.setRotation(-45, -45, 0);
lightEntity.addComponent(DirectLight).color = new Color(1, 1, 1, 1);

// Shared mesh and material
const mesh = PrimitiveMesh.createCuboid(engine, 1, 1, 1);
const material = new Material(engine, Shader.find("CustomInstanceShader"));
const customColorProperty = ShaderProperty.getByName("renderer_CustomColor");

// Create cubes with deterministic positions and colors
const count = 500;
const spread = 50;
for (let i = 0; i < count; i++) {
const entity = rootEntity.createChild("Cube" + i);
const t = i / count;
entity.transform.setPosition(
Math.sin(t * 137.5) * spread * 0.5,
Math.cos(t * 97.3) * spread * 0.5,
Math.sin(t * 59.1) * spread * 0.5
);
entity.transform.setRotation(t * 360, t * 720, t * 1080);

const renderer = entity.addComponent(MeshRenderer);
renderer.mesh = mesh;
renderer.setMaterial(material);

// Deterministic colors based on index
renderer.shaderData.setVector4(
customColorProperty,
new Vector4(Math.sin(t * 6.28) * 0.5 + 0.5, Math.cos(t * 4.71) * 0.5 + 0.5, Math.sin(t * 3.14) * 0.5 + 0.5, 1.0)
);
}

updateForE2E(engine);
initScreenshot(engine, camera);
});
40 changes: 36 additions & 4 deletions e2e/case/spriteMask-customStencil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,15 @@ WebGLEngine.create({ canvas: "canvas", shaderCompiler: new ShaderCompiler() }).t
// Create a sprite renderer that writes stencil.
pos.set(0, 0, 0);
scale.set(5, 5, 5);
const writeStencilSR = addSpriteRenderer(pos, scale, sprite, SpriteMaskInteraction.None, Layer.Layer0, Layer.Layer0, 0);
const writeStencilSR = addSpriteRenderer(
pos,
scale,
sprite,
SpriteMaskInteraction.None,
Layer.Layer0,
Layer.Layer0,
0
);
const writeStencilMaterial = writeStencilSR.getInstanceMaterial();
writeStencilMaterial.shader = customStencilShader;
const writeStencilData = writeStencilMaterial.shaderData;
Expand All @@ -161,7 +169,15 @@ WebGLEngine.create({ canvas: "canvas", shaderCompiler: new ShaderCompiler() }).t

// Create a sprite renderer that reads stencil.
pos.set(3, 3, 0);
const readStencilSR = addSpriteRenderer(pos, scale, sprite, SpriteMaskInteraction.None, Layer.Layer0, Layer.Layer0, 1);
const readStencilSR = addSpriteRenderer(
pos,
scale,
sprite,
SpriteMaskInteraction.None,
Layer.Layer0,
Layer.Layer0,
1
);
readStencilSR.color.set(1, 0, 0, 1);
const readStencilMaterial = readStencilSR.getInstanceMaterial();
readStencilMaterial.shader = customStencilShader;
Expand All @@ -173,7 +189,15 @@ WebGLEngine.create({ canvas: "canvas", shaderCompiler: new ShaderCompiler() }).t

// Create a sprite renderer with mask interaction (does not need custom stencil).
pos.set(5, -3, 0);
const maskSR = addSpriteRenderer(pos, scale, sprite, SpriteMaskInteraction.VisibleOutsideMask, Layer.Layer0, Layer.Layer0, 2);
const maskSR = addSpriteRenderer(
pos,
scale,
sprite,
SpriteMaskInteraction.VisibleOutsideMask,
Layer.Layer0,
Layer.Layer0,
2
);
maskSR.color.set(0, 1, 0, 1);

// Create a sprite mask.
Expand All @@ -183,7 +207,15 @@ WebGLEngine.create({ canvas: "canvas", shaderCompiler: new ShaderCompiler() }).t
// Create another sprite renderer that reads stencil with a different comparison.
pos.set(20, 10, 0);
scale.set(3, 3, 3);
const readStencilSR2 = addSpriteRenderer(pos, scale, sprite, SpriteMaskInteraction.None, Layer.Layer0, Layer.Layer0, 4);
const readStencilSR2 = addSpriteRenderer(
pos,
scale,
sprite,
SpriteMaskInteraction.None,
Layer.Layer0,
Layer.Layer0,
4
);
readStencilSR2.color.set(1, 0.5, 0.8, 1);
const readStencilMaterial2 = readStencilSR2.getInstanceMaterial();
readStencilMaterial2.shader = customStencilShader;
Expand Down
Loading
Loading