hajimehoshi / ebiten

Ebitengine - A dead simple 2D game engine for Go
https://ebitengine.org
Apache License 2.0
11.13k stars 663 forks source link

kage: local variable order is not used #3011

Closed tinne26 closed 2 months ago

tinne26 commented 5 months ago

Ebitengine Version

v2.7.4

Operating System

Go Version (go version)

go1.22.2

What steps will reproduce the problem?

func HSLToRGB(hsl vec3) vec3 {
    saturation := hsl[1]/100.0
    lightness  := hsl[2]/100.0

    c := (1 - abs(2*lightness - 1))*saturation
    x := c*(1 - abs(mod((hsl[0]/60.0), 2.0) - 1))
    m := lightness - c/2.0

    order := [6]ivec3{
        ivec3(2, 0, 1), ivec3(2, 1, 0),
        ivec3(0, 1, 2), ivec3(0, 2, 1),
        ivec3(1, 2, 0), ivec3(1, 0, 2),
    }[int(floor(hsl.x/60.0))]
    var rgb vec3
    rgb[order[0]] = 0 + m
    rgb[order[1]] = c + m
    rgb[order[2]] = x + m
    return rgb
}

What is the expected result?

Would be nice if it worked, but I don't really know if that kind of dynamic indexing is intended to be supported or not.

What happens instead?

The first error is: local variable order is not used.

If I _ = order at the end of the code to bypass that, I get a panic at go/pkg/mod/github.com/hajimehoshi/ebiten/v2@v2.6.0/internal/graphicscommand/command.go:377. EDIT: wait, I have v2.7.4, why does this say 2.6.0..?

Anything else you feel useful to add?

No response

hajimehoshi commented 4 months ago

Would be nice if it worked, but I don't really know if that kind of dynamic indexing is intended to be supported or not.

IIUC this is not supported. Does this work with GLSL for example?

hajimehoshi commented 4 months ago

Oh this should work. Let me see...

#extension GL_OES_standard_derivatives : enable

precision highp float;

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

void main( void ) {

    vec2 position = ( gl_FragCoord.xy / resolution.xy ) + mouse / 4.0;

    float color = 0.0;
    color += sin( position.x * cos( time / 15.0 ) * 80.0 ) + cos( position.y * cos( time / 15.0 ) * 10.0 );
    color += sin( position.y * sin( time / 10.0 ) * 40.0 ) + cos( position.x * sin( time / 25.0 ) * 40.0 );
    color += sin( position.x * sin( time / 5.0 ) * 10.0 ) + sin( position.y * sin( time / 35.0 ) * 80.0 );
    color *= sin( time / 10.0 ) * 0.5;

    vec4 x = vec4( vec3( color, color * 0.5, sin( color + time / 3.0 ) * 0.75 ), 1.0 );
    float y = x[0];
    x[0] = y;
    gl_FragColor = x;
}
hajimehoshi commented 4 months ago
#extension GL_OES_standard_derivatives : enable

precision highp float;

uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;

void main( void ) {

    vec2 position = ( gl_FragCoord.xy / resolution.xy ) + mouse / 4.0;

    float color = 0.0;
    color += sin( position.x * cos( time / 15.0 ) * 80.0 ) + cos( position.y * cos( time / 15.0 ) * 10.0 );
    color += sin( position.y * sin( time / 10.0 ) * 40.0 ) + cos( position.x * sin( time / 25.0 ) * 40.0 );
    color += sin( position.x * sin( time / 5.0 ) * 10.0 ) + sin( position.y * sin( time / 35.0 ) * 80.0 );
    color *= sin( time / 10.0 ) * 0.5;

    int idx = 0;
    vec4 x = vec4( vec3( color, color * 0.5, sin( color + time / 3.0 ) * 0.75 ), 1.0 );
    float y = x[idx];
    x[0] = y;
    gl_FragColor = x;
}

This doesn't work. "ERROR: 0:21: '[]' : Index expression must be constant"

hajimehoshi commented 2 months ago

WebGL 2 should support the dyaic index, as @Zyko0 says

hajimehoshi commented 2 months ago

I couldn't reproduce the issue even with 2.6.0.

diff --git a/internal/shader/syntax_test.go b/internal/shader/syntax_test.go
index fae669880..f92b6f138 100644
--- a/internal/shader/syntax_test.go
+++ b/internal/shader/syntax_test.go
@@ -3818,3 +3818,37 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
                }
        }
 }
+
+// Issue #3011
+func TestSyntaxUseVarForIndex(t *testing.T) {
+       if _, err := compileToIR([]byte(`package main
+
+func HSLToRGB(hsl vec3) vec3 {
+       saturation := hsl[1]/100.0
+       lightness  := hsl[2]/100.0
+
+       c := (1 - abs(2*lightness - 1))*saturation
+       x := c*(1 - abs(mod((hsl[0]/60.0), 2.0) - 1))
+       m := lightness - c/2.0
+
+       order := [6]ivec3{
+               ivec3(2, 0, 1), ivec3(2, 1, 0),
+               ivec3(0, 1, 2), ivec3(0, 2, 1),
+               ivec3(1, 2, 0), ivec3(1, 0, 2),
+       }[int(floor(hsl.x/60.0))]
+       var rgb vec3
+       rgb[order[0]] = 0 + m
+       rgb[order[1]] = c + m
+       rgb[order[2]] = x + m
+       return rgb
+}
+
+func Foo() float {
+       x := ivec2(0)
+       y := vec2(0)
+       return y[x[0]]
+}
+`)); err != nil {
+               t.Error(err)
+       }
+}

EDIT: Sorry I was testing on a wrong commit. I could reproduce this with v2.6.0. And also this was already fixed at v2.6.7.

hajimehoshi commented 2 months ago

2c967dd24e63b388479c71f2648418c14f7b94b7 already fixed the issue. See #2848