/src/aerys/minko/render/effect/lightScattering/LightScatteringPostProcessShader.as
ActionScript | 107 lines | 89 code | 17 blank | 1 comment | 1 complexity | d599b15f7441bdad9b1b7a3cd0fed9f7 MD5 | raw file
1package aerys.minko.render.effect.lightScattering
2{
3 import aerys.minko.render.resource.texture.TextureResource;
4 import aerys.minko.render.shader.SFloat;
5 import aerys.minko.render.shader.Shader;
6 import aerys.minko.render.shader.ShaderSettings;
7 import aerys.minko.render.shader.part.PostProcessingShaderPart;
8 import aerys.minko.scene.data.lightScattering.LightScatteringProvider;
9 import aerys.minko.type.enum.Blending;
10 import aerys.minko.type.enum.DepthTest;
11 import aerys.minko.type.enum.SamplerFiltering;
12 import aerys.minko.type.enum.SamplerMipMapping;
13 import aerys.minko.type.enum.SamplerWrapping;
14 import aerys.minko.type.enum.TriangleCulling;
15 import aerys.minko.type.math.Vector4;
16
17 import flash.utils.Dictionary;
18
19 public class LightScatteringPostProcessShader extends Shader
20 {
21 private var _postProcessing : PostProcessingShaderPart = null;
22
23 private var _numSamples : Number = 0.;
24 private var _nbPasses : Number = 0.;
25 private var _curPass : Number = 0.;
26 private var _occludedSource : TextureResource = null;
27
28 public function LightScatteringPostProcessShader(numSamples : Number,
29 nbPasses : Number,
30 curPass : Number,
31 occlusionMap : TextureResource)
32 {
33 _nbPasses = nbPasses;
34 _curPass = curPass;
35 _numSamples = numSamples;
36 _occludedSource = occlusionMap;
37
38 _postProcessing = new PostProcessingShaderPart(this);
39 }
40
41 override protected function initializeSettings(settings:ShaderSettings):void
42 {
43 super.initializeSettings(settings);
44
45 settings.depthTest = DepthTest.ALWAYS;
46 settings.blending = Blending.ADDITIVE;
47 settings.triangleCulling = TriangleCulling.NONE;
48 }
49
50 override protected function getVertexPosition() : SFloat
51 {
52 return _postProcessing.vertexPosition;
53 }
54
55 private function localToUV(value : SFloat) : SFloat
56 {
57 return divide(add(localToScreen(value), 1), 2);
58 }
59
60 override protected function getPixelColor() : SFloat
61 {
62 var lightPosition : SFloat = sceneBindings.getParameter(LightScatteringProperties.SOURCE_POSITION, 4);
63 var lighDirection : SFloat = normalize(subtract(lightPosition, cameraPosition));
64 var textureVertexPos : SFloat = saturate(interpolate(vertexUV));
65 var textureLightPos : SFloat = localToUV(lightPosition);
66 var vertexToLightDelta : SFloat = subtract(divide(textureLightPos.xy, textureLightPos.w), textureVertexPos);
67
68 var cameraDirection : SFloat = normalize(this.cameraDirection);
69 var dotProductResult : SFloat = dotProduct3(lighDirection, normalize(cameraDirection));
70 var colorMultiplier : SFloat = subtract(dotProductResult, 0.5);
71
72 var occlusionMap : SFloat = getTexture(
73 _occludedSource,
74 SamplerFiltering.LINEAR,
75 SamplerMipMapping.LINEAR,
76 SamplerWrapping.CLAMP
77 );
78 var initialColor : SFloat = sampleTexture(occlusionMap, textureVertexPos);
79 var illumDecay : SFloat = float(1.);
80 var sampleColor : SFloat = null;
81
82 // light scattering source values
83 var sourceCensity : SFloat = sceneBindings.getParameter(LightScatteringProperties.SOURCE_DENSITY, 1);
84 var sourceWeight : SFloat = sceneBindings.getParameter(LightScatteringProperties.SOURCE_WEIGHT, 1);
85 var sourceDecay : SFloat = sceneBindings.getParameter(LightScatteringProperties.SOURCE_DECAY, 1);
86 var sourceExposure : SFloat = sceneBindings.getParameter(LightScatteringProperties.SOURCE_EXPOSURE, 1);
87
88 vertexToLightDelta = multiply(vertexToLightDelta, divide(sourceCensity, _numSamples));
89 textureVertexPos = add(textureVertexPos, multiply(divide(vertexToLightDelta, _nbPasses), _curPass));
90
91 for (var i : int = 0; i < _numSamples; ++i)
92 {
93 textureVertexPos = add(textureVertexPos, vertexToLightDelta);
94 sampleColor = sampleTexture(occlusionMap, textureVertexPos);
95 sampleColor = multiply(sampleColor, sourceWeight, illumDecay);
96 initialColor = add(initialColor, sampleColor);
97
98 illumDecay.scaleBy(sourceDecay);
99 }
100
101 return float4(
102 multiply(initialColor.rgb, sourceExposure, colorMultiplier),
103 1.
104 );
105 }
106 }
107}