LogoLogo
  • Home
  • Projects
  • About
  • Contact

One More Filter For Starling

Devon O. · September 10, 2012 · Actionscript, Flash, Games, Shaders · 5 comments
13

As an addendum to the post I made yesterday, here is one other filter which can be used in the Starling framework that could probably come in quite handy for a few. In essence, it’s sort of a spotlight effect that illuminates a specified oval area of a Starling DisplayObject. Though I mainly see it being used for games where you only want to light up an area around your player (to move the light around, you just adjust the centerX and centerY properties), I suppose it could also produce a nice vignette effect as well. In any case you can see an example here. After the swf loads (around 200k or so), move your mouse around to see the filter in action. And if you’re looking for a flickering torch/dying flashlight or old movie effect, you can set the useFlicker property to true. In the example, clicking the image will toggle the flicker.

As usual, feel free to play around and use it as you’d like.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
*    Copyright (c) 2012 Devon O. Wolfgang
*
*    Permission is hereby granted, free of charge, to any person obtaining a copy
*    of this software and associated documentation files (the "Software"), to deal
*    in the Software without restriction, including without limitation the rights
*    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*    copies of the Software, and to permit persons to whom the Software is
*    furnished to do so, subject to the following conditions:
*
*    The above copyright notice and this permission notice shall be included in
*    all copies or substantial portions of the Software.
*
*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
*    THE SOFTWARE.
*/
package starling.filters
{
    import flash.display3D.Context3D;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Program3D;
    import starling.textures.Texture;
    public class SpotlightFilter extends FragmentFilter
    {
        private var mCenter:Vector.<Number> = new <Number>[1, 1, 1, 1];
        private var mVars:Vector.<Number> = new <Number>[.50, .50, .50, .50];
        private var mPixelSize:int;
        private var mShaderProgram:Program3D;
        
        private var mCenterX:Number;
        private var mCenterY:Number;
        private var mAmount:Number;
        private var mSize:Number;
        private var mRadius:Number;
        private var mUseFlicker:Boolean;
        
        /**
         * Produces a spotlight or vignette like effect on Starling display objects.
         * @param    cx            center x of spotlight. should be relative to display object being filtered
         * @param    cy            center y of spotlight. should be relative to display object being filtered
         * @param    amount        how much should the effect be applied.
         * @param    radius        the amount of inner bright light.
         * @param    size        the size of the effect
         */
        public function SpotlightFilter(cx:Number = 0.0, cy:Number = 0.0, amount:Number = 1.0, radius:Number = .25, size:Number = .25, useFlicker:Boolean = false )
        {
            mCenterX    = cx;
            mCenterY    = cy;
            mAmount        = amount;
            mRadius        = radius;
            mSize        = size;
            mUseFlicker    = useFlicker;
        }
        public override function dispose():void
        {
            if (mShaderProgram) mShaderProgram.dispose();
            super.dispose();
        }
        protected override function createPrograms():void
        {
            var fragmentProgramCode:String =
                "sub ft0.xy, v0.xy, fc0.xy \n" +
                "mov ft2.x, fc1.w \n" +
                "mul ft2.x, ft2.x, fc1.z \n" +
                "sub ft3.xy, ft0.xy, ft2.x \n" +
                "dp3 ft4.x, ft3.xy, ft3.xy \n" +
                "sqt ft4.x, ft4.x \n" +
                "dp3 ft4.y, ft2.x, ft2.x \n" +
                "sqt ft4.y, ft4.y \n" +
                "div ft5.x, ft4.x, ft4.y \n" +
                "pow ft5.y, ft5.x, fc1.y \n" +
                "mul ft5.z, fc1.x, ft5.y \n" +
                "sat ft5.z, ft5.z \n" +
                "min ft5.z, ft5.z, fc0.z \n" +
                "sub ft6, fc0.z, ft5.z \n" +
                "tex ft1, v0, fs0<2d, clamp, linear, nomip> \n" +
                "mul ft6, ft6, ft1 \n" +
                "mov ft6.w, ft1.w \n" +
                "mov oc, ft6"
            mShaderProgram = assembleAgal(fragmentProgramCode);
        }
        protected override function activate(pass:int, context:Context3D, texture:Texture):void
        {
            // already set by super class:
            //
            // vertex constants 0-3: mvpMatrix (3D)
            // vertex attribute 0:   vertex position (FLOAT_2)
            // vertex attribute 1:   texture coordinates (FLOAT_2)
            // texture 0:            input texture
            var halfSize:Number = mSize * .50;
            var cx:Number = mCenterX / texture.width - halfSize;
            var cy:Number = mCenterY / texture.height - halfSize;
            mCenter[0] = cx;
            mCenter[1] = cy;
            
            var radius:Number = mUseFlicker ? mRadius * Math.random() : mRadius;
            
            mVars[0] = mAmount;
            mVars[1] = radius;
            mVars[3] = mSize;
            context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, mCenter, 1);
            context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, mVars,   1);
            context.setProgram(mShaderProgram);
        }
        public function get centerX():Number { return mCenterX; }
        public function set centerX(value:Number):void { mCenterX = value; }
        
        public function get centerY():Number { return mCenterY; }
        public function set centerY(value:Number):void { mCenterY = value; }
        
        public function get amount():Number { return mAmount; }
        public function set amount(value:Number):void { mAmount = value; }
        
        public function get size():Number { return mSize; }
        public function set size(value:Number):void { mSize = value; }
        
        public function get radius():Number { return mRadius; }
        public function set radius(value:Number):void { mRadius = value; }
        
        public function get useFlicker():Boolean { return mUseFlicker; }
        public function set useFlicker(value:Boolean):void { mUseFlicker = value; }
    }
}
  Facebook   Pinterest   Twitter   Google+
starling
  • ARCore Mini Golf Game
    January 28, 2018 · 0 comments
    Having received a Samsung Galaxy S8 for my birthday (a gift from my wonderful
    4172
    50
    Read more
  • Fake Specular Highlights with Shader Graph
    December 27, 2018 · 0 comments
    So, the other day at work we were exploring various methods of adding nice
    6377
    17
    Read more
  • Save/Retrieve ByteArrays to/from Database via AMFPHP
    May 07, 2009 · 10 comments
    4754
    3
    Read more
5 Comments:
  1. Great filter!
    I was wondering, would you be able to create a mask effect using a filter where the center of the circle is visible and the pixels outside were set to alpha 0.
    Thanks

    Chris · September 21, 2012
  2. I can’t get it to work on an Ipad, am I doing somthing wrong?

    Math · October 11, 2012
  3. Hi Math, I rarely do much iOS development, so I’m not sure what the problem may be. My first thought is that perhaps the filter did not work with the ‘baselineConstrained’ profile, but I just tested it and it does. If you simply run the .swf file locally – and not on the device – does it work for you?

    Devon O. · October 11, 2012
  4. When I run it locally it work perfecly fine. But after IK build my IPA I only see the gradient Ellipse and the rest is at 100% alpha.

    Math · October 12, 2012

Leave a Comment! Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Devon O. Wolfgang

AIR | Unity3D | AR/VR

Unity Certified Developer

Technical Reviewer of “The Essential Guide to Flash CS4 AIR Development” and “Starling Game Development Essentials”

Reviewer of “The Starling Handbook”

Unity Engineer at Touch Press.

Categories
  • Actionscript (95)
  • AIR (16)
  • Flash (99)
  • Games (7)
  • Liberty (13)
  • Life (53)
  • Shaders (20)
  • Unity3D (21)
Recent Comments
  • MainDepth on Unity Ripple or Shock Wave Effect
  • Devon O. on Unity Ripple or Shock Wave Effect
  • Feral_Pug on Unity Ripple or Shock Wave Effect
  • bavvireal on Unity3D Endless Runner Part I – Curved Worlds
  • Danielius Vargonas on Custom Post Processing with the LWRP
Archives
  • December 2020 (1)
  • December 2019 (1)
  • September 2019 (1)
  • February 2019 (2)
  • December 2018 (1)
  • July 2018 (1)
  • June 2018 (1)
  • May 2018 (2)
  • January 2018 (1)
  • December 2017 (2)
  • October 2017 (1)
  • September 2017 (2)
  • January 2017 (1)
  • July 2016 (1)
  • December 2015 (2)
  • March 2015 (1)
  • September 2014 (1)
  • January 2014 (1)
  • August 2013 (1)
  • July 2013 (1)
  • May 2013 (1)
  • March 2013 (2)
  • December 2012 (1)
  • November 2012 (1)
  • September 2012 (3)
  • June 2012 (2)
  • May 2012 (1)
  • April 2012 (1)
  • December 2011 (2)
  • October 2011 (3)
  • September 2011 (1)
  • August 2011 (1)
  • July 2011 (1)
  • May 2011 (2)
  • April 2011 (2)
  • March 2011 (1)
  • February 2011 (1)
  • January 2011 (2)
  • December 2010 (3)
  • October 2010 (5)
  • September 2010 (1)
  • July 2010 (2)
  • May 2010 (5)
  • April 2010 (2)
  • March 2010 (7)
  • February 2010 (5)
  • January 2010 (5)
  • December 2009 (3)
  • November 2009 (1)
  • October 2009 (5)
  • September 2009 (5)
  • August 2009 (1)
  • July 2009 (1)
  • June 2009 (2)
  • May 2009 (6)
  • April 2009 (4)
  • March 2009 (2)
  • February 2009 (4)
  • January 2009 (1)
  • December 2008 (5)
  • November 2008 (2)
  • September 2008 (1)
  • August 2008 (6)
  • July 2008 (6)
  • June 2008 (9)
  • May 2008 (4)
  • April 2008 (3)
  • March 2008 (4)
  • February 2008 (9)
  • January 2008 (7)
  • December 2007 (6)
Copyright © 2021 Devon O. Wolfgang