protected override void OnMaterialRender(uint passId, Material material, ref bool skipPass) { base.OnMaterialRender(passId, material, ref skipPass); const int rt_downscale = 100; const int rt_blurHorizontal = 200; const int rt_blurVertical = 300; const int rt_autoFocus1 = 400; const int rt_autoFocus2 = 401; const int rt_autoFocus3 = 402; const int rt_autoFocusFinal = 403; const int rt_autoFocusCurrent = 404; //const int rt_blurFactors = 500; const int rt_targetOutput = 600; //Skip auto focus passes if no auto focus is enabled if (!autoFocus) { if (passId == rt_autoFocus1 || passId == rt_autoFocus2 || passId == rt_autoFocus3 || passId == rt_autoFocusFinal || passId == rt_autoFocusCurrent) { skipPass = true; return; } } // Prepare the fragment params offsets switch (passId) { case rt_downscale: { Vec2[] sampleOffsets = new Vec2[16]; CalculateDownScale4x4SampleOffsets(Owner.DimensionsInPixels.Size, sampleOffsets); //convert to Vec4 array Vec4[] vec4Offsets = new Vec4[16]; for (int n = 0; n < 16; n++) { Vec2 offset = sampleOffsets[n]; vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0); } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("sampleOffsets", vec4Offsets); } break; case rt_blurHorizontal: case rt_blurVertical: { // horizontal and vertical blur bool horizontal = passId == rt_blurHorizontal; float[] sampleOffsets = new float[15]; Vec4[] sampleWeights = new Vec4[15]; CalculateBlurSampleOffsets(horizontal ? downscaleTextureSize.X : downscaleTextureSize.Y, sampleOffsets, sampleWeights, 3, 1); //convert to Vec4 array Vec4[] vec4Offsets = new Vec4[15]; for (int n = 0; n < 15; n++) { float offset = sampleOffsets[n] * blurSpread; if (horizontal) { vec4Offsets[n] = new Vec4(offset, 0, 0, 0); } else { vec4Offsets[n] = new Vec4(0, offset, 0, 0); } } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("sampleOffsets", vec4Offsets); parameters.SetNamedConstant("sampleWeights", sampleWeights); } break; case rt_autoFocus1: { GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedAutoConstant("farClipDistance", GpuProgramParameters.AutoConstantType.FarClipDistance); } break; case rt_autoFocus2: case rt_autoFocus3: { Vec2[] sampleOffsets = new Vec2[16]; string textureSizeFrom = null; switch (passId) { case rt_autoFocus2: textureSizeFrom = "rt_autoFocus1"; break; case rt_autoFocus3: textureSizeFrom = "rt_autoFocus2"; break; default: Trace.Assert(false); break; } Vec2I sourceTextureSize = Technique.GetTextureDefinition(textureSizeFrom).Size; CalculateDownScale4x4SampleOffsets(sourceTextureSize, sampleOffsets); //convert to Vec4 array Vec4[] vec4Offsets = new Vec4[16]; for (int n = 0; n < 16; n++) { Vec2 offset = sampleOffsets[n]; vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0); } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("sampleOffsets", vec4Offsets); } break; case rt_autoFocusFinal: { GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; Vec4 properties = Vec4.Zero; properties.X = autoFocusRange.Minimum; properties.Y = autoFocusRange.Maximum; properties.Z = RendererWorld.Instance.FrameRenderTimeStep * autoFocusTransitionSpeed; parameters.SetNamedConstant("properties", properties); } break; case rt_autoFocusCurrent: break; //case rt_blurFactors: // { // GpuProgramParameters parameters = material.GetBestTechnique(). // Passes[ 0 ].FragmentProgramParameters; // parameters.SetNamedAutoConstant( "farClipDistance", // GpuProgramParameters.AutoConstantType.FarClipDistance ); // Vec4 properties = Vec4.Zero; // properties.X = autoFocus ? -1.0f : focalDistance; // properties.Y = focalSize; // properties.Z = backgroundTransitionLength; // properties.W = blurForeground ? foregroundTransitionLength : -1; // parameters.SetNamedConstant( "properties", properties ); // } // break; //Final pass case rt_targetOutput: { GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedAutoConstant("farClipDistance", GpuProgramParameters.AutoConstantType.FarClipDistance); Vec4 properties = Vec4.Zero; properties.X = autoFocus ? -1.0f : focalDistance; properties.Y = focalSize; properties.Z = backgroundTransitionLength; properties.W = blurForeground ? foregroundTransitionLength : -1; parameters.SetNamedConstant("properties", properties); //Vec2[] sampleOffsets = new Vec2[ 49 ]; //Vec2 textureSize = Owner.DimensionsInPixels.Size.ToVec2(); //for( int y = -3; y <= 3; y++ ) // for( int x = -3; x <= 3; x++ ) // sampleOffsets[ ( y + 3 ) * 7 + ( x + 3 ) ] = new Vec2( x, y ) / textureSize; ////convert to Vec4 array //Vec4[] vec4Offsets = new Vec4[ 49 ]; //for( int n = 0; n < 49; n++ ) //{ // Vec2 offset = sampleOffsets[ n ]; // vec4Offsets[ n ] = new Vec4( offset[ 0 ], offset[ 1 ], 0, 0 ); //} //parameters.SetNamedConstant( "sampleOffsets", vec4Offsets ); } break; } }
protected override void OnMaterialRender(uint passId, Material material, ref bool skipPass) { base.OnMaterialRender(passId, material, ref skipPass); //update material scheme { string materialScheme = RendererWorld.Instance.DefaultViewport.MaterialScheme; foreach (CompositionTechnique technique in Compositor.Techniques) { foreach (CompositionTargetPass pass in technique.TargetPasses) { pass.MaterialScheme = materialScheme; } if (technique.OutputTargetPass != null) { technique.OutputTargetPass.MaterialScheme = materialScheme; } } } const int rt_luminance0 = 994; const int rt_luminance1 = 993; const int rt_luminance2 = 992; const int rt_luminance3 = 991; const int rt_luminance4 = 990; const int rt_brightPass = 800; const int rt_bloomBlur = 700; const int rt_bloomHorizontal = 701; const int rt_bloomVertical = 702; const int rt_adaptedLuminance = 500; const int rt_targetOutput = 600; //Skip adaptation passes if adaptation switched off. if (!Adaptation) { if (passId == rt_luminance0 || passId == rt_luminance1 || passId == rt_luminance2 || passId == rt_luminance3 || passId == rt_luminance4) { skipPass = true; return; } } //Skip bloom passes if bloom switched off if (BloomScale == 0) { if (passId == rt_brightPass || passId == rt_bloomBlur || passId == rt_bloomHorizontal || passId == rt_bloomVertical) { skipPass = true; return; } } // Prepare the fragment params offsets switch (passId) { case rt_luminance0: { Vec2[] sampleOffsets = new Vec2[9]; // Initialize the sample offsets for the initial luminance pass. int textureSize = Technique.GetTextureDefinition("rt_luminance0").Size.X; float tu = 1.0f / (3.0f * textureSize); int index = 0; for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { sampleOffsets[index] = new Vec2(x, y) * tu; index++; } } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; //convert to Vec4 array Vec4[] vec4Offsets = new Vec4[9]; for (int n = 0; n < 9; n++) { Vec2 offset = sampleOffsets[n]; vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0); } parameters.SetNamedConstant("sampleOffsets", vec4Offsets); } break; case rt_luminance1: case rt_luminance2: case rt_luminance3: case rt_luminance4: { Vec2[] sampleOffsets = new Vec2[16]; string textureSizeFrom = null; switch (passId) { case rt_luminance1: textureSizeFrom = "rt_luminance0"; break; case rt_luminance2: textureSizeFrom = "rt_luminance1"; break; case rt_luminance3: textureSizeFrom = "rt_luminance2"; break; case rt_luminance4: textureSizeFrom = "rt_luminance3"; break; default: Trace.Assert(false); break; } Vec2I textureSize = Technique.GetTextureDefinition(textureSizeFrom).Size; CalculateDownScale4x4SampleOffsets(textureSize, sampleOffsets); //convert to Vec4 array Vec4[] vec4Offsets = new Vec4[16]; for (int n = 0; n < 16; n++) { Vec2 offset = sampleOffsets[n]; vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0); } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("sampleOffsets", vec4Offsets); } break; //BrightPass case rt_brightPass: { Vec2[] sampleOffsets = new Vec2[16]; Vec2I textureSize = Owner.DimensionsInPixels.Size; CalculateDownScale4x4SampleOffsets(textureSize, sampleOffsets); //convert to Vec4 array Vec4[] vec4Offsets = new Vec4[16]; for (int n = 0; n < 16; n++) { Vec2 offset = sampleOffsets[n]; vec4Offsets[n] = new Vec4(offset[0], offset[1], 0, 0); } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("brightThreshold", BloomBrightThreshold); parameters.SetNamedConstant("sampleOffsets", vec4Offsets); } break; case rt_bloomBlur: { Vec2[] sampleOffsets = new Vec2[13]; Vec4[] sampleWeights = new Vec4[13]; Vec2I textureSize = brightPassTextureSize; CalculateGaussianBlur5x5SampleOffsets(textureSize, sampleOffsets, sampleWeights, 1); //convert to Vec4 array Vec4[] vec4Offsets = new Vec4[13]; for (int n = 0; n < 13; n++) { Vec2 offset = sampleOffsets[n]; vec4Offsets[n] = new Vec4(offset.X, offset.Y, 0, 0); } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("sampleOffsets", vec4Offsets); parameters.SetNamedConstant("sampleWeights", sampleWeights); } break; case rt_bloomHorizontal: case rt_bloomVertical: { // horizontal and vertical bloom bool horizontal = passId == rt_bloomHorizontal; float[] sampleOffsets = new float[15]; Vec4[] sampleWeights = new Vec4[15]; Vec2I textureSize = bloomTextureSize; CalculateBloomSampleOffsets(horizontal ? textureSize.X : textureSize.Y, sampleOffsets, sampleWeights, 3, 2); //convert to Vec4 array Vec4[] vec4Offsets = new Vec4[15]; for (int n = 0; n < 15; n++) { float offset = sampleOffsets[n]; if (horizontal) { vec4Offsets[n] = new Vec4(offset, 0, 0, 0); } else { vec4Offsets[n] = new Vec4(0, offset, 0, 0); } } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("sampleOffsets", vec4Offsets); parameters.SetNamedConstant("sampleWeights", sampleWeights); } break; case rt_adaptedLuminance: { float elapsedTime; { float currentTime = RendererWorld.Instance.FrameRenderTime; if (lastLuminanceCalculationTime != -1) { elapsedTime = currentTime - lastLuminanceCalculationTime; } else { elapsedTime = 1000; } lastLuminanceCalculationTime = currentTime; } GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("adaptationMinimum", Adaptation ? AdaptationMinimum : 1); parameters.SetNamedConstant("adaptationMaximum", Adaptation ? AdaptationMaximum : 1); parameters.SetNamedConstant("adaptationVelocity", AdaptationVelocity); parameters.SetNamedConstant("elapsedTime", elapsedTime); } break; //Final pass case rt_targetOutput: { GpuProgramParameters parameters = material.GetBestTechnique(). Passes[0].FragmentProgramParameters; parameters.SetNamedConstant("adaptationMiddleBrightness", Adaptation ? AdaptationMiddleBrightness : 1); parameters.SetNamedConstant("bloomScale", BloomScale); } break; } }