mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-02-28 17:37:07 +08:00
feat: 优化着色器组件
This commit is contained in:
parent
2561d7f23d
commit
57760d501e
@ -75,6 +75,8 @@ Mota.require('var', 'hook').once('reset', () => {
|
||||
const transform = render.transform;
|
||||
render.mount();
|
||||
|
||||
const ani = new Animation();
|
||||
|
||||
const shader = new Shader();
|
||||
const layer = new LayerGroup();
|
||||
|
||||
@ -93,14 +95,35 @@ Mota.require('var', 'hook').once('reset', () => {
|
||||
shader.appendChild(layer);
|
||||
shader.size(480, 480);
|
||||
shader.fs(`
|
||||
uniform float u_offset;
|
||||
|
||||
void main() {
|
||||
vec2 coord = v_texCoord;
|
||||
if (coord.y > 0.25 && coord.y < 0.35) {
|
||||
coord.y = sin((coord.y - 0.25) * 3.1415926535 / 0.2) * 0.1 + 0.25;
|
||||
}
|
||||
gl_FragColor = texture2D(u_sampler, coord);
|
||||
// 计算当前像素到爆炸中心的距离
|
||||
vec2 coordToCenter = v_texCoord - vec2(0.5, 0.5);
|
||||
float distance = length(coordToCenter);
|
||||
|
||||
// 根据时间计算当前距离上的波动相位
|
||||
float wavePhase = 100.0 * (distance - u_offset);
|
||||
|
||||
// 计算波动的强度(正弦波)并结合衰减
|
||||
float wave = sin(wavePhase) * 0.02 / (1.0 + 10.0 * distance);
|
||||
|
||||
// 将波动效果应用到纹理坐标上,造成扭曲
|
||||
vec2 warpedCoords = v_texCoord + normalize(coordToCenter) * wave;
|
||||
|
||||
// 采样纹理并输出颜色
|
||||
gl_FragColor = texture2D(u_sampler, warpedCoords);
|
||||
}
|
||||
`);
|
||||
shader.compileShader();
|
||||
|
||||
const offset = shader.getUniform('u_offset');
|
||||
shader.delegateTicker(() => {
|
||||
shader.gl.uniform1f(offset, ani.value.offset);
|
||||
shader.update();
|
||||
}, 20000);
|
||||
ani.value.offset = 0;
|
||||
ani.mode(linear()).time(10000).absolute().apply('offset', 1);
|
||||
|
||||
layer.requestAfterFrame(() => {
|
||||
hero.setImage(core.material.images.images['hero2.png']);
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { isNil } from 'lodash-es';
|
||||
import { logger } from '../common/logger';
|
||||
import { MotaOffscreenCanvas2D } from '../fx/canvas2d';
|
||||
import { isWebGL2Supported } from '../fx/webgl';
|
||||
import { Container } from './container';
|
||||
import { ERenderItemEvent, RenderItemPosition } from './item';
|
||||
import { ERenderItemEvent, RenderItem, RenderItemPosition } from './item';
|
||||
import { Transform } from './transform';
|
||||
|
||||
const SHADER_VERTEX_PREFIX_300 = /* glsl */ `#version 300 es
|
||||
@ -94,6 +95,8 @@ export class Shader extends Container<EShaderEvent> {
|
||||
private shaderModified: boolean = false;
|
||||
/** 需要重新编译的着色器 */
|
||||
private shaderDirty: boolean = true;
|
||||
/** 是否需要重新渲染着色器 */
|
||||
private shaderRanderDirty: boolean = true;
|
||||
/** 当前程序是否被外部调用过 */
|
||||
private programExterned: boolean = false;
|
||||
|
||||
@ -141,7 +144,6 @@ export class Shader extends Container<EShaderEvent> {
|
||||
if (this.shaderDirty) {
|
||||
this.cacheDirty = true;
|
||||
this.compileShader();
|
||||
this.shaderDirty = false;
|
||||
}
|
||||
|
||||
if (this.cacheDirty) {
|
||||
@ -150,10 +152,14 @@ export class Shader extends Container<EShaderEvent> {
|
||||
ctx.save();
|
||||
super.render(this.cache, transform);
|
||||
ctx.restore();
|
||||
this.drawScene();
|
||||
this.cacheDirty = false;
|
||||
}
|
||||
|
||||
if (this.shaderRanderDirty) {
|
||||
this.drawScene();
|
||||
this.shaderRanderDirty = false;
|
||||
}
|
||||
|
||||
canvas.ctx.drawImage(this.canvas, 0, 0, this.width, this.height);
|
||||
}
|
||||
}
|
||||
@ -175,9 +181,17 @@ export class Shader extends Container<EShaderEvent> {
|
||||
this.canvas.height = height * scale;
|
||||
}
|
||||
|
||||
update(item?: RenderItem<any>): void {
|
||||
const isSelf = item === this && !this.cacheDirty;
|
||||
super.update(item);
|
||||
if (isSelf) this.cacheDirty = false;
|
||||
this.shaderRanderDirty = true;
|
||||
}
|
||||
|
||||
drawScene() {
|
||||
const gl = this.gl;
|
||||
if (!this.uniform || !gl) return;
|
||||
|
||||
// 清空画布
|
||||
gl.viewport(0, 0, this.canvas.width, this.canvas.height);
|
||||
|
||||
@ -305,6 +319,7 @@ export class Shader extends Container<EShaderEvent> {
|
||||
Shader.deleteProgram(this, this.getProgram());
|
||||
}
|
||||
this.programExterned = false;
|
||||
this.shaderDirty = false;
|
||||
|
||||
this.program = program.program;
|
||||
this.shader = program.shader;
|
||||
@ -313,6 +328,32 @@ export class Shader extends Container<EShaderEvent> {
|
||||
this.gl?.useProgram(this.program);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取属性位置
|
||||
* @param name 属性名称
|
||||
*/
|
||||
getAttribute(name: string) {
|
||||
if (!this.attribute || !this.gl || !this.program) return null;
|
||||
if (!isNil(this.attribute[name])) return this.attribute[name];
|
||||
return (this.attribute[name] = this.gl.getAttribLocation(
|
||||
this.program,
|
||||
name
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取uniform位置
|
||||
* @param name 属性名称
|
||||
*/
|
||||
getUniform(name: string) {
|
||||
if (!this.uniform || !this.gl || !this.program) return null;
|
||||
if (!isNil(this.uniform[name])) return this.uniform[name];
|
||||
return (this.uniform[name] = this.gl.getUniformLocation(
|
||||
this.program,
|
||||
name
|
||||
));
|
||||
}
|
||||
|
||||
// ----- 初始化部分
|
||||
|
||||
private init() {
|
||||
|
Loading…
Reference in New Issue
Block a user