Fix particleRenderer enable startFrame (#2333)

* feat: enable startFrame
This commit is contained in:
JujieX
2024-08-20 18:08:24 +08:00
committed by GitHub
parent f3400c8373
commit aea19122a8
6 changed files with 114 additions and 21 deletions

View File

@@ -0,0 +1,79 @@
/**
* @title Particle TextureSheetAnimation
* @category Particle
*/
import {
AssetType,
BlendMode,
Camera,
Color,
Logger,
ParticleCurveMode,
ParticleMaterial,
ParticleRenderer,
Vector3,
WebGLEngine,
Vector2,
BoxShape,
Entity
} from "@galacean/engine";
import { initScreenshot, updateForE2E } from "./.mockForE2E";
// Create engine
WebGLEngine.create({
canvas: "canvas"
}).then((engine) => {
Logger.enable();
engine.canvas.resizeByClientSize();
const scene = engine.sceneManager.activeScene;
const ambientLight = scene.ambientLight;
ambientLight.diffuseSolidColor.set(0.8, 0.8, 1, 1);
ambientLight.diffuseIntensity = 0.5;
const rootEntity = scene.createRootEntity();
scene.background.solidColor = new Color(25 / 255, 25 / 255, 112 / 255, 1);
// Create camera
const cameraEntity = rootEntity.createChild("camera_entity");
cameraEntity.transform.position = new Vector3(0, 10, 30);
const camera = cameraEntity.addComponent(Camera);
camera.fieldOfView = 60;
engine.run();
engine.resourceManager
.load({
url: "https://mdn.alipayobjects.com/huamei_qbugvr/afts/img/A*5EyLSqmA7q0AAAAAAAAAAAAADtKFAQ/original",
type: AssetType.Texture2D
})
.then((texture) => {
const particleEntity = new Entity(engine);
const particleRenderer = particleEntity.addComponent(ParticleRenderer);
const material = new ParticleMaterial(engine);
material.baseColor = new Color(1.0, 1.0, 1.0, 1.0);
material.blendMode = BlendMode.Additive;
material.baseTexture = texture;
particleRenderer.setMaterial(material);
particleRenderer.generator.useAutoRandomSeed = false;
const shape = new BoxShape();
shape.size.set(22, 1, 0);
particleRenderer.generator.emission.shape = shape;
const { textureSheetAnimation } = particleRenderer.generator;
textureSheetAnimation.enabled = true;
textureSheetAnimation.tiling = new Vector2(5, 3);
textureSheetAnimation.frameOverTime.mode = ParticleCurveMode.TwoConstants;
textureSheetAnimation.frameOverTime.constantMin = 0;
textureSheetAnimation.frameOverTime.constantMax = 3 / 15;
cameraEntity.addChild(particleEntity);
updateForE2E(engine, 500);
initScreenshot(engine, camera);
});
});

View File

@@ -189,6 +189,11 @@ export const E2E_CONFIG = {
category: "Particle",
caseFileName: "particleRenderer-dream",
threshold: 0.3
},
textureSheetAnimation: {
category: "Particle",
caseFileName: "particleRenderer-textureSheetAnimation",
threshold: 0.3
}
},
PostProcess: {

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a6f67df682bf50422dc3d5c4c48b82f88be39f8359f01ac2d98398dd49e701f5
size 43859

View File

@@ -806,12 +806,21 @@ export class ParticleGenerator {
}
// Simulation UV
if (this.textureSheetAnimation.enabled) {
const tillingInfo = this.textureSheetAnimation._tillingInfo;
instanceVertices[offset + ParticleBufferUtils.simulationUVOffset] = tillingInfo.x;
instanceVertices[offset + 35] = tillingInfo.y;
instanceVertices[offset + 36] = 0;
instanceVertices[offset + 37] = 0;
if (textureSheetAnimation.enabled) {
const { frameOverTime } = textureSheetAnimation;
const { x, y, z } = textureSheetAnimation._tillingInfo;
let tileRow = 0;
if (frameOverTime.mode === ParticleCurveMode.Constant || frameOverTime.mode === ParticleCurveMode.TwoConstants) {
tileRow =
Math.floor(frameOverTime.evaluate(undefined, textureSheetAnimation._frameOverTimeRand.random()) * z) * x;
}
const tileRowIndex = Math.floor(tileRow);
instanceVertices[offset + ParticleBufferUtils.simulationUVOffset] = x;
instanceVertices[offset + 35] = y;
instanceVertices[offset + 36] = tileRow - tileRowIndex;
instanceVertices[offset + 37] = tileRowIndex * y;
} else {
instanceVertices[offset + ParticleBufferUtils.simulationUVOffset] = 1;
instanceVertices[offset + 35] = 1;

View File

@@ -16,14 +16,12 @@ export class TextureSheetAnimationModule extends ParticleGeneratorModule {
private static readonly _frameCurveMacro = ShaderMacro.getByName("RENDERER_TSA_FRAME_CURVE");
private static readonly _frameRandomCurvesMacro = ShaderMacro.getByName("RENDERER_TSA_FRAME_RANDOM_CURVES");
private static readonly _cycleCountProperty = ShaderProperty.getByName("renderer_TSACycles");
private static readonly _tillingParamsProperty = ShaderProperty.getByName("renderer_TSATillingParams");
private static readonly _frameMinCurveProperty = ShaderProperty.getByName("renderer_TSAFrameMinCurve");
private static readonly _frameMaxCurveProperty = ShaderProperty.getByName("renderer_TSAFrameMaxCurve");
/** Start frame of the texture sheet. */
@deepClone
readonly startFrame = new ParticleCompositeCurve(0);
private static readonly _cycleCountProperty = ShaderProperty.getByName("renderer_TSACycles");
private static readonly _tillingParamsProperty = ShaderProperty.getByName("renderer_TSATillingParams");
/** Frame over time curve of the texture sheet. */
@deepClone
readonly frameOverTime = new ParticleCompositeCurve(new ParticleCurve(new CurveKey(0, 0), new CurveKey(1, 1)));
@@ -42,7 +40,7 @@ export class TextureSheetAnimationModule extends ParticleGeneratorModule {
@deepClone
private _tiling = new Vector2(1, 1);
@ignoreClone
private _textureSheetMacro: ShaderMacro;
private _frameCurveMacro: ShaderMacro;
/**
* Tiling of the texture sheet.
@@ -78,7 +76,7 @@ export class TextureSheetAnimationModule extends ParticleGeneratorModule {
}
}
this._textureSheetMacro = this._enableMacro(shaderData, this._textureSheetMacro, frameMacro);
this._frameCurveMacro = this._enableMacro(shaderData, this._frameCurveMacro, frameMacro);
}
/**

View File

@@ -2,10 +2,10 @@
uniform float renderer_TSACycles;
uniform vec3 renderer_TSATillingParams; // x:subU y:subV z:tileCount
uniform vec2 renderer_TSAFrameMaxCurve[4]; // x:time y:value
#endif
#ifdef RENDERER_TSA_FRAME_RANDOM_CURVES
uniform vec2 renderer_TSAFrameMinCurve[4]; // x:time y:value
#ifdef RENDERER_TSA_FRAME_RANDOM_CURVES
uniform vec2 renderer_TSAFrameMinCurve[4]; // x:time y:value
#endif
#endif
vec2 computeParticleUV(in vec2 uv, in float normalizedAge) {
@@ -13,17 +13,16 @@ vec2 computeParticleUV(in vec2 uv, in float normalizedAge) {
float scaledNormalizedAge = normalizedAge * renderer_TSACycles;
float cycleNormalizedAge = scaledNormalizedAge - floor(scaledNormalizedAge);
float normalizedFrame = evaluateParticleCurve(renderer_TSAFrameMaxCurve, cycleNormalizedAge);
#ifdef RENDERER_TSA_FRAME_RANDOM_CURVES
normalizedFrame = mix(evaluateParticleCurve(renderer_TSAFrameMinCurve, cycleNormalizedAge), normalizedFrame, a_Random1.x);
#endif
float frame = floor(normalizedFrame * renderer_TSATillingParams.z);
float totalULength = frame * renderer_TSATillingParams.x;
float floorTotalULength = floor(totalULength);
uv.x += totalULength - floorTotalULength;
uv.y += floorTotalULength * renderer_TSATillingParams.y;
float tileRow = frame * renderer_TSATillingParams.x;
float floorTotalULength = floor(tileRow);
uv.x += tileRow - tileRowIndex;
uv.y += tileRowIndex * renderer_TSATillingParams.y;
#endif
return uv;