haxiomic / vector-math

Shader-math in haxe: library for GLSL vector operations, complete with swizzles and all
MIT License
39 stars 7 forks source link

Create GLSL code #15

Open rainyt opened 3 years ago

rainyt commented 3 years ago

I currently use this library to implement an implementation of GLSL in Haxe for OpenFL: Haxe Source:

package zygame.shader;

import zygame.shader.engine.OpenFLShader;
import VectorMath;

/**
 * 流光效果渲染
 */
// @:debug
class FluxaySuperShader extends OpenFLShader {
    @:uniform public var speed:Float;

    @:precision("highp float")
    @:define("TAU 6.12")
    @:define("MAX_ITER 5")
    override function fragment() {
        super.fragment();
        var time:Float = speed * 0.5 + 5;
        // uv should be the 0-1 uv of texture...
        var uv:Vec2 = gl_openfl_TextureCoordv.xy;
        var p:Vec2 = mod(uv * TAU, TAU) - 250.0;
        var i:Vec2 = vec2(p);
        var c = 1.;
        var inten = .0045;
        for (n in 0...MAX_ITER) {
            var t:Float = time * (1 - (3.5 / float(n + int(1))));
            i = p + vec2(cos(t - i.x) + sin(t + i.y), sin(t - i.y) + cos(1.5 * t + i.x));
            c += 1.0 / length(vec2(p.x / (cos(i.x + t) / inten), p.y / (cos(i.y + t) / inten)));
        }
        c /= float(MAX_ITER);
        c = 1.17 - pow(c, 1.4);
        var tex:Vec4 = texture2D(openfl_Texture, uv);
        var colour:Vec3 = vec3(pow(abs(c), 20.0));
        colour = clamp(colour + vec3(0.0, 0.0, .0), 0.0, tex.a);
        // 混合波光
        var alpha:Float = c * tex[3];
        tex[0] = tex[0] + colour[0] * alpha;
        tex[1] = tex[1] + colour[1] * alpha;
        tex[2] = tex[2] + colour[2] * alpha;
        gl_FragColor = tex + color * tex;
    }

    public function new(speed:Float = 1) {
        super();
        this.setFrameEvent(true);
        this.speed = speed;
    }

    override function onFrame() {
        super.onFrame();
        if (this.u_speed.value == null) {
            this.u_speed.value = [0];
        }
        this.u_speed.value[0] += 1 / 60 * speed;
    }
}

GLSL:

#pragma header
precision highp float;
#define TAU 6.12
#define MAX_ITER 5
uniform float u_speed;

 void main(void){#pragma body
  float time=u_speed*0.5+5.;
  vec2 uv=openfl_TextureCoordv.xy;
  vec2 p=mod(uv*TAU,TAU)-250.0;
  vec2 i=vec2(p);
  float c=1.;
  float inten=.0045;
  for(int n = 0;n<MAX_ITER;n++){
  float t=time*(1.-(3.5/float(n+int(1.))));
i=p+vec2(cos(t-i.x)+sin(t+i.y),sin(t-i.y)+cos(1.5*t+i.x));
c+=1.0/length(vec2(p.x/(cos(i.x+t)/inten),p.y/(cos(i.y+t)/inten)));

};
  c/=float(MAX_ITER);
  c=1.17-pow(c,1.4);
  vec4 tex=texture2D(openfl_Texture,uv);
  vec3 colour=vec3(pow(abs(c),20.0));
  colour=clamp(colour+vec3(0.0,0.0,.0),0.0,tex.a);
  float alpha=c*tex[3];
  tex[0]=tex[0]+colour[0]*alpha;
  tex[1]=tex[1]+colour[1]*alpha;
  tex[2]=tex[2]+colour[2]*alpha;
  gl_FragColor=tex+color*tex;

}

The library is very convenient for me to realize the basic content, I only did the translation.

So I plan to use this library to implement the GLSL basic API currently required. Hope to have more implementation support~

rainyt commented 3 years ago

My Github:https://github.com/rainyt/openfl-glsl

haxiomic commented 3 years ago

Woah! This is very very cool @rainyt!

I've added a link this to the readme, in the future I plan to make a general VectorMath -> GLSL | HLSL | SPIR-V translator – perhaps we can collaborate on that one day!

rainyt commented 3 years ago

Okay, thank you, very much looking forward to it!

rainyt commented 3 years ago

Now you can write GLSL directly in Haxe, you can refer to the example: https://github.com/rainyt/openfl-glsl-samples/blob/main/Source/glsl/Haxe2GLSL.hx

When using HaxeToGLSL, you can access the static variables of the class fragmentSource and vertexSource.

Use:

Haxe2GLSL.fragmentSource;
Haxe2GLSL.vertexSource;

This will have nothing to do with OpenFL.

haxiomic commented 3 years ago

I can't wait to play with this! Great stuff @rainyt