`

Starling GodRay 效果实现

 
阅读更多

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

 

分享到:
评论

相关推荐

    基于starling的游戏

    1. **硬件加速**:Starling利用Stage3D API实现硬件加速,显著提升了2D图形的渲染速度,使游戏画面更加流畅。 2. **轻量级**:Starling的API设计简洁,易于理解和使用,开发者可以快速上手并专注于游戏逻辑。 3. *...

    Starling1.8源码(包含粒子系统扩展包)

    通过研究这个源码,开发者不仅可以了解Starling框架的内部工作原理,还能学习到如何高效地实现粒子效果。例如,如何使用星型或圆形粒子,如何控制粒子的发射速度和方向,以及如何实现粒子的生命周期管理(出生、运动...

    Starling Graphics extension 绘图API 扩展

    Starling是一个高效、跨平台的ActionScript 3库,专门设计用于游戏开发,它利用硬件加速来提供流畅的动画效果。Graphics扩展则进一步提升了Starling的功能,为开发者提供了更多高级的绘图选项。 首先,让我们深入...

    adobe starling as3 flash 3d Starling演讲PPT以及附件

    内容包括AS3 项目源文件两个 包含PDF中提到的例子 以及运行效果SWF10个 在Stage3D出现之前,Flash3D引擎( Papervision3D, Away3D,…)都是软解 CPU是通用处理器,没有为渲染三角形而优化过 Stage3D是一个新的Flash...

    starling 任意形状遮罩

    Starling 任意形状遮罩是一种在AS3(ActionScript 3)环境中,使用Starling框架实现的高级图形处理技术。Starling是一个针对Adobe Flash Player和Adobe AIR的2D游戏开发框架,它允许开发者利用硬件加速来提升游戏...

    框架starling

    1. **硬件加速**:Starling通过使用Stage3D API实现了硬件加速,这使得开发者能够在2D图形处理中充分利用现代GPU的能力,提高渲染速度和帧率,尤其是在处理大量动态图形时。 2. **简单API**:尽管Stage3D底层API...

    Starling开发的游戏

    5. **物理引擎集成**:可与Box2D等物理引擎无缝集成,实现真实的物理效果。 6. **动画系统**:提供强大的时间轴和动作管理,简化动画制作过程。 7. **触摸和手势支持**:对于移动设备,Starling提供了触摸事件和手势...

    air starling 图片旋转

    本篇文章将深入探讨如何在Starling中实现图片旋转,并讨论如何消除旋转过程中可能出现的锯齿现象,特别是在桌面应用中。 首先,我们需要理解Starling中的基本概念。Starling的核心是`DisplayObject`类,它是所有可...

    Starling1.5.1

    6. **物理引擎集成**:Starling与Box2D等物理引擎有良好的兼容性,可轻松添加物理效果到游戏中。 7. **事件系统**:遵循ActionScript 3的事件模型,让事件处理变得直观和简单。 8. **声音管理**:提供了音频播放...

    Starling实现的图标拖拽

    在本文中,我们将深入探讨如何使用Starling框架在Adobe AIR应用程序中实现图标拖放功能。Starling是一个由Daniel Slopov开发的高性能2D游戏开发库,它利用硬件加速的Stage3D API来提供流畅的动画体验。在Air环境中,...

    Starling开发的微信飞机大战源码

    在Starling框架下,游戏的逻辑处理、碰撞检测、动画效果等都可以得到优化。Starling支持矢量图形,这意味着游戏中的飞机、子弹、敌人等元素可以实现高质量的缩放,同时保持流畅的帧率。 “Starling”是基于AS3的跨...

    Starling9宫格类库

    通过这样的9宫格类库,开发者可以轻松地在Starling项目中实现高质量的缩放效果,无论是在移动设备还是桌面平台上,都能提供良好的用户体验。在实际应用中,9宫格缩放常用于按钮、背景、窗口等元素,使得UI元素在不同...

    starling版消灭星星

    在开发过程中,开发者可能利用了Starling的特性来创建动画效果,如星星的出现、碰撞检测以及消除时的爆炸特效,这些都需要对图形渲染和事件处理有深入理解。 首先,我们要理解Starling框架的基本结构。它使用了...

    Starling Feathers:Starling专属UI框架

    Starling本身是一个跨平台的游戏开发框架,基于ActionScript 3.0,利用硬件加速来实现高效的2D图形渲染,尤其适合在移动设备上使用。Feathers的出现弥补了Starling在UI组件上的不足,提供了丰富的控件和布局选项,...

    PrimaryFeather-Starling-Framework-v1.3-175-g09eebe4.zip

    - 源代码:Starling框架的实现,供学习和自定义。 - 资源文件:如纹理、音频或其他媒体,用于演示或测试。 - 文档:关于如何使用框架的指南或API文档。 总的来说,Starling Framework为2D游戏开发者提供了强大的...

    starling中文API

    Shader允许你编写GLSL代码来实现复杂的图形效果。 7. **Event Handling**:Starling提供了一套事件处理机制,类似于Flash的事件系统,包括触摸、鼠标和键盘事件。 8. **Animation**:Starling通过Timeline和Tween...

    <CitrusEngine系列教程二:结合starling和Box2D开发游戏>示例源码

    在本教程中,Starling将用于绘制游戏场景和角色,实现流畅的图形效果。 3. **Box2D**:Box2D是一个流行的开源2D物理引擎,用于模拟现实世界的物理行为。在ActionScript3中,Box2D被广泛应用于游戏开发,因为它可以...

    Starling,Features和StarlingMVC第三方库

    Starling 是一个强大的2D游戏开发框架,它基于Adobe Flash Player和Adobe AIR,为开发者提供了在这些平台上实现高性能图形渲染的能力。Starling 使用Stage3D技术,能够将2D渲染优化到接近原生代码的速度,这使得它...

    starling中文版粒子

    starling中文版粒子下载

    starling.swc

    Starling是一个基于Adobe Flash...通过这个SWC文件,开发者可以轻松构建2D游戏和应用,利用硬件加速实现流畅的性能。不过,要注意的是,不同版本的Starling可能有不同的特性和兼容性,选择适合项目需求的版本至关重要。

Global site tag (gtag.js) - Google Analytics