LogoLogo
  • Home
  • Projects
  • About
  • Contact

Starling ‘God Ray’ Filter

Devon O. · March 10, 2013 · Actionscript, Shaders · 22 comments
16

While cruising the internet today looking for interesting things to try out, I ran across this fun little GPU Gem about creating a post-process volumetric lighting effect. With a little bit of work I quickly ported it over to an AGAL shader (you can see it on Wonderfl here). Then I figured what the hell, why not make it into a Starling filter.

I should say right off the bat that this won’t work in ‘baseline constrained’ mode (i.e. no mobile apps), but if you’re working on a web or desktop project, this filter will give you an effect like this.

The entire filter is below. Enjoy.

 

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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
*    Copyright (c) 2013 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.Context3DBlendFactor;
    import flash.display3D.Context3DProgramType;
    import flash.display3D.Program3D;
    import starling.textures.Texture;
    
    /**
     * Creates a 'God Rays' / fake volumetric light filter effect. Only use with Context3DProfile.BASELINE (not compatible with constrained profile)
     * @author Devon O.
     */
    
    public class GodRaysFilter extends FragmentFilter
    {
        
        private var shaderProgram:Program3D;
        
        private var numSteps:int;
        
        // lightx, lighty
        private var lightPos:Vector.<Number> = Vector.<Number>( [ .5, .5, 1, 1 ]);
        
        // numsamples, density, numsamples * density, 1 / numsamples * density
        private var values1:Vector.<Number> = Vector.<Number>( [ 1, 1, 1, 1 ]);
        
        // weight, decay, exposure
        private var values2:Vector.<Number> = Vector.<Number>( [ 1, 1, 1, 1 ]);
        
        
        private var _lightX:Number         = 0;
        private var _lightY:Number        = 0;
        private var _weight:Number        = .50;
        private var _decay:Number        = .87;
        private var _exposure:Number    = .35;
        private var _density:Number        = 2.0;
        
        public function GodRaysFilter(numSteps:int = 30)
        {
            this.numSteps = numSteps;
        }
        
        public override function dispose():void
        {
            if (this.shaderProgram) this.shaderProgram.dispose();
            super.dispose();
        }
        
        protected override function createPrograms():void
        {
            var frag:String = "";
            
            // Calculate vector from pixel to light source in screen space.
            frag += "sub ft0.xy, v0.xy, fc0.xy \n";
            
            // Divide by number of samples and scale by control factor.  
            frag += "mul ft0.xy, ft0.xy, fc1.ww \n";
            
            // Store initial sample.  
            frag += "tex ft1,  v0, fs0 <2d, clamp, linear, mipnone> \n";
            
            // Set up illumination decay factor.  
            frag += "mov ft2.x, fc0.w \n";
            
            // Store the texcoords
            frag += "mov ft4.xy, v0.xy \n";
            
            for (var i:int = 0; i < this.numSteps; i++)
            {
                // Step sample location along ray.
                frag += "sub ft4.xy, ft4.xy, ft0.xy \n";
                
                // Retrieve sample at new location.  
                frag += "tex ft3,  ft4.xy, fs0 <2d, clamp, linear, mipnone> \n";
                
                // Apply sample attenuation scale/decay factors.  
                frag += "mul ft2.y, ft2.x, fc2.x \n";
                frag += "mul ft3.xyz, ft3.xyz, ft2.yyy \n";
                
                // Accumulate combined color.  
                frag += "add ft1.xyz, ft1.xyz, ft3.xyz \n";
                
                // Update exponential decay factor.  
                frag += "mul ft2.x, ft2.x, fc2.y \n";
            }
            
            // Output final color with a further scale control factor.
            frag += "mul ft1.xyz, ft1.xyz, fc2.zzz \n";
            frag += "mov oc, ft1";
                
            this.shaderProgram = assembleAgal(frag);
        }
        
        protected override function activate(pass:int, context:Context3D, texture:Texture):void
        {        
            // light position
            this.lightPos[0] = this._lightX / texture.width;
            this.lightPos[1] = this._lightY / texture.height;
            
            // numsamples, density, numsamples * density, 1 / numsamples * density
            this.values1[0] = this.numSteps;
            this.values1[1] = this._density;
            this.values1[2] = this.numSteps * values1[1];
            this.values1[3] = 1 / values1[2];
            
            // weight, decay, exposure
            this.values2[0] = this._weight;
            this.values2[1] = this._decay;
            this.values2[2] = this._exposure;
            
            context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, this.lightPos, 1 );    
            context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, this.values1,  1 );
            context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 2, this.values2,  1 );
            
            context.setProgram(this.shaderProgram);
            
        }
        
        public function set lightX(value:Number):void { this._lightX = value; }
        public function get lightX():Number { return this._lightX; }
        
        public function set lightY(value:Number):void { this._lightY = value; }
        public function get lightY():Number { return this._lightY; }
        
        public function set decay(value:Number):void { this._decay = value; }
        public function get decay():Number { return this._decay; }
        
        public function set exposure(value:Number):void { this._exposure = value; }
        public function get exposure():Number { return this._exposure; }
        
        public function set weight(value:Number):void { this._weight = value; }
        public function get weight():Number { return this._weight; }
        
        public function set density(value:Number):void { this._density = value; }
        public function get density():Number { return this._density; }
        
    }
}

  Facebook   Pinterest   Twitter   Google+
  • Animating Bezier Curves
    March 27, 2010 · 11 comments
    4969
    6
    Read more
  • Officially Certifiable
    March 14, 2008 · 0 comments
    1293
    2
    Read more
  • Update to Website Generation Tool
    May 03, 2009 · 7 comments
    2239
    2
    Read more
22 Comments:
  1. Awesome, with this settings
    Density 10
    Exposure .5
    Weight .1
    Decay .8

    It create a strange “3d” effect ^^

    YopSolo · March 17, 2013
  2. Nice!

    Devon O. · March 18, 2013
  3. Hello !

    Great stuff !!

    But when I apply your filter on an image, it doesn’t work, my image is just a little bit darker … even if I correctly set the density, exposure, weight, decay, lightX and lightY :

    var godRaysFilter:GodRaysFilter = new GodRaysFilter();
    godRaysFilter.density = 3.8;
    godRaysFilter.exposure = 0.3;
    godRaysFilter.weight = 0.2;
    godRaysFilter.decay = 1.0;
    godRaysFilter.lightX = myImage.width / 2;
    godRaysFilter.lightY = myImage.height / 2;
    myImage.filter = godRaysFilter;

    Did I miss something ?
    Thanks !

    Matt · April 17, 2013
  4. Hey Matt,

    All that looks correct. Are you sure you’re using the baseline profile rather than baseline constrained? If that’s not the problem, I’m not sure what it would be without some more info.

    d.

    Devon O. · April 23, 2013
  5. Yes, I use the baseline profile.

    I made a new application test, and it works now ! So I guess there was a problem with my previous code, but what ?…

    Thanks, by the way !

    Matt · April 24, 2013
  6. The problem come from the use of PDParticleSystem in the same Starling instance … For an unknown reason, when I use PDParticleSystem, no filter works, even on a DisplayObject which has nothing to do with PDParticleSystem.
    Any idea of how I can solve this issue ?
    Thanks !

    Matt · April 27, 2013
  7. Sorry for my previous post, I was wrong !
    After some tests, the real problem is that when I apply a filter on an image, but my filter is created for example in a timer handler, it doesn’t work :

    private function timerHandler(event:TimerEvent):void
    {
    var godRaysFilter:GodRaysFilter = new GodRaysFilter();
    myImage.filter = godRaysFilter;
    }

    BUT if I put “godRaysFilter” as a class variable, it works :

    private var godRaysFilter:GodRaysFilter = new GodRaysFilter();
    private function timerTest():void
    {
    myImage.filter = godRaysFilter;
    }

    Voila ! If it can help …

    Matt · April 27, 2013
  8. Hey Matt,

    That’s really odd, but I’m glad you got it sorted. And thank you for posting your findings..

    Devon O. · April 27, 2013
  9. So I am having the same issue with this filter as Matt :/. The image just appears quite a bit darker when the filter is running. I am calling this class in a Starling and Away3D Interpolation, which should not really make a difference. I am just going to post the code for this part of the project. Could you tell me if you see anything that might be getting in my way:

    package
    {
    import com.greensock.loading.display.ContentDisplay;
    import com.greensock.*;
    import com.greensock.easing.*;
    import com.greensock.loading.*;
    import flash.events.Event;

    import flash.display.BitmapData;
    import flash.display.GradientType;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;

    import starling.filters.*;
    import starling.filters.GodRaysFilter;
    import starling.filters.FragmentFilter;
    import starling.display.*;
    import starling.display.Image;
    import starling.display.Sprite;
    import starling.textures.*;
    import starling.textures.Texture;
    import starling.utils.AssetManager;
    import starling.core.Starling;

    public class StarlingLevelforgeBaseImageSprite extends Sprite
    {
    //=========================================================================
    //
    //*** Variable Declarations for the Starling Instance.
    //
    //=========================================================================

    private static var instanceLevelforgeBaseImageLoader:StarlingLevelforgeBaseImageSprite;
    private var levelforgeBaseImageLoaderContainer:Sprite;

    private var godRaysDistortion:GodRaysFilter = new GodRaysFilter();

    private var starlingBackDrop:Image;

    //=========================================================================
    //
    //*** Variable Declarations for the Image Loaders.
    //
    //=========================================================================

    private var backDropLoaderAssets:AssetManager = new AssetManager();

    public static function getInstance():StarlingLevelforgeBaseImageSprite
    {
    return instanceLevelforgeBaseImageLoader;
    }

    public function StarlingLevelforgeBaseImageSprite()
    {
    instanceLevelforgeBaseImageLoader = this;

    backDropLoaderAssets.verbose = true;
    backDropLoaderAssets.enqueue(“assets/BackDropImageTEST.jpg”);
    backDropLoaderAssets.loadQueue(function(ratio:Number):void
    {
    trace(“Loading Background Image assets, progress:”, ratio);

    if (ratio == 1.0)
    {
    initiateStarlingImageContainer();
    }
    });
    }

    private function initiateStarlingImageContainer():void
    {
    trace(“Starling BasePlate Loader Initiated!”);
    var backPlateImage:Texture = backDropLoaderAssets.getTexture(“BackDropImageTEST”);

    starlingBackDrop = new Image(backPlateImage);
    starlingBackDrop.pivotX = starlingBackDrop.width / 2;
    starlingBackDrop.pivotY = starlingBackDrop.height / 2;

    godRaysDistortion.lightX = starlingBackDrop.width / 2;
    godRaysDistortion.lightY = starlingBackDrop.height / 2;
    godRaysDistortion.density = 2;
    godRaysDistortion.exposure = 0.4;
    godRaysDistortion.weight = 0.4;
    godRaysDistortion.decay = 0.9;

    TweenMax.to(starlingBackDrop, .001, {autoAlpha: 0});

    // Create a sprite and add an image using the checker texture
    // Assign the pivot point in the centre of the sprite
    levelforgeBaseImageLoaderContainer = new Sprite();

    levelforgeBaseImageLoaderContainer.x = 187.95;
    levelforgeBaseImageLoaderContainer.y = 83;

    levelforgeBaseImageLoaderContainer.addChild(starlingBackDrop);

    levelforgeBaseImageLoaderContainer.filter = godRaysDistortion;

    // Add the container sprite to the Starling stage
    addChild(levelforgeBaseImageLoaderContainer);

    initImageTweenEngine();
    }

    private function initImageTweenEngine():void
    {
    trace(“Backdrop Volumetric initialized!”);

    TweenMax.to(starlingBackDrop, .001, {x: 419, y: 205});
    TweenMax.fromTo(starlingBackDrop, 5, {autoAlpha: 0}, {autoAlpha: 1, ease: Quad.easeIn});
    }
    }
    }

    UbiAssassin · January 19, 2014
  10. I also tried applying the filter directly onto the image “starlingBackDrop,” but it does the exact same thing. Any help would be greatly appreciated :)

    UbiAssassin · January 19, 2014
  11. Hey UbiAssassin,

    The results you describe (the image just getting darker) sounds very much like what happens when you run the filter in BASELINE_CONSTRAINED mode. I guess there’s a few things to try. Have you made just a basic app that does nothing but apply the filter to a display object and run that on the device your testing on? In fact, if you can make a stripped down project that reproduces the problem and post it somewhere or send it to me, I’d be happy to check it out. Another thing to try is reducing the number of steps passed to the constructor and see if you can eventually get it to a number that works properly (of course the effect is lessened by fewer steps, but at least that could help pin point the problem). Also, I don’t know if there are any differences or not, but it may be better getting the filter from the github repo here: https://github.com/devon-o/Starling-Filters , rather than from this post – I try to keep those on the repo up to date.

    -d.

    Devon O. · January 20, 2014
  12. Thank you for the response! I have tried running it on a simple project and it works fine. I think my problem must be related to the fact that I am using away3D and Starling Interpolation :/ Here is how I am setting up the Starling instances:

    private function initStarlingLayers():void
    {
    // Create the Starling scene to add the PhotoGrid background.
    StarlingLevelforgeContentBackPlate = new Starling(StarlingLevelforgeContentBackPlateSprite, stage, levelforgeStage3DProxy.viewPort, levelforgeStage3DProxy.stage3D, Context3DRenderMode.AUTO, Context3DProfile.BASELINE);

    StarlingLevelforgeImageLoader = new Starling(StarlingLevelforgeImageLoaderSprite, stage, levelforgeStage3DProxy.viewPort, levelforgeStage3DProxy.stage3D, Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
    StarlingLevelforgeImageLoader.shareContext = true;

    StarlingLevelforgeGravPartLoader = new Starling(StarlingLevelforgeGravParticlesSprite, stage, levelforgeStage3DProxy.viewPort, levelforgeStage3DProxy.stage3D, Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
    StarlingLevelforgeGravPartLoader.shareContext = true;

    VolumetricLightBackDropLoader = new Starling(StarlingLevelforgeBaseImageSprite, stage, levelforgeStage3DProxy.viewPort, levelforgeStage3DProxy.stage3D, Context3DRenderMode.AUTO, Context3DProfile.BASELINE);
    VolumetricLightBackDropLoader.shareContext = true;

    loaderVar + 1;
    }

    The render function is this:

    private function startRenderEngine(event:Event):void
    {
    // Render the Starling animation layer
    StarlingLevelforgeContentBackPlate.nextFrame();

    // Render the first Particle Emitter [GravParts]
    StarlingLevelforgeGravPartLoader.nextFrame();

    // Render the ImageBackPlate Instance.
    viewAreaBackPlate.render();

    //Render the Starling Image Loader Layer
    StarlingLevelforgeImageLoader.nextFrame();

    VolumetricLightBackDropLoader.nextFrame();

    // Render the PortfolioSymbol Instance.
    viewArea.layeredView = true;
    viewArea.render();
    }

    And finally the class that calls your filter, that is loaded in the starling function in the first code snippet above:

    package
    {
    import com.greensock.loading.display.ContentDisplay;
    import com.greensock.*;
    import com.greensock.easing.*;
    import com.greensock.loading.*;

    import flash.events.Event;
    import flash.display.BitmapData;
    import flash.display.GradientType;
    import flash.geom.Matrix;
    import flash.geom.Rectangle;

    import starling.filters.*;
    import starling.filters.GodRaysFilter;
    import starling.filters.FragmentFilter;
    import starling.display.*;
    import starling.display.Image;
    import starling.display.Sprite;
    import starling.textures.*;
    import starling.textures.Texture;
    import starling.utils.AssetManager;
    import starling.core.Starling;

    public class StarlingLevelforgeBaseImageSprite extends Sprite
    {

    //=========================================================================
    //
    //*** Variable Declarations for the Starling Instance.
    //
    //=========================================================================

    private static var instanceLevelforgeBaseImageLoader:StarlingLevelforgeBaseImageSprite;
    private var levelforgeBaseImageLoaderContainer:Sprite;

    public var godRaysDistortion:GodRaysFilter = new GodRaysFilter();

    private var starlingBackDrop:Image;

    //=========================================================================
    //
    //*** Variable Declarations for the Image Loaders.
    //
    //=========================================================================

    private var backDropLoaderAssets:AssetManager = new AssetManager();

    public static function getInstance():StarlingLevelforgeBaseImageSprite
    {
    return instanceLevelforgeBaseImageLoader;
    }

    public function StarlingLevelforgeBaseImageSprite()
    {
    instanceLevelforgeBaseImageLoader = this;

    backDropLoaderAssets.verbose = true;
    backDropLoaderAssets.enqueue(“assets/BackDropImageTEST.jpg”);
    backDropLoaderAssets.loadQueue(function(ratio:Number):void
    {
    trace(“Loading Background Image assets, progress:”, ratio);

    if (ratio == 1.0)
    {
    initiateStarlingImageContainer();
    }
    });
    }

    public function initiateStarlingImageContainer():void
    {
    trace(“Starling BasePlate Loader Initiated!”);
    var backPlateImage:Texture = backDropLoaderAssets.getTexture(“BackDropImageTEST”);

    starlingBackDrop = new Image(backPlateImage);
    starlingBackDrop.pivotX = starlingBackDrop.width / 2;
    starlingBackDrop.pivotY = starlingBackDrop.height / 2;

    godRaysDistortion.x = starlingBackDrop.width / 2;
    godRaysDistortion.y = starlingBackDrop.height / 2;
    godRaysDistortion.density = 2;
    godRaysDistortion.exposure = 0.4;
    godRaysDistortion.weight = 0.4;
    godRaysDistortion.decay = 0.9;

    TweenMax.to(starlingBackDrop, .001, {autoAlpha: 0});

    // Create a sprite and add an image using the checker texture
    // Assign the pivot point in the centre of the sprite
    levelforgeBaseImageLoaderContainer = new Sprite();

    levelforgeBaseImageLoaderContainer.x = 187.95;
    levelforgeBaseImageLoaderContainer.y = 83;

    levelforgeBaseImageLoaderContainer.addChild(starlingBackDrop);

    // Add the container sprite to the Starling stage
    addChild(levelforgeBaseImageLoaderContainer);

    initImageTweenEngine();
    }

    private function initImageTweenEngine():void
    {
    trace(“Backdrop Volumetric initialized!”);

    TweenMax.to(starlingBackDrop, .001, {x: 419, y: 205});
    TweenMax.fromTo(starlingBackDrop, 5, {autoAlpha: 0}, {autoAlpha: 1, ease: Quad.easeIn});
    starlingBackDrop.filter = godRaysDistortion;
    }
    }
    }

    UbiAssassin · January 20, 2014
  13. Ok sorry for the wall of text. I tried a bunch of things to no avail. Your filter is awesome, so I would love to get it to work.

    1. I tried all of what you said above and it never works in my away3D/Starling interpolation.

    2. I tried converting the entire stage to Bitmap Data. I had an odd epiphany that the Starling Image might not be right for the filter….Not an issue LOL.

    3. I now have some code that automatically grabs the highest context3DProfile available. For me that defaults to Baseline, so this is fine. It also tell me when I am running in software mode or hardware. When I test in FlashCC it is of course software mode, but I can run the swf on its own to get hardware mode.

    4. I have tried applying the filter options in the main Control Class instead of the Starling Sprite Class that contains the code and loads the image.

    5. I remember briefly having this problem with the stand alone using one of the other versions of this from your link. I commented-out the LightPos[0] and LightPos[1] code or left it so that the Lights followed the mouse positions on screen and it worked. But if I added my own numbers like 600 for width and 305 for Y it would just turn dark. So there is also some funkiness that I do not understand with the lightPos options.

    6. I also tried dropping the numSteps down from 30 to 20 to 10 to 5 and still no go.

    7. Link to the image of it failing: http://levelforge.com/Dump%20Folder/Weirdness.jpg
    You can see in the top left corner that I am rendering in hardware mode using the context3DProfile Baseline. I am just using an easy to see upside-down texture to show you the image that is supposed to be producing Godrays.

    At this point I am out of ideas, because I am just learning Starling and Away3D API’s.

    Thanks for any responses :)

    UbiAssassin · January 21, 2014
  14. Hey UbiAssassin,

    Didn’t mean to leave you hanging but it won’t be until the weekend that I’ll have time to take a closer look. Have to admit though, I’ve only played with Away3D/Starling integration once on a very small personal project and I’ve never seen a project which instantiated so many instances of Starling, so I’m not sure how helpful I may be. Would love to see it working though.

    d.

    Devon O. · January 22, 2014
  15. Hey Devon,

    No worries at all. I completely understand.

    Yeah this is an intense setup. This is the base content plate for my website, over which all other button event content plates will load. I am pushing all of my Away3D / Starling content in this one setup because you can only have one Stage3D instance showing. Any others loaded will be hidden since we do not have stage3D instance transparency as of now :/

    The sad thing is that most filters are incedibly simple, so it is hard for me to drill down to the specific problem. I tested using BlurFilter.createDropShadow and that works in my setup without issue, but then again it is not doing anything particularly complicated. Your filter is definitely trying to initiate, as I am seeing a definite darkening of the image that I target.

    I juggled my code a bit last night to push all of the GodRay filter options in the Main interpolation Class and not in the Starling class loading the image. That has not changed anything, but I figure it is better to handle the filter in the class that actually calls the render stack process. It also applies the GodRay filter after this class has made sure that the content is in the Baseline profile. So it is safer I think.

    If you would like access to any of my files, just poke me. Thanks for your response! I love your particle generator btw. I have been using it for the last couple of days. Great stuff.

    UbiAssassin · January 22, 2014
  16. Ok something really bizarre happened. I have been working on one of the away3D layers and I noticed that in FlashCC test mode (software mode) if I maximize the window, the GodRays filter starts working. It will stay working when I normalize the window size again.

    I cannot get it to happen in Hardware mode when just running the .swf. It is very weird, but maybe this will spark something for you?

    UbiAssassin · January 23, 2014
  17. Hey UbiAssassin,

    The fact that the image is darkening makes me suspicious. Like I was saying, this is the same thing it does when you run the filter in baseline_constrained mode and the reason it does that is because it tries to perform too many operations. Makes me wonder if by creating so many Starling instances and bringing in Away3D, you’ve tapped the resources to the point where it can’t handle the same number of opcodes. If you run in debug mode are any errors thrown (I’m sure you would have mentioned that, but I have to ask)? Also I would try setting the steps to 2 (so instantiate the filter with new GodRaysFilter(2) or even just use 1). I pick 2 because it’s the max number of steps baseline_constrained can handle. Now if that actually works, it will look like garbage, but it will at least pin point the problem. And if that much does work, we can check out a work around like using multiple passes.

    Unfortunately, if it still does nothing but darken after lowering the number of steps to just 1 or 2 then I’m at a complete loss.

    d.

    Devon O. · January 25, 2014
  18. This is so weird. I can get it to work only in debug mode (FlashCC test window which is locked to software mode) if I hit the maximize button on the test window. Once maximized the filter starts working. Does this make sense to you? If I resize the window in hardware rendering the godRay effect never initiates. It is like some kind of re-initialization happens in software test mode only on window maximize that kicks the godRays filter and enables it. Maybe I can code something to touch it and wake it up like the maximize event is doing?

    Here is the output when I maximize and the filter begins to work:

    [Starling] Initialization complete.
    [Starling] Display Driver: Software Hw_disabled=explicit (Embedded)
    [Starling] Initialization complete.
    [Starling] Display Driver: Software Hw_disabled=explicit (Embedded)
    [Starling] Initialization complete.
    [Starling] Display Driver: Software Hw_disabled=explicit (Embedded)
    [Starling] Initialization complete.
    [Starling] Display Driver: Software Hw_disabled=explicit (Embedded)
    [Starling] Initialization complete.
    [Starling] Display Driver: Software Hw_disabled=explicit (Embedded)

    UbiAssassin · January 25, 2014
  19. I also tried setting the steps to 2 a

    UbiAssassin · January 25, 2014
  20. Whoops posted before done :( So I tried steps 2 and 1 and neither setting changed anything. The only change that I can cause is the one mentioned in my last post. Maximizing the test window suddenly makes the filter work O.o

    Thanks for all of your input so far. In the end this is more of a “I want to know issue” more than enything. There probably is just some limitation caused by the fact that I am using interpolation.

    There are also no errors posted in the output.

    UbiAssassin · January 25, 2014
  21. Error: Error #3715: Too many instructions used in native shader. Detected 199 but can only support 96 for fragment program.
    Why?
    var _bgTexture:Texture = Texture.fromBitmap(new Bg());
    _bgImage = new Image(_bgTexture);
    addChild(_bgImage);
    var _f:GodRaysFilter = new GodRaysFilter(32);
    _f.density = 10;
    _f.exposure = .5;
    _f.weight = .1;
    _f.decay = .8
    _bgImage.filter = _f;

    alexvoz · September 10, 2014
  22. Hey alexvoz,

    I suspect you need to bump up the Context3DProfile to use that Filter (e.g. try Baseline rather than Baseline Constrained). Hopefully that will solve the issue.

    Devon O. · September 13, 2014

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