ebiten: use zero values for an unspecified uniform variable

Closes #2709
This commit is contained in:
Hajime Hoshi 2023-07-29 19:11:46 +09:00
parent d0e4023d88
commit 0b1c7404d5
3 changed files with 59 additions and 0 deletions

View File

@ -535,6 +535,8 @@ type DrawTrianglesShaderOptions struct {
// If the uniform variable type is an array, a vector or a matrix, // 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. // 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. // 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 Uniforms map[string]any
// Images is a set of the source images. // Images is a set of the source images.
@ -710,6 +712,8 @@ type DrawRectShaderOptions struct {
// If the uniform variable type is an array, a vector or a matrix, // 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. // 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. // 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 Uniforms map[string]any
// Images is a set of the source images. // Images is a set of the source images.

View File

@ -55,6 +55,9 @@ func (s *Shader) AppendUniforms(dst []uint32, uniforms map[string]any) []uint32
origLen := len(dst) origLen := len(dst)
if cap(dst)-len(dst) >= s.uniformUint32Count { if cap(dst)-len(dst) >= s.uniformUint32Count {
dst = dst[:len(dst)+s.uniformUint32Count] dst = dst[:len(dst)+s.uniformUint32Count]
for i := origLen; i < len(dst); i++ {
dst[i] = 0
}
} else { } else {
dst = append(dst, make([]uint32, s.uniformUint32Count)...) dst = append(dst, make([]uint32, s.uniformUint32Count)...)
} }

View File

@ -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)
}
}
}
}