# 其他属性和动画

## 基于不同RenderMode的渲染

`RenderMode`不进行设置的前提下, 无论相机如何的转动，所有粒子永远正对着屏幕。  

这里通过`render-mode`字段进行控制，示例如下：

```xml
<xr-particle id="colorGradient" position="2 0 -2" render-mode="off" capacity="20" emit-rate="5" life-time="3" emitter-type="BoxShape"></xr-particle>
```

### RenderMode字段相关变量介绍
| 名称 | 备注 | 
| --- | --- |
| off | 是否启用Billboard渲染 |
| default | 默认Billboard渲染模式，粒子始终正对屏幕 | 
| y | Y轴渲染模式，粒子Y轴将锁定, 其它轴的显示正对屏幕 | 
| stretched | 拉伸渲染模式，将附带一些旋转，使粒子朝向其运动方向 | 
| mesh | 粒子将以指定网格渲染，与粒子系统中的mesh字段搭配 |

可以通过代码调用禁用`Billboard渲染`，粒子将保持它自己的位置，面片的显示不会随着相机旋转而进行调整：
```ts
  particleComponent.useBillBoard = false
```

要设定Billboard模式，首先要启用useBillBoard，并对billboardMode进行设置， 这里以"BILLBOARDMODE_Y"为例
```ts
  particleComponent.useBillBoard = true
  particleComponent.billboardMode = BillBoardMode.BILLBOARDMODE_Y || 1
```

## 支持色彩取样构建
粒子系统目前支持基于alpha值，在色彩梯度渐变图上进行采样, 从而更改粒子的颜色, 要启用此功能，首先将`useRampGradients`置为true

通过如下示例，构建自定义色彩取样表

```ts
  particleComponent.useRampGradient = true;
  particleComponent.addRampGradient(0.0, Vector3.createFromNumber(1, 1, 1));
  particleComponent.addRampGradient(0.2, Vector3.createFromNumber(0.8, 0.8, 0.05));
  particleComponent.addRampGradient(0.4, Vector3.createFromNumber(0.86, 0.5, 0.05));
  particleComponent.addRampGradient(0.6, Vector3.createFromNumber(0.75, 0.18, 0.07));
  particleComponent.addRampGradient(0.8, Vector3.createFromNumber(0.45, 0.08, 0.06));
  particleComponent.addRampGradient(1, Vector3.createFromNumber(0.05, 0.05, 0.05));
```

最终粒子将根据自身alpha值，在取样表中采取对应的色彩。

通过如下示例，也可以在生命周期的不同阶段，指定alpha值的变化范围，影响对色彩渐变图的采样。 

例如：0.2s时，,因为此时的采样范围为[0.1,0.8], 粒子alpha=0.8时视值为1, 在区间内值映射为(alpha-0.1)/0.8

```ts
  particleComponent.addColorRemapGradient(0, 0, 0.1);
  particleComponent.addColorRemapGradient(0.2, 0.1, 0.8);
  particleComponent.addColorRemapGradient(0.3, 0.2, 0.85);
```

| 名称 | 类型 | 备注 | 默认值 |
| --- | --- | --- | --- |
| useRampGradients | boolean | 是否启用色彩梯度取样 | false |

### 相关方法
### `addRampGradient`
| 名称 | 类型 | 备注 | 
| --- | --- | --- | 
| gradient | number | 在指定位置设置对应色彩, 该值与（1-粒子alpha值）对应，取值范围[0~1] |
| color | Vector3 | 色彩RGB值 |

### `addColorRemapGradient`
| 名称 | 类型 | 备注 | 
| --- | --- | --- | 
| time | number | 指定粒子生命周期的阶段 |
| min | number | alpha值左区间 |
| max | number | alpha值右区间 |

## 粒子属性的动态变化
粒子在运动过程中，可以定制对其大小、颜色、速度的动态变化。  

本粒子系统同时内置有关粒子大小的控制方法addSizeGradient，用法如下：

```ts
  particleComponent.addSizeGradient(0,1);
  particleComponent.addSizeGradient(0.5,0.8);
  particleComponent.addSizeGradient(0.75,0.3,0.5);
  particleComponent.addSizeGradient(1,0);
```

调用`addColorGradient`支持带有alpha通道的颜色过渡：

```ts
    particleComponent.addColorGradient(0, Vector4.createFromNumber(1,1,1,0));
    particleComponent.addColorGradient(0.3, Vector4.createFromNumber(0.3,1,1,0.5),Vector4.createFromNumber(0.2,0,0.6,0.5),);
    particleComponent.addColorGradient(1, Vector4.createFromNumber(0,1,1,1));
```

调用`addAlphaGradient`可以专门调整透明度的过渡：

```ts
    particleComponent.addAlphaGradient(0,0);
    particleComponent.addAlphaGradient(0.3,0.3, 0.5);
    particleComponent.addAlphaGradient(1,1);
```

调用`addSpeedScaleGradient`动态改变粒子运动过程中的速度大小：

```ts
    particleComponent.addSpeedScaleGradient(0,0);
    particleComponent.addSpeedScaleGradient(0.3,0.5, 1);
    particleComponent.addSpeedScaleGradient(1,2);
```

### 相关方法
### `addSizeGradient`
|参数|类型|描述|
|---|---|---|
|gradient|number|指定所处粒子生命周期的阶段|
|sizeScale|number|指定粒子大小的左区间|
|sizeScale2|number|指定粒子大小的右区间[可选]|

其中`gradient`统一取值范围为[0,1]间，表示相对粒子生命周期的占比，如0.1,即指定
粒子在0.1 * `lifeTime`的时刻；`sizeScale`与`sizeScale2`值的大小为相对于**粒子系统**属性中
`scale`配置的值，如`sizeScale`为2,则粒子体积大小为`size` * 2

### `addColorGradient`
|参数|类型|描述|
|---|---|---|
|gradient|number|指定所处粒子生命周期的阶段|
|color|Vector4|指定粒子颜色的左区间|
|color2|Vector4|指定粒子颜色的右区间[可选]|

### `addAlphaGradient`
|参数|类型|描述|
|---|---|---|
|gradient|number|指定所处粒子生命周期的阶段|
|alpha|number|指定粒子颜色透明度的左区间|
|alpha2|number|指定粒子颜色透明度的右区间[可选]|

### `addSpeedScaleGradient`
|参数|类型|描述|
|---|---|---|
|gradient|number|指定所处粒子生命周期的阶段|
|speedScale|number|指定粒子速度的左区间|
|speedScale2|number|指定粒子速度的右区间[可选]|

`speedScale`与`speedScale2`值的大小为相对于**粒子系统**属性中
`speed`配置的值，如`speedScale`为2,则粒子速度大小为`speed` * s2

## 动画粒子

首先我们需要创建一个图集资源，如实例所示，命名此资源名为"particle-atlas":

```xml
    <xr-asset-load type="atlas" asset-id="particle-atlas" src="/path/to/atlas.json" />
    <xr-particle capacity="100" size="2" emit-rate="12" life-time="4" angle="0 360" atlas="particle-atlas" atlas-frames="frame-name" atlas-speed="4" atlas-random="true" atlas-loop="true"></xr-particle>
```

粒子将从图集依次序取出对应纹理样式进行渲染
- atlas-random：决定默认的纹理从第一张开始或者是随机
- atlas-frames：指定图集中特定的纹理名字参与渲染
- atlas-speed：将控制纹理的变化速度
- atlas-loop：决定当轮转到图集最后一张纹理时，是否回到第一张纹理开始渲染

## 子发射器

目前系统支持构建子发射器，可以通过构建子发射器实现类似的烟花绽放的粒子效果。
示例如下，为子发射器构建参数的过程与粒子系统的构建基本一致，可以参考粒子系统的相关参数介绍。

```xml
 <xr-asset-load type="texture" asset-id="particlePoint" src="xxx" /> <!-- xxx为纹理的url -->
```

```ts
   var myData ={}
    myData = {
      "capacity": 10,
      "emitRate": 5,
      "size":[0.1],
      "startColor":[1,1,0,1],
      "endColor":[1,1,0,1],
      "emitterType":"SphereShape",
      "emitterProps": [["radius","0.1"]],
      "stopDuration":3,
      "lifeTime":[3],
      "texture":"particlePoint", // xxx为纹理的url
      "speed":[0.5],
    }
    const particleSystemElement = xrScene.getElementById("xxxx"); // xxx为粒子系统的id命名
    tempSystem = particleSystemElement.getComponent(xrFrameSystem.Particle)
    var subEmitter = this.createSubEmitter(myData)
    subEmitter.state = 0
    //可以规定多个子发射器的阵列
    particleComponent.subEmitters = [subEmitter]
```

如`myData`的配置所示，调用`createSubEmitter`创建一个子发射器，具体参数类型参考粒子系统的相关参数介绍:

### 相关属性
`SubEmitterState`
|参数|类型|描述|默认值
|---|---|---|---|
|ATTACH|number|指定发射器为附加类型|0|
|END|number|指定发射器为粒子结束时生成|1|

`SubEmitterState.ATTACH`  
当一个粒子产生时，从子发射器阵列中随机选择一种并附加到新粒子上，用于在新粒子上创建拖尾粒子效果。

`SubEmitterState.END`   
当粒子灭亡时，从子发射器阵列中随机选择一种进行克隆并渲染，用于在新粒子上创建收尾特效。
