Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
 .. Failed to load latest commit information. assets component controller asyncModule.ts cover.jpg index.ts readme.md types.ts

# ImageFragmentTransition

2D图形碎片化转换鲜果。

## 原理

### 使用顶点构成三角片

1. 构造基于Buffer的几何体并生成顶点数据：
```function disposeArray() {
this.array = null;
}

const geometry = new THREE.BufferGeometry();
const positions = [x0, y0, z0, x1, y1, z1, x2, y2, z2];

`attribute vec3 position;`
```const material = new THREE.RawShaderMaterial({
uniforms,
});
material.needsUpdate = true;  ```

1. 生成曲面：
`const mesh = new THREE.Mesh(geometry, material);`

### 使用三角片构造平面

`const positions = [l, t, 0, r, t, 0, l, b, 0, l, b, 0, r, b, 0, r, t, 0];`

```const stepX = .1;
const stepY = .05;
const hStepX = stepX;
const hStepY = stepY;

for (let x = left; x < right; x += stepX) {
for (let y = top; y < bottom; y += stepY) {
const xL = x;
const xR = x + hStepX;
const yT = y;
const yB = y + hStepY;

positions.push(xL, yT, 0);
positions.push(xL, yB, 0);
positions.push(xR, yB, 0);
positions.push(xL, yT, 0);
positions.push(xR, yT, 0);
positions.push(xR, yB, 0);
}
}```

### 着色

���上面说的都是如何生成顶点，但还有很重要的一步没说——如何给三角片着色？有过一定基础的同学应该都知道，在fragment shader中我们一般是通过uv坐标来采样纹理输出颜色，大家有没想过这个uv是从哪来的？不错，这个uv实际上是从vertex shader中的attribute变量传来的，而这个attribute和`position`一样，都是在CPU中算好（存储在模型顶点数据中）的：

```for (let x = left; x < right; x += stepX) {
for (let y = top; y < bottom; y += stepY) {
// positions
......

uvs.push((xL + right) / width, (yT + bottom) / height);
uvs.push((xL + right) / width, (yB + bottom) / height);
uvs.push((xR + right) / width, (yB + bottom) / height);
uvs.push((xL + right) / width, (yT + bottom) / height);
uvs.push((xR + right) / width, (yT + bottom) / height);
uvs.push((xR + right) / width, (yB + bottom) / height);
}
}

`attribute vec2 uv;`

### 打碎！添加attribute连接顶点

```vec3 new_position = position;
new_position.z += position.x;

gl_Position = projectionMatrix * modelViewMatrix * vec4(new_position, 1.0);```

```for (let x = left; x < right; x += stepX) {
for (let y = top; y < bottom; y += stepY) {
// positions, uvs
......

for (let i = 0; i < 3; i += 1) {
centres.push(xL + (xR - xL) / 4, (yT + yB) / 2, 0);
}

for (let i = 0; i < 3; i += 1) {
centres.push(xR - (xR - xL) / 4, (yT + yB) / 2, 0);
}
}
}

`new_position.z += centre.x;`

### 动起来

```attribute vec3 position;
attribute vec3 centre;
attribute vec2 uv;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform float progress;
uniform float top;
uniform float left;
uniform float width;
uniform float height;

varying vec2 vUv;

vec3 rotate_around_z_in_degrees(vec3 vertex, float degree) {
float alpha = degree * 3.14 / 180.0;
float sina = sin(alpha);
float cosa = cos(alpha);
mat2 m = mat2(cosa, -sina, sina, cosa);
return vec3(m * vertex.xy, vertex.z).xyz;
}

void main() {
vUv = uv;
vec3 new_position = position;
vec3 center = vec3(left + width * 0.5, top + height * 0.5, 0);
vec3 dist = center - centre;
float len = length(dist);
float factor;

if (progress < 0.5) {
factor = progress;
} else {
factor = (1. - progress);
}

float factor1 = len * factor * 10.;
new_position.x -= sin(dist.x * factor1);
new_position.y -= sin(dist.y * factor1);
new_position.z += factor1;
new_position = rotate_around_z_in_degrees(new_position, progress * 360.);

gl_Position = projectionMatrix * modelViewMatrix * vec4(new_position, 1.0);
}```

### 两张图片自然过渡

```uniform sampler2D image1;
uniform sampler2D image2;
uniform float progress;

varying vec2 vUv;

void main() {
vec4 t_image;
vec4 t_image1 = texture2D(image1, vUv);
vec4 t_image2 = texture2D(image2, vUv);

t_image = progress * t_image1 + (1. - progress) * t_image2;

gl_FragColor = t_image;
}```