mirror of
https://github.com/galacean/engine.git
synced 2026-06-19 23:27:20 +08:00
Fix particleRenderer enable startFrame (#2333)
* feat: enable startFrame
This commit is contained in:
79
e2e/case/particleRenderer-textureSheetAnimation.ts
Normal file
79
e2e/case/particleRenderer-textureSheetAnimation.ts
Normal 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);
|
||||
});
|
||||
});
|
||||
@@ -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: {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a6f67df682bf50422dc3d5c4c48b82f88be39f8359f01ac2d98398dd49e701f5
|
||||
size 43859
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user