diff --git a/pixelgl/attr.go b/pixelgl/attr.go
index cfae110523fde5621cb89a325a5fb22bc351e95a..5757d20929395f002457667bea52943da6a3f4a1 100644
--- a/pixelgl/attr.go
+++ b/pixelgl/attr.go
@@ -18,6 +18,8 @@ const (
 	TexCoord
 	// Transform is an object transformation matrix
 	Transform
+	// MaskColor is a masking color. When drawing, each color gets multiplied by this color.
+	MaskColor
 	// IsTexture signals, whether a texture is present.
 	IsTexture
 	// NumStandardAttrPurposes is the number of standard attribute purposes
diff --git a/window.go b/window.go
index c6104e2c6c51881b3a717e7cfa357413b82a6eef..1ab4a4f79423327ea798567055840b8bb3feb661 100644
--- a/window.go
+++ b/window.go
@@ -333,6 +333,7 @@ var defaultVertexFormat = pixelgl.VertexFormat{
 }
 
 var defaultUniformFormat = pixelgl.UniformFormat{
+	"maskColor": {Purpose: pixelgl.MaskColor, Type: pixelgl.Vec4},
 	"transform": {Purpose: pixelgl.Transform, Type: pixelgl.Mat3},
 	"isTexture": {Purpose: pixelgl.IsTexture, Type: pixelgl.Int},
 }
@@ -364,14 +365,15 @@ in vec2 TexCoord;
 
 out vec4 color;
 
+uniform vec4 maskColor;
 uniform int isTexture;
 uniform sampler2D tex;
 
 void main() {
 	if (isTexture != 0) {
-		color = Color * texture(tex, vec2(TexCoord.x, 1 - TexCoord.y));
+		color = maskColor * Color * texture(tex, vec2(TexCoord.x, 1 - TexCoord.y));
 	} else {
-		color = Color;
+		color = maskColor * Color;
 	}
 }
 `