Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A MeshStyle for Starling 2 that discards texels with an alpha value below a certain threshold. This makes it perfect for arbitrarily shaped stencil masks.
// =================================================================================================
//
// Starling Framework
// Copyright 2011-2016 Gamua. All Rights Reserved.
//
// This program is free software. You can redistribute and/or modify it
// in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================
package starling.extensions
{
import starling.display.Mesh;
import starling.rendering.MeshEffect;
import starling.rendering.VertexDataFormat;
import starling.styles.MeshStyle;
public class TextureMaskStyle extends MeshStyle
{
public static const VERTEX_FORMAT:VertexDataFormat =
MeshStyle.VERTEX_FORMAT.extend("threshold:float1");
private var _threshold:Number;
public function TextureMaskStyle(threshold:Number=0.5)
{
_threshold = threshold;
}
override public function copyFrom(meshStyle:MeshStyle):void
{
var otherStyle:TextureMaskStyle = meshStyle as TextureMaskStyle;
if (otherStyle) _threshold = otherStyle._threshold;
super.copyFrom(meshStyle);
}
override public function createEffect():MeshEffect
{
return new TextureMaskEffect();
}
override public function get vertexFormat():VertexDataFormat
{
return VERTEX_FORMAT;
}
override protected function onTargetAssigned(target:Mesh):void
{
updateVertices();
}
private function updateVertices():void
{
var numVertices:int = vertexData.numVertices;
for (var i:int=0; i<numVertices; ++i)
vertexData.setFloat(i, "threshold", _threshold);
setRequiresRedraw();
}
// properties
public function get threshold():Number { return _threshold; }
public function set threshold(value:Number):void
{
if (_threshold != value && target)
{
_threshold = value;
updateVertices();
}
}
}
}
import flash.display3D.Context3D;
import starling.extensions.TextureMaskStyle;
import starling.rendering.MeshEffect;
import starling.rendering.Program;
import starling.rendering.VertexDataFormat;
class TextureMaskEffect extends MeshEffect
{
public static const VERTEX_FORMAT:VertexDataFormat = TextureMaskStyle.VERTEX_FORMAT;
public function TextureMaskEffect()
{ }
override protected function createProgram():Program
{
if (texture)
{
var vertexShader:String = [
"m44 op, va0, vc0", // 4x4 matrix transform to output clip-space
"mov v0, va1 ", // pass texture coordinates to fragment program
"mul v1, va2, vc4", // multiply alpha (vc4) with color (va2), pass to fp
"mov v2, va3 " // pass threshold to fp
].join("\n");
var fragmentShader:String = [
tex("ft0", "v0", 0, texture),
"sub ft1, ft0, v2.xxxx", // subtract threshold
"kil ft1.w ", // abort if alpha < 0
"mul oc, ft0, v1 " // else multiply with color & copy to output buffer
].join("\n");
return Program.fromSource(vertexShader, fragmentShader);
}
else return super.createProgram();
}
override protected function beforeDraw(context:Context3D):void
{
super.beforeDraw(context);
if (texture) vertexFormat.setVertexBufferAt(3, vertexBuffer, "threshold");
}
override protected function afterDraw(context:Context3D):void
{
if (texture) context.setVertexBufferAt(3, null);
super.afterDraw(context);
}
override public function get vertexFormat():VertexDataFormat
{
return VERTEX_FORMAT;
}
}
@soccerob

This comment has been minimized.

Copy link

soccerob commented Mar 14, 2016

var style:TextureMaskStyle = new TextureMaskStyle(0.8);

the above line will cause the following error just by creating a new instance of a TextureMaskStyle (testing starling 2.0 alpha)

[Fault] exception, information=ArgumentError: Invalid attribute format: bytes4. Use one of the following: 'float1'-'float4'

@PrimaryFeather

This comment has been minimized.

Copy link
Owner Author

PrimaryFeather commented Mar 15, 2016

Sorry for that! With the very latest Starling head revision, it should work again.

@andrewmillion

This comment has been minimized.

Copy link

andrewmillion commented Apr 10, 2016

Hi! I need hide a part of image (ball) by maskTexture:Texture with some threshold. How i can use it?
Not work for me, when i do:

var ball:Image = new Image(ballTexture);
var textureMaskStyle:TextureMaskStyle = new TextureMaskStyle(0.5);
textureMaskStyle.texture = maskTexture;
ball.style = textureMaskStyle;
@PrimaryFeather

This comment has been minimized.

Copy link
Owner Author

PrimaryFeather commented Apr 12, 2016

You need to use the mask a little different than that. I updated your sample:

var ball:Image = new Image(ballTexture);
var textureMaskStyle:TextureMaskStyle = new TextureMaskStyle(0.5);
var mask:Image = new Image(maskTexture);
mask.style = textureMaskStyle;
ball.mask = mask;

In a nutshell, you are using the mask property that's part of all display object. But since masks normally only work for the actual polygon area (i.e. they ignore the texture contents), you use the TextureMaskStyle for the mask.

Does that help?

@andrewmillion

This comment has been minimized.

Copy link

andrewmillion commented Apr 15, 2016

Yes, it helped! Thank you!

@fmrunware

This comment has been minimized.

Copy link

fmrunware commented May 4, 2016

Hi there,

First, excuse my very poor english.

Is there a way to use your starling extension with a Sprite as a mask instead of an Image ?

I'm trying to threshold a sprite containing particles with blur effect and affect this result as a mask on an image.

I'm using Starling 2.0 and Nape.

Thanks for your advices.

Regards

@Vabavia

This comment has been minimized.

Copy link

Vabavia commented Jun 20, 2016

Hi! Can you explain how to use this extension with Starling Builder if possible?

@yuhengh

This comment has been minimized.

Copy link

yuhengh commented Oct 3, 2016

@Vabavia You can now use TextureMaskStyle in Starling Builder 2.2. Make sure to use the EmbeddedComponents.swf from the latest demo workspace, which contains the TextureMaskStyle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.