mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-26 19:58:54 +01:00
Pre-failing test for color interpolation during rendering. (#2001)
Before #1996, this failed with: image_test.go:1997: At(1, 0): got: {64 64 128 255}, want: {0 128 128 255} The difference is: - Before, colors were interpolated in straight-color space: - Background: {0 0 255 255} - Vertex A: {255 0 0 0} - Vertex B: {0 255 0 255} - Interpolated: {128 128 0 128} - Premultiplied: {64 64 0 128} - Onto Background: {64 64 128 255} - After, colors are interpolated in premultiplied space: - Background: {0 0 255 255} - Vertex A: {255 0 0 0} - Vertex A premultiplied: {0 0 0 0} - Vertex B: {0 255 0 255} - Vertex B premultiplied: {0 255 0 255} - Interpolated: {0 128 0 128} - Onto Background: {0 128 128 255} This DIFFERS from the sample fragment shader, which returns the color as is (Kage allows vertex color values to be used for arbitrary purposes and interpolates independently): - Shader sample: - Background: {0 0 255 255} - Vertex A: {255 0 0 0} - Vertex B: {0 255 0 255} - Interpolated: {128 128 0 128} - Onto Background: {128 128 128 255} as the blend function is `GL_ONE` / `GL_ONE_MINUS_SRC_ALPHA`. This shader behavior is unchanged but has been documented by #1996.
This commit is contained in:
parent
f2209a0b51
commit
62229e82a6
151
image_test.go
151
image_test.go
@ -1928,6 +1928,157 @@ func TestImageDrawTrianglesWithColorM(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImageDrawTrianglesInterpolatesColors(t *testing.T) {
|
||||||
|
const w, h = 3, 1
|
||||||
|
src := ebiten.NewImage(w, h)
|
||||||
|
dst := ebiten.NewImage(w, h)
|
||||||
|
src.Fill(color.White)
|
||||||
|
|
||||||
|
vs := []ebiten.Vertex{
|
||||||
|
{
|
||||||
|
DstX: 0,
|
||||||
|
DstY: 0,
|
||||||
|
SrcX: 0,
|
||||||
|
SrcY: 0,
|
||||||
|
ColorR: 1,
|
||||||
|
ColorG: 0,
|
||||||
|
ColorB: 0,
|
||||||
|
ColorA: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DstX: w,
|
||||||
|
DstY: 0,
|
||||||
|
SrcX: w,
|
||||||
|
SrcY: 0,
|
||||||
|
ColorR: 0,
|
||||||
|
ColorG: 1,
|
||||||
|
ColorB: 0,
|
||||||
|
ColorA: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DstX: 0,
|
||||||
|
DstY: h,
|
||||||
|
SrcX: 0,
|
||||||
|
SrcY: h,
|
||||||
|
ColorR: 1,
|
||||||
|
ColorG: 0,
|
||||||
|
ColorB: 0,
|
||||||
|
ColorA: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DstX: w,
|
||||||
|
DstY: h,
|
||||||
|
SrcX: w,
|
||||||
|
SrcY: h,
|
||||||
|
ColorR: 0,
|
||||||
|
ColorG: 1,
|
||||||
|
ColorB: 0,
|
||||||
|
ColorA: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dst.Fill(color.RGBA{0x00, 0x00, 0xff, 0xff})
|
||||||
|
op := &ebiten.DrawTrianglesOptions{}
|
||||||
|
is := []uint16{0, 1, 2, 1, 2, 3}
|
||||||
|
dst.DrawTriangles(vs, is, src, op)
|
||||||
|
|
||||||
|
got := dst.At(1, 0).(color.RGBA)
|
||||||
|
|
||||||
|
// Correct color interpolation uses the alpha channel and notices that colors on the left side of the texture are fully transparent.
|
||||||
|
want := color.RGBA{0x00, 0x80, 0x80, 0xff}
|
||||||
|
|
||||||
|
// Interpolation isn't exactly specified, so a range is accepable.
|
||||||
|
diff := math.Max(math.Max(math.Max(
|
||||||
|
math.Abs(float64(got.R)-float64(want.R)),
|
||||||
|
math.Abs(float64(got.G)-float64(want.G))),
|
||||||
|
math.Abs(float64(got.B)-float64(want.B))),
|
||||||
|
math.Abs(float64(got.A)-float64(want.A)))
|
||||||
|
|
||||||
|
if diff > 5 {
|
||||||
|
t.Errorf("At(1, 0): got: %v, want: %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestImageDrawTrianglesShaderInterpolatesValues(t *testing.T) {
|
||||||
|
const w, h = 3, 1
|
||||||
|
src := ebiten.NewImage(w, h)
|
||||||
|
dst := ebiten.NewImage(w, h)
|
||||||
|
src.Fill(color.White)
|
||||||
|
|
||||||
|
vs := []ebiten.Vertex{
|
||||||
|
{
|
||||||
|
DstX: 0,
|
||||||
|
DstY: 0,
|
||||||
|
SrcX: 0,
|
||||||
|
SrcY: 0,
|
||||||
|
ColorR: 1,
|
||||||
|
ColorG: 0,
|
||||||
|
ColorB: 0,
|
||||||
|
ColorA: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DstX: w,
|
||||||
|
DstY: 0,
|
||||||
|
SrcX: w,
|
||||||
|
SrcY: 0,
|
||||||
|
ColorR: 0,
|
||||||
|
ColorG: 1,
|
||||||
|
ColorB: 0,
|
||||||
|
ColorA: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DstX: 0,
|
||||||
|
DstY: h,
|
||||||
|
SrcX: 0,
|
||||||
|
SrcY: h,
|
||||||
|
ColorR: 1,
|
||||||
|
ColorG: 0,
|
||||||
|
ColorB: 0,
|
||||||
|
ColorA: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
DstX: w,
|
||||||
|
DstY: h,
|
||||||
|
SrcX: w,
|
||||||
|
SrcY: h,
|
||||||
|
ColorR: 0,
|
||||||
|
ColorG: 1,
|
||||||
|
ColorB: 0,
|
||||||
|
ColorA: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
dst.Fill(color.RGBA{0x00, 0x00, 0xff, 0xff})
|
||||||
|
op := &ebiten.DrawTrianglesShaderOptions{
|
||||||
|
Images: [4]*ebiten.Image{src, nil, nil, nil},
|
||||||
|
}
|
||||||
|
is := []uint16{0, 1, 2, 1, 2, 3}
|
||||||
|
shader, err := ebiten.NewShader([]byte(`
|
||||||
|
package main
|
||||||
|
func Fragment(position vec4, texCoord vec2, color vec4) vec4 {
|
||||||
|
return color
|
||||||
|
}
|
||||||
|
`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not compile shader: %v", err)
|
||||||
|
}
|
||||||
|
dst.DrawTrianglesShader(vs, is, shader, op)
|
||||||
|
|
||||||
|
got := dst.At(1, 0).(color.RGBA)
|
||||||
|
|
||||||
|
// Shaders get each color value interpolated independently.
|
||||||
|
want := color.RGBA{0x80, 0x80, 0x80, 0xff}
|
||||||
|
|
||||||
|
// Interpolation isn't exactly specified, so a range is accepable.
|
||||||
|
diff := math.Max(math.Max(math.Max(
|
||||||
|
math.Abs(float64(got.R)-float64(want.R)),
|
||||||
|
math.Abs(float64(got.G)-float64(want.G))),
|
||||||
|
math.Abs(float64(got.B)-float64(want.B))),
|
||||||
|
math.Abs(float64(got.A)-float64(want.A)))
|
||||||
|
|
||||||
|
if diff > 5 {
|
||||||
|
t.Errorf("At(1, 0): got: %v, want: %v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Issue #1137
|
// Issue #1137
|
||||||
func TestImageDrawOver(t *testing.T) {
|
func TestImageDrawOver(t *testing.T) {
|
||||||
dst := ebiten.NewImage(320, 240)
|
dst := ebiten.NewImage(320, 240)
|
||||||
|
Loading…
Reference in New Issue
Block a user