-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
540 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module type="Flex" version="4"> | ||
<component name="FlexBuildConfigurationManager" active="Starling-Extension-TextureProcessor"> | ||
<configurations> | ||
<configuration name="Starling-Extension-TextureProcessor" target-platform="Desktop" pure-as="true" output-type="Library" output-file="Starling-Extension-TextureProcessor.swc" output-folder="$MODULE_DIR$/out"> | ||
<dependencies target-player="11.8"> | ||
<entries> | ||
<entry module-name="EasyAGAL" build-configuration-name="EasyAGAL"> | ||
<dependency linkage="Merged" /> | ||
</entry> | ||
<entry module-name="Starling" build-configuration-name="Starling"> | ||
<dependency linkage="Merged" /> | ||
</entry> | ||
</entries> | ||
<sdk name="AIR SDK 3.8 Beta" /> | ||
</dependencies> | ||
<compiler-options /> | ||
<packaging-air-desktop /> | ||
<packaging-android /> | ||
<packaging-ios /> | ||
</configuration> | ||
</configurations> | ||
<compiler-options /> | ||
</component> | ||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | ||
<exclude-output /> | ||
<content url="file://$MODULE_DIR$"> | ||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> | ||
<excludeFolder url="file://$MODULE_DIR$/out" /> | ||
</content> | ||
<orderEntry type="jdk" jdkName="AIR SDK 3.8 Beta" jdkType="Flex SDK Type (new)" /> | ||
<orderEntry type="sourceFolder" forTests="false" /> | ||
<orderEntry type="module" module-name="EasyAGAL" exported="" /> | ||
<orderEntry type="module" module-name="Starling" exported="" /> | ||
</component> | ||
</module> | ||
|
263 changes: 263 additions & 0 deletions
263
extension/src/starling/shaders/FastGaussianBlurShader.as
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,263 @@ | ||
/** | ||
* User: booster | ||
* Date: 18/12/13 | ||
* Time: 11:29 | ||
*/ | ||
package starling.shaders { | ||
import com.barliesque.agal.EasierAGAL; | ||
import com.barliesque.agal.IComponent; | ||
import com.barliesque.agal.IRegister; | ||
import com.barliesque.agal.TextureFlag; | ||
import com.barliesque.shaders.macro.Utils; | ||
|
||
import flash.display3D.Context3D; | ||
import flash.display3D.Context3DProgramType; | ||
|
||
public class FastGaussianBlurShader extends EasierAGAL implements ITextureShader { | ||
public static const HORIZONTAL:String = "horizontal"; | ||
public static const VERTICAL:String = "vertical"; | ||
|
||
private static const DEFAULT_FIRST_PASS_STRENGTH:Number = 1.25; | ||
private static const DEFAULT_STRENGTH_INCREASE_PER_PASS_RATIO:Number = 3.0; | ||
|
||
private static var _verticalOffsets:Vector.<Number> = new <Number>[0.0, 1.3846153846, 0.0, 3.2307692308]; | ||
private static var _horizontalOffsets:Vector.<Number> = new <Number>[1.3846153846, 0.0, 3.2307692308, 0.0]; | ||
|
||
private var _type:String = HORIZONTAL; | ||
private var _pass:int = 0; | ||
private var _strength:Number = Number.NaN; | ||
private var _firstPassStrength:Number = DEFAULT_FIRST_PASS_STRENGTH; | ||
private var _strengthIncreaseRatio:Number = DEFAULT_STRENGTH_INCREASE_PER_PASS_RATIO; | ||
private var _pixelWidth:Number = Number.NaN; | ||
private var _pixelHeight:Number = Number.NaN; | ||
private var _paramsDirty:Boolean = true; | ||
private var _strengthsDirty:Boolean = true; | ||
|
||
private var _strengths:Vector.<Number> = new <Number>[]; | ||
private var _offsets:Vector.<Number> = new <Number>[0, 0, 0, 0]; | ||
private var _uv:Vector.<Number> = new <Number>[0, 1, 0, 1]; | ||
private var _weights:Vector.<Number> = new <Number>[0.2270270270, 0.3162162162, 0.0702702703, 0]; | ||
|
||
public function get type():String { return _type; } | ||
public function set type(value:String):void { | ||
if(value == _type) | ||
return; | ||
|
||
_type = value; | ||
_paramsDirty = true; | ||
} | ||
|
||
public function get strength():Number { return _strength; } | ||
public function set strength(value:Number):void { | ||
if(value == _strength) | ||
return; | ||
|
||
_strength = value; | ||
_paramsDirty = true; | ||
_strengthsDirty = true; | ||
} | ||
|
||
public function get firstPassStrength():Number { return _firstPassStrength; } | ||
public function set firstPassStrength(value:Number):void { | ||
if(_firstPassStrength == value) | ||
return; | ||
|
||
_firstPassStrength = value; | ||
_paramsDirty = true; | ||
_strengthsDirty = true; | ||
} | ||
|
||
public function get strengthIncreaseRatio():Number { return _strengthIncreaseRatio; } | ||
public function set strengthIncreaseRatio(value:Number):void { | ||
if(_strengthIncreaseRatio == value) | ||
return; | ||
|
||
_strengthIncreaseRatio = value; | ||
_paramsDirty = true; | ||
_strengthsDirty = true; | ||
} | ||
|
||
public function get pass():int { return _pass; } | ||
public function set pass(value:int):void { | ||
if(value == _pass) | ||
return; | ||
|
||
_pass = value; | ||
_paramsDirty = true; | ||
} | ||
|
||
public function get pixelWidth():Number { return _pixelWidth; } | ||
public function set pixelWidth(value:Number):void { | ||
if(value == _pixelWidth) | ||
return; | ||
|
||
_pixelWidth = value; | ||
_paramsDirty = true; | ||
} | ||
|
||
public function get pixelHeight():Number { return _pixelHeight; } | ||
public function set pixelHeight(value:Number):void { | ||
if(value == _pixelHeight) | ||
return; | ||
|
||
_pixelHeight = value; | ||
_paramsDirty = true; | ||
} | ||
|
||
public function get passesNeeded():int { | ||
if(_strengthsDirty) | ||
updateStrengths(); | ||
|
||
return _strengths.length; | ||
} | ||
|
||
public function get minU():Number { return _uv[0]; } | ||
public function set minU(value:Number):void { _uv[0] = value; } | ||
|
||
public function get maxU():Number { return _uv[1]; } | ||
public function set maxU(value:Number):void { _uv[1] = value; } | ||
|
||
public function get minV():Number { return _uv[2]; } | ||
public function set minV(value:Number):void { _uv[2] = value; } | ||
|
||
public function get maxV():Number { return _uv[3]; } | ||
public function set maxV(value:Number):void { _uv[3] = value; } | ||
|
||
public function activate(context:Context3D):void { | ||
if(_strengthsDirty) | ||
updateStrengths(); | ||
|
||
if(_paramsDirty) | ||
updateParameters(); | ||
|
||
context.setProgramConstantsFromVector(Context3DProgramType.VERTEX, 4, _offsets); | ||
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, _weights); | ||
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, _uv); | ||
} | ||
|
||
public function deactivate(context:Context3D):void { | ||
} | ||
|
||
override protected function _vertexShader():void { | ||
comment("Apply a 4x4 matrix to transform vertices to clip-space"); | ||
multiply4x4(OUTPUT, ATTRIBUTE[0], CONST[0]); | ||
|
||
comment("Pass uv coordinates to fragment shader"); | ||
move(VARYING[0], ATTRIBUTE[1]); | ||
|
||
comment("pass 4 additional UVs for sampling neighbours, in order: -2, -1, +1, +2 pixels away"); | ||
subtract(VARYING[1], ATTRIBUTE[1], CONST[4].zw); | ||
subtract(VARYING[2], ATTRIBUTE[1], CONST[4].xy); | ||
add(VARYING[3], ATTRIBUTE[1], CONST[4].xy); | ||
add(VARYING[4], ATTRIBUTE[1], CONST[4].zw); | ||
} | ||
|
||
override protected function _fragmentShader():void { | ||
var uvCenter:IRegister = VARYING[0]; | ||
var uvMinusTwo:IRegister = VARYING[1]; | ||
var uvMinusOne:IRegister = VARYING[2]; | ||
var uvPlusOne:IRegister = VARYING[3]; | ||
var uvPlusTwo:IRegister = VARYING[4]; | ||
var uv:IRegister = TEMP[7]; | ||
var weightCenter:IComponent = CONST[0].x; | ||
var weightOne:IComponent = CONST[0].y; | ||
var weightTwo:IComponent = CONST[0].z; | ||
var minU:IComponent = CONST[1].x; | ||
var maxU:IComponent = CONST[1].y; | ||
var minV:IComponent = CONST[1].z; | ||
var maxV:IComponent = CONST[1].w; | ||
var colorCenter:IRegister = TEMP[0]; | ||
var colorMinusTwo:IRegister = TEMP[1]; | ||
var colorMinusOne:IRegister = TEMP[2]; | ||
var colorPlusOne:IRegister = TEMP[3]; | ||
var colorPlusTwo:IRegister = TEMP[4]; | ||
var outputColor:IRegister = TEMP[5]; | ||
var textureFlags:Array = [TextureFlag.TYPE_2D, TextureFlag.MODE_CLAMP, TextureFlag.FILTER_LINEAR, TextureFlag.MIP_NO]; | ||
|
||
sampleTexture(colorCenter, uvCenter, SAMPLER[0], textureFlags); | ||
multiply(outputColor, colorCenter, weightCenter); | ||
|
||
move(uv, uvMinusTwo); | ||
Utils.clamp(uv.x, uv.x, minU, maxU); | ||
Utils.clamp(uv.y, uv.y, minV, maxV); | ||
sampleTexture(colorMinusTwo, uv, SAMPLER[0], textureFlags); | ||
multiply(colorMinusTwo, colorMinusTwo, weightTwo); | ||
add(outputColor, outputColor, colorMinusTwo); | ||
|
||
move(uv, uvMinusOne); | ||
Utils.clamp(uv.x, uv.x, minU, maxU); | ||
Utils.clamp(uv.y, uv.y, minV, maxV); | ||
sampleTexture(colorMinusOne, uv, SAMPLER[0], textureFlags); | ||
multiply(colorMinusOne, colorMinusOne, weightOne); | ||
add(outputColor, outputColor, colorMinusOne); | ||
|
||
move(uv, uvPlusOne); | ||
Utils.clamp(uv.x, uv.x, minU, maxU); | ||
Utils.clamp(uv.y, uv.y, minV, maxV); | ||
sampleTexture(colorPlusOne, uv, SAMPLER[0], textureFlags); | ||
multiply(colorPlusOne, colorPlusOne, weightOne); | ||
add(outputColor, outputColor, colorPlusOne); | ||
|
||
move(uv, uvPlusTwo); | ||
Utils.clamp(uv.x, uv.x, minU, maxU); | ||
Utils.clamp(uv.y, uv.y, minV, maxV); | ||
sampleTexture(colorPlusTwo, uv, SAMPLER[0], textureFlags); | ||
multiply(colorPlusTwo, colorPlusTwo, weightTwo); | ||
add(outputColor, outputColor, colorPlusTwo); | ||
|
||
move(OUTPUT, outputColor); | ||
} | ||
|
||
private function updateParameters():void { | ||
// algorithm described here: | ||
// http://rastergrid.com/blog/2010/09/efficient-gaussian-blur-with-linear-sampling/ | ||
// | ||
// To run in constrained mode, we can only make 5 texture lookups in the fragment | ||
// shader. By making use of linear texture sampling, we can produce similar output | ||
// to what would be 9 lookups. | ||
|
||
_paramsDirty = false; | ||
|
||
var multiplier:Number, str:Number = _strengths[_pass]; | ||
var i:int, count:int = 4; | ||
|
||
trace("str: " + str); | ||
|
||
if(type == HORIZONTAL) { | ||
multiplier = _pixelWidth * str; | ||
|
||
for(i = 0; i < count; i++) | ||
_offsets[i] = _horizontalOffsets[i] * multiplier; | ||
} | ||
else { | ||
multiplier = _pixelHeight * str; | ||
|
||
for(i = 0; i < count; i++) | ||
_offsets[i] = _verticalOffsets[i] * multiplier; | ||
} | ||
} | ||
|
||
private function updateStrengths():void { | ||
_strengthsDirty = false; | ||
|
||
_strengths.length = 0; | ||
var str:Number = Math.min(_firstPassStrength, _strength); | ||
var sum:Number = 0; | ||
|
||
while(sum + str < _strength) { | ||
_strengths[_strengths.length] = str; | ||
sum += str; | ||
str *= _strengthIncreaseRatio; | ||
} | ||
|
||
var diff:Number = _strength - sum; | ||
|
||
if(diff > 0 || _strengths.length == 0) | ||
_strengths[_strengths.length] = diff; | ||
|
||
_strengths.sort(function (a:Number, b:Number):Number { return b - a; }); | ||
|
||
trace("strengths: [" + _strengths + "], total: " + _strength); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/** | ||
* User: booster | ||
* Date: 11/12/13 | ||
* Time: 14:26 | ||
*/ | ||
package starling.shaders { | ||
import flash.display3D.Context3D; | ||
import flash.display3D.Program3D; | ||
|
||
public interface ITextureShader { | ||
function activate(context:Context3D):void | ||
function upload(context:Context3D):Program3D | ||
function deactivate(context:Context3D):void | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* User: booster | ||
* Date: 10/12/13 | ||
* Time: 12:50 | ||
*/ | ||
package starling.shaders { | ||
import com.barliesque.agal.EasierAGAL; | ||
import com.barliesque.agal.TextureFlag; | ||
|
||
import flash.display3D.Context3D; | ||
|
||
public class RenderTextureShader extends EasierAGAL implements ITextureShader { | ||
public function RenderTextureShader(debug:Boolean = true, assemblyDebug:Boolean = false) { | ||
super(debug, assemblyDebug); | ||
} | ||
|
||
public function activate(context:Context3D):void { } | ||
|
||
public function deactivate(context:Context3D):void { } | ||
|
||
override protected function _vertexShader():void { | ||
comment("Apply a 4x4 matrix to transform vertices to clip-space"); | ||
multiply4x4(OUTPUT, ATTRIBUTE[0], CONST[0]); | ||
|
||
comment("Pass uv coordinates to fragment shader"); | ||
move(VARYING[0], ATTRIBUTE[1]); | ||
} | ||
|
||
override protected function _fragmentShader():void { | ||
comment("Use UV coordinates passed from vertex shader to sample the texture"); | ||
sampleTexture(TEMP[1], VARYING[0], SAMPLER[0], [TextureFlag.TYPE_2D, TextureFlag.MODE_CLAMP, TextureFlag.FILTER_NEAREST, TextureFlag.MIP_NO]); | ||
move(OUTPUT, TEMP[1]); | ||
} | ||
} | ||
} |
Oops, something went wrong.