HeapsIO / heaps

Heaps : Haxe Game Framework
http://heaps.io
MIT License
3.19k stars 337 forks source link

HXSL `return` in entry-point methods breaks shaders #1213

Open Yanrishatum opened 4 months ago

Yanrishatum commented 4 months ago

Honestly not sure if it's a bug or just wrong usage, but it definitely should be handled either at compile time or runtime in one way or another. Having a return; inside fragment or vertex methods would cause shaders to break, as it would exit before outputs are properly assigned. I'd suggest making it a compile time error if return; statement is used inside entry-point methods.

Source: Haxe#Heaps Discord message by kevansevans

Shader code ```haxe class InfGridShader extends Shader { static var SRC = { @:import h3d.shader.Texture; @param var size:Int = 1; @param var scale:Float = 1; @param var offset_x:Float = 0; @param var offset_y:Float = 0; @param var ratioX:Float = 1; @param var ratioY:Float = 1; function vertex() { calculatedUV = input.uv; } function fragment() { var uvOffset:Vec2 = calculatedUV; var copy:Vec4 = pixelColor; //commenting this out completely breaks it for some reason var alph:Float = min((size * (1 / scale)) / 3, 0.5); if (((uvOffset.x - 0.5) / ratioX) % (size * (1 / scale)) <= 0.01) { pixelColor = vec4(1, 1, 1, 1.0); return; } else if (((uvOffset.y - 0.5) / ratioY) % (size * (1 / scale)) <= 0.01) { pixelColor = vec4(1, 1, 1, 1); return; } } } public function new() { super(); } } ```

-D shader_debug_dump dump: 5_dump.txt

Produced fragment shader:

void main(void) {
    pixelColor = fragmentParams[0];
    uvOffset = calculatedUV_varying;
    if( mod(((uvOffset.x - 0.5) / fragmentParams[1].z), (float(int(fragmentParams[1].x)) * (1. / fragmentParams[1].y))) <= 0.01) {
        pixelColor = vec4(1., 1., 1., 1.);
        return;
    } else {
        if( mod(((uvOffset.y - 0.5) / fragmentParams[1].w), (float(int(fragmentParams[1].x)) * (1. / fragmentParams[1].y))) <= 0.01) {
            pixelColor = vec4(1., 1., 1., 1.);
            return;
        };
    };
    lightPixelColor = fragmentGlobals[0].xyz;
    pixelColor.xyz *= _val0();
    color2 = pixelColor;
    OUTPUT1 = color2;
}