mirror of
				https://github.com/unanmed/HumanBreak.git
				synced 2025-11-04 15:12:58 +08:00 
			
		
		
		
	着色器特效支持动画
This commit is contained in:
		
							parent
							
								
									f15007513a
								
							
						
					
					
						commit
						a06021531d
					
				@ -1,6 +1,6 @@
 | 
				
			|||||||
import { Ticker } from 'mutate-animate';
 | 
					import { Animation, Ticker, hyper } from 'mutate-animate';
 | 
				
			||||||
import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
 | 
					import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
 | 
				
			||||||
import { loading } from '../loader/load';
 | 
					import { ensureArray } from '../../plugin/utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface ShaderEvent extends EmitableEvent {}
 | 
					interface ShaderEvent extends EmitableEvent {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -33,6 +33,32 @@ interface MixedImage {
 | 
				
			|||||||
    update(): void;
 | 
					    update(): void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UniformBinderNum = 1 | 2 | 3 | 4;
 | 
				
			||||||
 | 
					type UniformBinderType = 'f' | 'i';
 | 
				
			||||||
 | 
					type UniformFunc<
 | 
				
			||||||
 | 
					    N extends UniformBinderNum,
 | 
				
			||||||
 | 
					    T extends UniformBinderType,
 | 
				
			||||||
 | 
					    V extends 'v' | ''
 | 
				
			||||||
 | 
					> = `uniform${N}${T}${V}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UniformBinderValue<N extends UniformBinderNum> = N extends 1
 | 
				
			||||||
 | 
					    ? number
 | 
				
			||||||
 | 
					    : N extends 2
 | 
				
			||||||
 | 
					    ? [number, number]
 | 
				
			||||||
 | 
					    : N extends 3
 | 
				
			||||||
 | 
					    ? [number, number, number]
 | 
				
			||||||
 | 
					    : [number, number, number, number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface UniformBinder<
 | 
				
			||||||
 | 
					    N extends UniformBinderNum,
 | 
				
			||||||
 | 
					    T extends UniformBinderType,
 | 
				
			||||||
 | 
					    V extends 'v' | ''
 | 
				
			||||||
 | 
					> {
 | 
				
			||||||
 | 
					    value: UniformBinderValue<N>;
 | 
				
			||||||
 | 
					    set(value: UniformBinderValue<N>): void;
 | 
				
			||||||
 | 
					    get(): UniformBinderValue<N>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const builtinVs = `
 | 
					const builtinVs = `
 | 
				
			||||||
#ifdef GL_ES
 | 
					#ifdef GL_ES
 | 
				
			||||||
    precision highp float;
 | 
					    precision highp float;
 | 
				
			||||||
@ -106,25 +132,31 @@ export class ShaderEffect extends EventEmitter<ShaderEvent> {
 | 
				
			|||||||
     * @param compile 是否重新编译着色器脚本,并重新创建纹理
 | 
					     * @param compile 是否重新编译着色器脚本,并重新创建纹理
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    update(compile: boolean = false) {
 | 
					    update(compile: boolean = false) {
 | 
				
			||||||
        const gl = this.gl;
 | 
					        if (compile) this.compile();
 | 
				
			||||||
        if (compile) {
 | 
					 | 
				
			||||||
            gl.deleteProgram(this.program);
 | 
					 | 
				
			||||||
            gl.deleteTexture(this.texture);
 | 
					 | 
				
			||||||
            gl.deleteBuffer(this.buffer?.position ?? null);
 | 
					 | 
				
			||||||
            gl.deleteBuffer(this.buffer?.texture ?? null);
 | 
					 | 
				
			||||||
            gl.deleteShader(this.shader?.vertex ?? null);
 | 
					 | 
				
			||||||
            gl.deleteShader(this.shader?.fragment ?? null);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            this.program = this.createProgram();
 | 
					 | 
				
			||||||
            this.programInfo = this.getProgramInfo();
 | 
					 | 
				
			||||||
            this.buffer = this.initBuffers();
 | 
					 | 
				
			||||||
            this.texture = this.createTexture();
 | 
					 | 
				
			||||||
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        this.textureCanvas?.update();
 | 
					        this.textureCanvas?.update();
 | 
				
			||||||
        this.drawScene();
 | 
					        this.drawScene();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 仅重新编译着色器,不进行纹理创建和特效渲染
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    compile() {
 | 
				
			||||||
 | 
					        const gl = this.gl;
 | 
				
			||||||
 | 
					        gl.deleteProgram(this.program);
 | 
				
			||||||
 | 
					        gl.deleteTexture(this.texture);
 | 
				
			||||||
 | 
					        gl.deleteBuffer(this.buffer?.position ?? null);
 | 
				
			||||||
 | 
					        gl.deleteBuffer(this.buffer?.texture ?? null);
 | 
				
			||||||
 | 
					        gl.deleteShader(this.shader?.vertex ?? null);
 | 
				
			||||||
 | 
					        gl.deleteShader(this.shader?.fragment ?? null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.program = this.createProgram();
 | 
				
			||||||
 | 
					        this.programInfo = this.getProgramInfo();
 | 
				
			||||||
 | 
					        this.buffer = this.initBuffers();
 | 
				
			||||||
 | 
					        this.texture = this.createTexture();
 | 
				
			||||||
 | 
					        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
 | 
				
			||||||
 | 
					        gl.useProgram(this.program);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 设置顶点着色器,使用 glsl 编写,插件提供了一些新的 api
 | 
					     * 设置顶点着色器,使用 glsl 编写,插件提供了一些新的 api
 | 
				
			||||||
     * 着色器中必须包含 main 函数,同时为 gl_Position 赋值
 | 
					     * 着色器中必须包含 main 函数,同时为 gl_Position 赋值
 | 
				
			||||||
@ -182,6 +214,64 @@ export class ShaderEffect extends EventEmitter<ShaderEvent> {
 | 
				
			|||||||
        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
 | 
					        gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * 创建一个全局变量绑定器,用于操作全局变量
 | 
				
			||||||
 | 
					     * @param uniform 全局变量的变量名
 | 
				
			||||||
 | 
					     * @param num 变量的元素数量,float和int视为1,vec2 vec3 vec4分别视为 2 3 4
 | 
				
			||||||
 | 
					     * @param type 数据类型,可以填'f',表示浮点型,或者填'i',表示整型
 | 
				
			||||||
 | 
					     * @param vector 是否为向量,可以填'v',表示是向量,或者填'',表示不是向量
 | 
				
			||||||
 | 
					     * @returns 一个uniform绑定器,用于操作全局变量uniform
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    createUniformBinder<
 | 
				
			||||||
 | 
					        N extends UniformBinderNum,
 | 
				
			||||||
 | 
					        T extends UniformBinderType,
 | 
				
			||||||
 | 
					        V extends 'v' | ''
 | 
				
			||||||
 | 
					    >(uniform: string, num: N, type: T, vector: V): UniformBinder<N, T, V> {
 | 
				
			||||||
 | 
					        if (!this.program) {
 | 
				
			||||||
 | 
					            throw new Error(
 | 
				
			||||||
 | 
					                `Uniform binder should be use when the program initialized.`
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const suffix = `${num}${type}${vector ? 'v' : ''}`;
 | 
				
			||||||
 | 
					        const func = `uniform${suffix}` as UniformFunc<N, T, V>;
 | 
				
			||||||
 | 
					        const value = (
 | 
				
			||||||
 | 
					            num === 1 ? 0 : Array(num).fill(0)
 | 
				
			||||||
 | 
					        ) as UniformBinderValue<N>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const loc = this.gl.getUniformLocation(this.program, uniform);
 | 
				
			||||||
 | 
					        const gl = this.gl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					            value,
 | 
				
			||||||
 | 
					            set(value) {
 | 
				
			||||||
 | 
					                this.value = value;
 | 
				
			||||||
 | 
					                let v;
 | 
				
			||||||
 | 
					                if (vector === 'v') {
 | 
				
			||||||
 | 
					                    let _v = ensureArray(value);
 | 
				
			||||||
 | 
					                    if (type === 'f') {
 | 
				
			||||||
 | 
					                        v = new Float32Array(_v);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        v = new Int32Array(_v);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    v = ensureArray(value);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                // 对uniform赋值
 | 
				
			||||||
 | 
					                if (vector === 'v') {
 | 
				
			||||||
 | 
					                    // @ts-ignore
 | 
				
			||||||
 | 
					                    gl[func](loc, v);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    // @ts-ignore
 | 
				
			||||||
 | 
					                    gl[func](loc, ...v);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            get() {
 | 
				
			||||||
 | 
					                return this.value;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private createProgram() {
 | 
					    private createProgram() {
 | 
				
			||||||
        const gl = this.gl;
 | 
					        const gl = this.gl;
 | 
				
			||||||
        const vs = this.loadShader(gl.VERTEX_SHADER, this.vsSource);
 | 
					        const vs = this.loadShader(gl.VERTEX_SHADER, this.vsSource);
 | 
				
			||||||
@ -398,7 +488,8 @@ export function replaceGameCanvas(effect: ShaderEffect, canvas: string[]) {
 | 
				
			|||||||
    let zIndex = 0;
 | 
					    let zIndex = 0;
 | 
				
			||||||
    canvas.forEach(v => {
 | 
					    canvas.forEach(v => {
 | 
				
			||||||
        const canvas = core.canvas[v].canvas;
 | 
					        const canvas = core.canvas[v].canvas;
 | 
				
			||||||
        const z = parseInt(canvas.style.zIndex);
 | 
					        const style = getComputedStyle(canvas);
 | 
				
			||||||
 | 
					        const z = parseInt(style.zIndex);
 | 
				
			||||||
        if (z > zIndex) zIndex = z;
 | 
					        if (z > zIndex) zIndex = z;
 | 
				
			||||||
        canvas.style.display = 'none';
 | 
					        canvas.style.display = 'none';
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user