Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5d37ccc
fix(shader-lab): resolve GVec4 generic return type for texture() buil…
zhuxudong Mar 26, 2026
727bcec
fix(shader-lab): simplify resolveGenericReturnType, fix textureCube/t…
zhuxudong Mar 26, 2026
b69233b
implement HorizontalBillboard render mode (#2938)
hhhhkrx Mar 23, 2026
8a0a605
fix(shader-lab): return TypeAny for unresolved generic builtin return…
zhuxudong Mar 26, 2026
889b096
fix(shader-lab): resolve GVec4 generic return type for texture() buil…
zhuxudong Mar 26, 2026
2d25129
fix(shader-lab): simplify resolveGenericReturnType, fix textureCube/t…
zhuxudong Mar 26, 2026
4b3d632
fix(shader-lab): return TypeAny for unresolved generic builtin return…
zhuxudong Mar 26, 2026
2f6712a
fix(shader-lab): transform struct member access in #define values dur…
zhuxudong Mar 26, 2026
a0e6fc8
test(shader-lab): add transformation result assertions for define-str…
zhuxudong Mar 26, 2026
60480bb
test(shader-lab): enrich define-struct-access tests with usage assert…
zhuxudong Mar 26, 2026
d05187b
fix(shader-lab): support global #define with cross-stage struct var t…
zhuxudong Mar 26, 2026
828752d
fix(shader-lab): skip type inference for member access macros in sema…
zhuxudong Mar 26, 2026
7b18aef
test(shader-lab): add Cocos FSInput pattern test for member access ma…
zhuxudong Mar 26, 2026
80e6e3e
fix(shader-lab): handle global struct-typed variables and simplify ma…
zhuxudong Mar 26, 2026
bfe4e9e
fix(shader-lab): add missing semicolon in GLES100 fragment return con…
zhuxudong Mar 26, 2026
b902c21
feat: merge code
cptbtptpbcptdtptp Mar 27, 2026
b714609
fix: temp
cptbtptpbcptdtptp Mar 27, 2026
1749077
fix: temp
cptbtptpbcptdtptp Mar 27, 2026
c662731
fix: entity disable
cptbtptpbcptdtptp Mar 27, 2026
d0dada8
fix: keep mesh data
cptbtptpbcptdtptp Mar 27, 2026
3cf1883
fix(shader-lab): allow logical NOT operator on numeric operands in pr…
zhuxudong Mar 27, 2026
41f024e
fix(camera): make invViewProjMat ignore scale consistently with viewM…
cptbtptpbcptdtptp Mar 27, 2026
63dff37
test(camera): add unit test for invViewProjMat scale consistency
cptbtptpbcptdtptp Mar 27, 2026
ca0d518
fix: use project type
cptbtptpbcptdtptp Mar 28, 2026
13521cc
fix(loader): componentRef 解析支持 clone entity 子树查找
luzhuang Mar 29, 2026
a6156ba
fix(clone): prefab 克隆时自动 deep clone 同类型 Object 属性,防止共享状态
luzhuang Mar 29, 2026
d9a2674
fix(animation): normalize single-root clip binding paths
luzhuang Mar 29, 2026
63c715b
fix(animation): add per-instance speed to AnimatorStatePlayData
luzhuang Mar 30, 2026
13052d2
feat(ui): add SpriteSizeMode to Image component
luzhuang Mar 30, 2026
15b19af
feat: particle bug not fix
luzhuang Apr 1, 2026
207a381
feat(2d): add FilledSpriteAssembler and sprite filled mode support
cptbtptpbcptdtptp Apr 2, 2026
ca5252a
feat: supported filled
cptbtptpbcptdtptp Apr 7, 2026
5c2edee
fix: clone and sibling index
cptbtptpbcptdtptp Apr 15, 2026
40006d9
fix: raycast collider layer
cptbtptpbcptdtptp Apr 15, 2026
4fe4fae
fix(shader): add missing camera_VPMat declaration in Transform.glsl
zhuxudong Apr 15, 2026
3071f90
fix(loader): always create GLTF_ROOT container for consistent animati…
luzhuang Mar 26, 2026
40734f8
fix(e2e): update blendShape e2e tests for GLTF_ROOT nesting
luzhuang Mar 26, 2026
5abb3f5
fix(loader): restore single-root GLTF scene without GLTF_ROOT wrapper
luzhuang Apr 15, 2026
b3bf58a
Revert "fix(loader): restore single-root GLTF scene without GLTF_ROOT…
luzhuang Apr 15, 2026
069f182
fix(loader): normalize gltf wrapper and skin roots
luzhuang Apr 15, 2026
f5be424
fix: raycast and clone
cptbtptpbcptdtptp Apr 15, 2026
5d7e6af
Merge remote-tracking branch 'origin/fix/shaderlab' into fix/shaderlab
cptbtptpbcptdtptp Apr 15, 2026
bc35a61
fix: revert code
cptbtptpbcptdtptp Apr 15, 2026
d5b6dd9
fix(loader): add audio extension to AudioLoader supported types
luzhuang Apr 15, 2026
bdf5490
fix(physics-physx): raycast 和 sweep 跳过 initial overlap
luzhuang Apr 15, 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
2 changes: 1 addition & 1 deletion e2e/.dev/physx.release.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion e2e/.dev/physx.release.simd.js

Large diffs are not rendered by default.

Binary file modified e2e/.dev/physx.release.simd.wasm
Binary file not shown.
Binary file modified e2e/.dev/physx.release.wasm
Binary file not shown.
1 change: 1 addition & 0 deletions e2e/.dev/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ demoList.forEach(({ file }) => {
fs.outputJSONSync(path.join(__dirname, OUT_PATH, ".demoList.json"), demoSorted);

module.exports = {
publicDir: path.resolve(__dirname, "public"),
server: {
open: true,
host: "0.0.0.0",
Expand Down
2 changes: 1 addition & 1 deletion e2e/case/animator-blendShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
const { defaultSceneRoot } = asset;
rootEntity.addChild(defaultSceneRoot);
const animator = defaultSceneRoot.getComponent(Animator);
const skinMeshRenderer = defaultSceneRoot.getComponent(SkinnedMeshRenderer);
const skinMeshRenderer = defaultSceneRoot.getComponentsIncludeChildren(SkinnedMeshRenderer, [])[0];
skinMeshRenderer.blendShapeWeights[0] = 1.0;
animator.play("TheWave");

Expand Down
4 changes: 2 additions & 2 deletions e2e/case/animator-multiSubMeshBlendShape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ WebGLEngine.create({ canvas: "canvas" }).then((engine) => {
.then((asset) => {
const { defaultSceneRoot } = asset;
rootEntity.addChild(defaultSceneRoot);
const entity = defaultSceneRoot;
defaultSceneRoot.transform.rotation = new Vector3(-90, -0, 0);
const entity = defaultSceneRoot.children[0];
entity.transform.rotation = new Vector3(-90, -0, 0);
const animator = entity.addComponent(Animator);

animator.animatorController = new AnimatorController(engine);
Expand Down
4 changes: 2 additions & 2 deletions e2e/case/particleRenderer-dream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ WebGLEngine.create({

cameraEntity.addChild(fireEntity);

updateForE2E(engine, 500);
initScreenshot(engine, camera);
// updateForE2E(engine, 500);
// initScreenshot(engine, camera);
});
});

Expand Down
146 changes: 146 additions & 0 deletions examples/src/sprite-renderer-filled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/**
* @title Sprite Filled
* @category 2D
*/

import * as dat from "dat.gui";
import {
AssetType,
Camera,
Sprite,
SpriteDrawMode,
SpriteFilledMode,
SpriteFilledOrigin,
SpriteRenderer,
Texture2D,
Vector3,
WebGLEngine
} from "@galacean/engine";

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

const scene = engine.sceneManager.activeScene;
scene.background.solidColor.set(0.15, 0.15, 0.18, 1);
const rootEntity = scene.createRootEntity();

// Create camera
const cameraEntity = rootEntity.createChild("camera");
cameraEntity.transform.setPosition(0, 0, 50);
cameraEntity.addComponent(Camera);

// Load texture and create sprite
engine.resourceManager
.load<Texture2D>({
url: "https://gw.alipayobjects.com/mdn/rms_7c464e/afts/img/A*ApFPTZSqcMkAAAAAAAAAAAAAARQnAQ",
type: AssetType.Texture2D
})
.then((texture) => {
const spriteEntity = rootEntity.createChild("sprite");
spriteEntity.transform.position = new Vector3(0, 0, 0);
spriteEntity.transform.setScale(2, 2, 2);
const renderer = spriteEntity.addComponent(SpriteRenderer);
renderer.sprite = new Sprite(engine, texture);

// Set filled mode
renderer.drawMode = SpriteDrawMode.Filled;
renderer.filledMode = SpriteFilledMode.Radial360;
renderer.filledOrigin = SpriteFilledOrigin.Bottom;
renderer.filledAmount = 0.75;
renderer.filledClockWise = true;

addGUI(renderer);
});

engine.run();

function addGUI(renderer: SpriteRenderer) {
const gui = new dat.GUI();

const filledModeMap: Record<string, SpriteFilledMode> = {
Horizontal: SpriteFilledMode.Horizontal,
Vertical: SpriteFilledMode.Vertical,
Radial90: SpriteFilledMode.Radial90,
Radial180: SpriteFilledMode.Radial180,
Radial360: SpriteFilledMode.Radial360
};

const originForRadial360: string[] = ["Right", "Top", "Left", "Bottom"];
const originForRadial180: string[] = ["Right", "Top", "Left", "Bottom"];
const originForRadial90: string[] = ["BottomLeft", "BottomRight", "TopRight", "TopLeft"];
const originForHorizontal: string[] = ["Left", "Right"];
const originForVertical: string[] = ["Bottom", "Top"];

const originMap: Record<string, SpriteFilledOrigin> = {
Right: SpriteFilledOrigin.Right,
TopRight: SpriteFilledOrigin.TopRight,
Top: SpriteFilledOrigin.Top,
TopLeft: SpriteFilledOrigin.TopLeft,
Left: SpriteFilledOrigin.Left,
BottomLeft: SpriteFilledOrigin.BottomLeft,
Bottom: SpriteFilledOrigin.Bottom,
BottomRight: SpriteFilledOrigin.BottomRight
};

const state = {
filledMode: "Radial360",
origin: "Bottom",
amount: 0.75,
clockWise: true
};

const folder = gui.addFolder("Filled Sprite");
folder.open();

// Filled mode
folder.add(state, "filledMode", Object.keys(filledModeMap)).onChange((value: string) => {
renderer.filledMode = filledModeMap[value];
updateOriginOptions(value);
});

// Origin
let originCtrl = folder.add(state, "origin", originForRadial360).onChange((value: string) => {
renderer.filledOrigin = originMap[value];
});

// Amount
folder.add(state, "amount", 0.0, 1.0, 0.01).onChange((value: number) => {
renderer.filledAmount = value;
});

// ClockWise
folder.add(state, "clockWise").onChange((value: boolean) => {
renderer.filledClockWise = value;
});

function updateOriginOptions(mode: string) {
folder.remove(originCtrl);

let options: string[];
switch (mode) {
case "Horizontal":
options = originForHorizontal;
break;
case "Vertical":
options = originForVertical;
break;
case "Radial90":
options = originForRadial90;
break;
case "Radial180":
options = originForRadial180;
break;
default:
options = originForRadial360;
break;
}

state.origin = options[0];
renderer.filledOrigin = originMap[state.origin];

originCtrl = folder.add(state, "origin", options).onChange((value: string) => {
renderer.filledOrigin = originMap[value];
});
}
}
});
Loading
Loading