Skip to content

Commit

Permalink
ebiten: use zero values for an unspecified uniform variable
Browse files Browse the repository at this point in the history
Closes #2709
  • Loading branch information
hajimehoshi committed Jul 29, 2023
1 parent d0e4023 commit 0b1c740
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
4 changes: 4 additions & 0 deletions image.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@ type DrawTrianglesShaderOptions struct {
// If the uniform variable type is an array, a vector or a matrix,
// you have to specify linearly flattened values as a slice or an array.
// For example, if the uniform variable type is [4]vec4, the length will be 16.
//
// If a uniform variable's name doesn't exist in Uniforms, this is treated as if zero values are specified.
Uniforms map[string]any

// Images is a set of the source images.
Expand Down Expand Up @@ -710,6 +712,8 @@ type DrawRectShaderOptions struct {
// If the uniform variable type is an array, a vector or a matrix,
// you have to specify linearly flattened values as a slice or an array.
// For example, if the uniform variable type is [4]vec4, the length will be 16.
//
// If a uniform variable's name doesn't exist in Uniforms, this is treated as if zero values are specified.
Uniforms map[string]any

// Images is a set of the source images.
Expand Down
3 changes: 3 additions & 0 deletions internal/ui/shader.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ func (s *Shader) AppendUniforms(dst []uint32, uniforms map[string]any) []uint32
origLen := len(dst)
if cap(dst)-len(dst) >= s.uniformUint32Count {
dst = dst[:len(dst)+s.uniformUint32Count]
for i := origLen; i < len(dst); i++ {
dst[i] = 0
}
} else {
dst = append(dst, make([]uint32, s.uniformUint32Count)...)
}
Expand Down
52 changes: 52 additions & 0 deletions shader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1960,3 +1960,55 @@ func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
})
}
}

// Issue #2709
func TestShaderUniformDefaultValue(t *testing.T) {
const w, h = 16, 16

dst := ebiten.NewImage(w, h)
s, err := ebiten.NewShader([]byte(`//kage:unit pixel
package main
var U vec4
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
return U
}
`))
if err != nil {
t.Fatal(err)
}

// Draw with a uniform variable value.
op := &ebiten.DrawRectShaderOptions{}
op.Uniforms = map[string]any{
"U": [...]float32{1, 1, 1, 1},
}
dst.DrawRectShader(w, h, s, op)

for j := 0; j < h; j++ {
for i := 0; i < w; i++ {
got := dst.At(i, j).(color.RGBA)
want := color.RGBA{0xff, 0xff, 0xff, 0xff}
if got != want {
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
}
}
}

// Draw without a uniform variable value. In this case, the uniform variable value should be 0.
dst.Clear()
op.Uniforms = nil
dst.DrawRectShader(w, h, s, op)

for j := 0; j < h; j++ {
for i := 0; i < w; i++ {
got := dst.At(i, j).(color.RGBA)
want := color.RGBA{0, 0, 0, 0}
if got != want {
t.Errorf("dst.At(%d, %d): got: %v, want: %v", i, j, got, want)
}
}
}
}

0 comments on commit 0b1c740

Please sign in to comment.