Starling ‘God Ray’ Filter

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.

 

/**
 *	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; }
 
    }
}

22 Comments »

  1. YopSolo says:

    Awesome, with this settings
    Density 10
    Exposure .5
    Weight .1
    Decay .8

    It create a strange “3d” effect ^^

  2. Matt says:

    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 !

  3. Devon O. says:

    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.

  4. Matt says:

    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 !

  5. Matt says:

    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 !

  6. Matt says:

    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 …

  7. Devon O. says:

    Hey Matt,

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

  8. UbiAssassin says:

    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});
    }
    }
    }

  9. UbiAssassin says:

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

  10. Devon O. says:

    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.

  11. UbiAssassin says:

    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;
    }
    }
    }

  12. UbiAssassin says:

    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 :)

  13. Devon O. says:

    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.

  14. UbiAssassin says:

    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.

  15. UbiAssassin says:

    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?

  16. Devon O. says:

    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.

  17. UbiAssassin says:

    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)

  18. UbiAssassin says:

    I also tried setting the steps to 2 a

  19. UbiAssassin says:

    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.

  20. alexvoz says:

    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;

  21. Devon O. says:

    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.

RSS feed for comments on this post. / TrackBack URI

Leave a Reply

Devon O. Wolfgang

Technical Reviewer of “The Essential Guide to Flash CS4 AIR Development”

Contributing Author of “Flash AS3 for Interactive Agencies”

Senior Software Engineer at Meez

Starling Particle Editor

vignette

Some Photographic Shaders


A couple weeks ago I was contacted and asked to develop some filters for Starling that could be used in a mobile camera app[...]

boids

Animated Particles, Books, and Code – It’s a New Year


It’s a new year[...]

bug

Logical Or Assignment Bug in ASC2


So, here’s something to keep an eye on if switching to AIR 3.8[...]

Starling Filter Collection

Starling Filter Collection


Building up a collection of filters for the Starling framework[...]

Starling Warp

Warp Filter for Starling


Another filter for the Starling framework[...]

promise

Promises Promises


What it boils down to is handling asynchronous tasks [...] in a clean, intelligent fashion [...]

GodRays

Starling ‘God Ray’ Filter


While cruising the internet today looking for interesting things to try out I ran across this fun little GPU Gem[...]

Alpha in Starling Filters and Basic Branching in AGAL


In plain English to create a circular mask we would want to do something like this[...]

Starling, Nape Physics, and PhysicsEditor


A look at using the PhysicsEditor tool for Nape and Starling [...]

Playing With a Couple Game Ideas


Just a couple game fragments, really[...]

One More Filter For Starling


Another filter for the Starling framework[...]

Filters in Starling


Using and writing filters in the Starling framework[...]

Towards a Better Scratch


Perhaps it was too much Meat Beat Manifesto in the late 80’s [...]

Learning AGAL with AGALMacroAssembler and OpenGL Examples

So the other day I sat down and thought to myself: self, it’s high time you learn you some of this new fancy pants AGAL[...]

UV Scrolling in Starling


Obviously this could come in pretty darned handy for space games, side scrollers, etc, etc[...]

Drawing on Stuff in Away3D 4.0

So, Easter Day, I thought I’d sit down and make a little ‘Paint on an Egg and Send it to Your Friend’ app.