mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/graphicsdriver/opengl, metal, directx: use premultiplied alpha format for color scales
Updates #2365
This commit is contained in:
parent
8a7d860632
commit
5e459bbe42
30
image.go
30
image.go
@ -87,12 +87,10 @@ func (i *Image) Fill(clr color.Color) {
|
|||||||
|
|
||||||
var crf, cgf, cbf, caf float32
|
var crf, cgf, cbf, caf float32
|
||||||
cr, cg, cb, ca := clr.RGBA()
|
cr, cg, cb, ca := clr.RGBA()
|
||||||
if ca != 0 {
|
crf = float32(cr) / 0xffff
|
||||||
crf = float32(cr) / float32(ca)
|
cgf = float32(cg) / 0xffff
|
||||||
cgf = float32(cg) / float32(ca)
|
cbf = float32(cb) / 0xffff
|
||||||
cbf = float32(cb) / float32(ca)
|
caf = float32(ca) / 0xffff
|
||||||
caf = float32(ca) / 0xffff
|
|
||||||
}
|
|
||||||
b := i.Bounds()
|
b := i.Bounds()
|
||||||
x, y := i.adjustPosition(b.Min.X, b.Min.Y)
|
x, y := i.adjustPosition(b.Min.X, b.Min.Y)
|
||||||
i.image.Fill(crf, cgf, cbf, caf, x, y, b.Dx(), b.Dy())
|
i.image.Fill(crf, cgf, cbf, caf, x, y, b.Dx(), b.Dy())
|
||||||
@ -386,9 +384,9 @@ func (i *Image) DrawTriangles(vertices []Vertex, indices []uint16, img *Image, o
|
|||||||
sx, sy := img.adjustPositionF32(v.SrcX, v.SrcY)
|
sx, sy := img.adjustPositionF32(v.SrcX, v.SrcY)
|
||||||
vs[i*graphics.VertexFloatCount+2] = sx
|
vs[i*graphics.VertexFloatCount+2] = sx
|
||||||
vs[i*graphics.VertexFloatCount+3] = sy
|
vs[i*graphics.VertexFloatCount+3] = sy
|
||||||
vs[i*graphics.VertexFloatCount+4] = v.ColorR * cr
|
vs[i*graphics.VertexFloatCount+4] = v.ColorR * v.ColorA * cr
|
||||||
vs[i*graphics.VertexFloatCount+5] = v.ColorG * cg
|
vs[i*graphics.VertexFloatCount+5] = v.ColorG * v.ColorA * cg
|
||||||
vs[i*graphics.VertexFloatCount+6] = v.ColorB * cb
|
vs[i*graphics.VertexFloatCount+6] = v.ColorB * v.ColorA * cb
|
||||||
vs[i*graphics.VertexFloatCount+7] = v.ColorA * ca
|
vs[i*graphics.VertexFloatCount+7] = v.ColorA * ca
|
||||||
}
|
}
|
||||||
is := make([]uint16, len(indices))
|
is := make([]uint16, len(indices))
|
||||||
@ -994,14 +992,9 @@ func NewImageFromImageWithOptions(source image.Image, options *NewImageFromImage
|
|||||||
// colorMToScale returns a new color matrix and color sclaes that equal to the given matrix in terms of the effect.
|
// colorMToScale returns a new color matrix and color sclaes that equal to the given matrix in terms of the effect.
|
||||||
//
|
//
|
||||||
// If the given matrix is merely a scaling matrix, colorMToScale returns
|
// If the given matrix is merely a scaling matrix, colorMToScale returns
|
||||||
// an identity matrix and its scaling factors. This is useful to optimize
|
// an identity matrix and its scaling factors in premultiplied-alpha format.
|
||||||
// the rendering speed by avoiding the use of the color matrix and instead
|
// This is useful to optimize the rendering speed by avoiding the use of the
|
||||||
// multiplying all vertex colors by the scale.
|
// color matrix and instead multiplying all vertex colors by the scale.
|
||||||
//
|
|
||||||
// NOTE: this is only safe when not using a custom Kage shader,
|
|
||||||
// as custom shaders may be using vertex colors for different purposes
|
|
||||||
// than colorization. However, currently there are no Ebitengine APIs that
|
|
||||||
// support both shaders and color matrices.
|
|
||||||
func colorMToScale(colorm affine.ColorM) (newColorM affine.ColorM, r, g, b, a float32) {
|
func colorMToScale(colorm affine.ColorM) (newColorM affine.ColorM, r, g, b, a float32) {
|
||||||
if colorm.IsIdentity() {
|
if colorm.IsIdentity() {
|
||||||
return colorm, 1, 1, 1, 1
|
return colorm, 1, 1, 1, 1
|
||||||
@ -1010,6 +1003,7 @@ func colorMToScale(colorm affine.ColorM) (newColorM affine.ColorM, r, g, b, a fl
|
|||||||
if !colorm.ScaleOnly() {
|
if !colorm.ScaleOnly() {
|
||||||
return colorm, 1, 1, 1, 1
|
return colorm, 1, 1, 1, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
r = colorm.At(0, 0)
|
r = colorm.At(0, 0)
|
||||||
g = colorm.At(1, 1)
|
g = colorm.At(1, 1)
|
||||||
b = colorm.At(2, 2)
|
b = colorm.At(2, 2)
|
||||||
@ -1029,5 +1023,5 @@ func colorMToScale(colorm affine.ColorM) (newColorM affine.ColorM, r, g, b, a fl
|
|||||||
return colorm, 1, 1, 1, 1
|
return colorm, 1, 1, 1, 1
|
||||||
}
|
}
|
||||||
|
|
||||||
return affine.ColorMIdentity{}, r, g, b, a
|
return affine.ColorMIdentity{}, r * a, g * a, b * a, a
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,7 @@ PSInput VSMain(float2 position : POSITION, float2 tex : TEXCOORD, float4 color :
|
|||||||
PSInput result;
|
PSInput result;
|
||||||
result.position = mul(projectionMatrix, float4(position, 0, 1));
|
result.position = mul(projectionMatrix, float4(position, 0, 1));
|
||||||
result.texcoord = tex;
|
result.texcoord = tex;
|
||||||
result.color = float4(color.rgb, 1) * color.a;
|
result.color = color;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +70,7 @@ vertex VertexOut VertexShader(
|
|||||||
VertexOut out = {
|
VertexOut out = {
|
||||||
.position = projectionMatrix * float4(in.position, 0, 1),
|
.position = projectionMatrix * float4(in.position, 0, 1),
|
||||||
.tex = in.tex,
|
.tex = in.tex,
|
||||||
// Fragment shader wants premultiplied alpha.
|
.color = in.color,
|
||||||
.color = float4(in.color.rgb, 1) * in.color.a,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -115,9 +115,7 @@ varying vec4 varying_color_scale;
|
|||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
varying_tex = A1;
|
varying_tex = A1;
|
||||||
|
varying_color_scale = A2;
|
||||||
// Fragment shader wants premultiplied alpha.
|
|
||||||
varying_color_scale = vec4(A2.rgb, 1) * A2.a;
|
|
||||||
|
|
||||||
mat4 projection_matrix = mat4(
|
mat4 projection_matrix = mat4(
|
||||||
vec4(2.0 / viewport_size.x, 0, 0, 0),
|
vec4(2.0 / viewport_size.x, 0, 0, 0),
|
||||||
|
@ -140,14 +140,10 @@ func (i *Image) resolveDotsCacheIfNeeded() {
|
|||||||
for p, c := range i.dotsCache {
|
for p, c := range i.dotsCache {
|
||||||
dx := float32(p[0])
|
dx := float32(p[0])
|
||||||
dy := float32(p[1])
|
dy := float32(p[1])
|
||||||
|
crf := float32(c[0]) / 0xff
|
||||||
var crf, cgf, cbf, caf float32
|
cgf := float32(c[1]) / 0xff
|
||||||
if c[3] != 0 {
|
cbf := float32(c[2]) / 0xff
|
||||||
crf = float32(c[0]) / float32(c[3])
|
caf := float32(c[3]) / 0xff
|
||||||
cgf = float32(c[1]) / float32(c[3])
|
|
||||||
cbf = float32(c[2]) / float32(c[3])
|
|
||||||
caf = float32(c[3]) / 0xff
|
|
||||||
}
|
|
||||||
|
|
||||||
vs[graphics.VertexFloatCount*4*idx] = dx
|
vs[graphics.VertexFloatCount*4*idx] = dx
|
||||||
vs[graphics.VertexFloatCount*4*idx+1] = dy
|
vs[graphics.VertexFloatCount*4*idx+1] = dy
|
||||||
|
Loading…
Reference in New Issue
Block a user