Change the texture pixel format to premultiplied alpha (#36)

This commit is contained in:
Hajime Hoshi 2014-12-22 21:39:25 +09:00
parent df6ebd5a9c
commit a3b0831472
4 changed files with 17 additions and 18 deletions

View File

@ -101,7 +101,7 @@ type syncer interface {
} }
// Image represents an image. // Image represents an image.
// The pixel format is non alpha-premultiplied. // The pixel format is alpha-premultiplied.
type Image struct { type Image struct {
syncer syncer syncer syncer
inner *innerImage inner *innerImage

View File

@ -37,11 +37,11 @@ func NextPowerOf2Int(size int) int {
} }
func RGBA(clr color.Color) (r, g, b, a float64) { func RGBA(clr color.Color) (r, g, b, a float64) {
clr2 := color.NRGBA64Model.Convert(clr).(color.NRGBA64) cr, cg, cb, ca := clr.RGBA()
const max = math.MaxUint16 const max = math.MaxUint16
r = float64(clr2.R) / max r = float64(cr) / max
g = float64(clr2.G) / max g = float64(cg) / max
b = float64(clr2.B) / max b = float64(cb) / max
a = float64(clr2.A) / max a = float64(ca) / max
return return
} }

View File

@ -84,15 +84,15 @@ varying vec2 vertex_out_tex_coord1;
void main(void) { void main(void) {
vec4 color0 = texture2D(texture0, vertex_out_tex_coord0); vec4 color0 = texture2D(texture0, vertex_out_tex_coord0);
vec4 color1 = texture2D(texture1, vertex_out_tex_coord1); vec4 color1 = texture2D(texture1, vertex_out_tex_coord1);
// Un-premultiply alpha
color0.rgb /= color0.a;
// Apply the color matrix
color0 = (color_matrix * color0) + color_matrix_translation; color0 = (color_matrix * color0) + color_matrix_translation;
// Premultiply alpha
color0 = clamp(color0, 0.0, 1.0);
color0.rgb *= color0.a;
// Photoshop-like RGBA blending. gl_FragColor = color0 + (1.0 - color0.a) * color1;
//
// NOTE: If the textures are alpha premultiplied, this calc would be much simpler,
// but the color matrix must be applied to the straight alpha colors.
// Thus, straight alpha colors are used in Ebiten.
gl_FragColor.a = color0.a + (1.0 - color0.a) * color1.a;
gl_FragColor.rgb = (color0.a * color0.rgb + (1.0 - color0.a) * color1.a * color1.rgb) / gl_FragColor.a;
} }
`, `,
}, },
@ -104,8 +104,7 @@ varying vec2 vertex_out_tex_coord0;
void main(void) { void main(void) {
vec4 color0 = texture2D(texture0, vertex_out_tex_coord0); vec4 color0 = texture2D(texture0, vertex_out_tex_coord0);
gl_FragColor.rgb = color0.a * color0.rgb; gl_FragColor = color0;
gl_FragColor.a = 1.0;
} }
`, `,
}, },

View File

@ -23,7 +23,7 @@ import (
"image/draw" "image/draw"
) )
func adjustImageForTexture(img image.Image) *image.NRGBA { func adjustImageForTexture(img image.Image) *image.RGBA {
width, height := img.Bounds().Size().X, img.Bounds().Size().Y width, height := img.Bounds().Size().X, img.Bounds().Size().Y
adjustedImageBounds := image.Rectangle{ adjustedImageBounds := image.Rectangle{
image.ZP, image.ZP,
@ -32,11 +32,11 @@ func adjustImageForTexture(img image.Image) *image.NRGBA {
internal.NextPowerOf2Int(height), internal.NextPowerOf2Int(height),
}, },
} }
if nrgba, ok := img.(*image.NRGBA); ok && img.Bounds() == adjustedImageBounds { if nrgba, ok := img.(*image.RGBA); ok && img.Bounds() == adjustedImageBounds {
return nrgba return nrgba
} }
adjustedImage := image.NewNRGBA(adjustedImageBounds) adjustedImage := image.NewRGBA(adjustedImageBounds)
dstBounds := image.Rectangle{ dstBounds := image.Rectangle{
image.ZP, image.ZP,
img.Bounds().Size(), img.Bounds().Size(),