public MainWindow() { Logger.filePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\WooFractal\\Log.txt"; Logger.Log("Starting"); InitializeComponent(); Logger.Log("InitComp complete"); Assembly assembly = Assembly.GetExecutingAssembly(); FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(assembly.Location); string version = fileVersionInfo.ProductVersion; this.Title = "WooFractal (GPU Edition) " + version; DataContext = this; // initialise post process settings _PostProcess = new PostProcess(); _PostProcess._PostProcessFilter = 1; _FinalRTOptions._Progressive = true; _FinalRTOptions._MaxIterations = -1; // initialise the script objects LoadScratch(); Logger.Log("LoadScratch() complete"); UpdateGUI(); Logger.Log("UpdateGUI() complete"); }
public void SetPostProcess(PostProcess postProcess) { _PostProcess = postProcess; if (_GL != null) { _PostProcess.Initialise(_GL); } }
public ImageRenderer(System.Windows.Controls.Image image, string xml, int renderWidth, int renderHeight, bool continuous) { _Image = image; _XML = xml; _RenderWidth = renderWidth; _RenderHeight = renderHeight; _Continuous = continuous; _PostProcess = new PostProcess(); InitialiseRender(_XML); }
public FinalRender(ref Scene scene, ref RaytracerOptions raytracerOptions, ref PostProcess postprocess) { DataContext = this; InitializeComponent(); _Scene = scene; _RaytracerOptions = raytracerOptions; _PostProcess = postprocess; UpdateGUI(); }
private void InitialiseRenderer() { _RaytracerOptions = new RaytracerOptions(); _RaytracerOptions._DoFEnabled = false; _RaytracerOptions._ShadowsEnabled = true; _RaytracerOptions._Reflections = 1; _Scene = new Scene(); _Scene._FractalSettings._FractalIterations.Clear(); _Scene._FractalSettings._FractalColours.Clear(); _Scene._FractalSettings._RenderOptions._Background = 1; FractalGradient preview = new FractalGradient(); preview._GradientSegments[0]._StartColour = _Material; preview._Multiplier = 0.0f; _Scene._FractalSettings._FractalColours.Add(preview); _Scene._Camera._Position = new Vector3(0, 1.5, 1.5); _Scene._Camera._Target = new Vector3(0, 1, 0); _PostProcess = new PostProcess(); // _PostProcess._ToneMappingMode = 3; _PostProcess.Initialise(_GL); // Initialise the scene. string frag = ""; _Scene.Compile(_RaytracerOptions, _Scene._FractalSettings._RenderOptions, ref frag); _ShaderRenderer = new ShaderRenderer(); _ShaderRenderer.Compile(_GL, frag, 16); int width, height; width = (int)openGlCtrl.ActualWidth; height = (int)openGlCtrl.ActualHeight; _ShaderRenderer.Initialise(_GL, width, height, _Scene._Camera.GetViewMatrix(), _Scene._Camera.GetPosition(), false); _ShaderRenderer.SetShaderVars(_Scene._Camera.GetViewMatrix(), _Scene._Camera.GetPosition(), _Scene._FractalSettings._RenderOptions.GetSunVec3(), _Scene._Camera, _Scene._FractalSettings); _ShaderRenderer.SetProgressive(_RaytracerOptions._Progressive); _ShaderRenderer.SetPostProcess(_PostProcess); _ShaderRenderer.Clean(_GL); _ShaderRenderer.Start(); }
public PostProcessSettings(ref PostProcess postProcess, FinalRender parent) { _PostProcess = postProcess; _Parent = parent; DataContext = this; _Iterations = _PostProcess._Settings5x5._Iterations; _BoostPower = _PostProcess._Settings5x5._BoostPower; _SourceWeight = _PostProcess._Settings5x5._SourceWeight; _TargetWeight = _PostProcess._Settings5x5._TargetWeight; _GWidth = _PostProcess._SettingsFastGaussian._Width; _GBoostPower = _PostProcess._SettingsFastGaussian._BoostPower; _GSourceWeight = _PostProcess._SettingsFastGaussian._SourceWeight; _GTargetWeight = _PostProcess._SettingsFastGaussian._TargetWeight; InitializeComponent(); checkBox1.IsChecked = _PostProcess._Settings5x5._Enabled; checkBox2.IsChecked = _PostProcess._SettingsFastGaussian._Enabled; UpdateKernelUI(); }
public MainWindow() { InitializeComponent(); DataContext = this; _SettingsLocation = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\WooFractal\\Settings.xml"; _AppSettings = AppSettings.Load(_SettingsLocation); _WootracerOptions = _AppSettings._WootracerOptions; // initialise post process settings _PostProcess = new PostProcess(); // starting camera settings _WootracerOptions = new WootracerOptions(); InitialiseCamera(); // initialise the scene InitialiseScene(); // initialise the script objects InitialiseScript(); InitialiseTestScene(); ShaderScript.ReadDistanceSchema(); BuildFractalList(); BuildOptionsList(); BuildColourList(); // FractalSettings fractalSettings = LoadFractal("scratch"); // _FractalIterations = fractalSettings._FractalIterations; // _FractalColours = fractalSettings._FractalColours; // _RenderOptions = fractalSettings._RenderOptions; }
public FinalRender(ref Scene scene, ref Camera camera, ref PostProcess postprocess) { _Scene = scene; _Camera = camera; _Recursions = _Scene._Recursions; DataContext = this; InitializeComponent(); _MaxValue = 1; _Factor = 1; _ToneFactor = 1.4; _GammaFactor = 0.7; _GammaContrast = 0.7; if (_Camera._AAEnabled) { checkBox1.IsChecked = true; } if (_Camera._DOFEnabled) { checkBox2.IsChecked = true; } if (_Scene._PathTracer) { checkBox3.IsChecked = true; } if (_Scene._Caustics) { checkBox4.IsChecked = true; } _SamplesPerPixel = _Camera._MinSamples; _PostProcess = postprocess; BuildXML(); }
/// <summary> /// Initialises the Scene. /// </summary> /// <param name="gl">The OpenGL instance.</param> public void Initialise(OpenGL gl, int width, int height, mat4 viewMatrix, vec3 position, bool burnVariables) { Logger.Log("ShaderRenderer.Initialise Started"); _GL = gl; if (_Initialised) { Destroy(gl); _Initialised = true; } _ViewMatrix = viewMatrix; _Position = position; _TargetWidth = width; _TargetHeight = height; _ProgressiveSteps = 1; _ProgressiveIndex = 0; _BurnVariables = burnVariables; // We're going to specify the attribute locations for the position and normal, // so that we can force both shaders to explicitly have the same locations. const uint positionAttribute = 0; var attributeLocations = new Dictionary <uint, string> { { positionAttribute, "Position" } }; Logger.Log("ShaderRenderer.Initialise Loading shaders from manifest"); // Create the raymarch shader shaderRayMarch = new ShaderProgram(); if (_Program == null) { shaderRayMarch.Create(gl, ManifestResourceLoader.LoadTextFile(@"Shaders\RayMarchProgressive.vert"), ManifestResourceLoader.LoadTextFile(@"Shaders\RayMarch.frag"), attributeLocations); } else { if (_BurnVariables) { ShaderVariables shaderVars = GetShaderVars(); shaderVars.BurnVariables(ref _Program); } _ShaderError = false; try { shaderRayMarch.Create(gl, ManifestResourceLoader.LoadTextFile(@"Shaders\RayMarchProgressive.vert"), _Program, attributeLocations); } catch (ShaderCompilationException exception) { _ShaderError = true; MessageBox.Show(exception.Message + "\r\n" + exception.CompilerOutput); } } // Create the transfer shader string fragShader = @" #version 130 in vec2 texCoord; out vec4 FragColor; uniform float mode; // 0=ramp, 1=exposure, 2=standard uniform float toneFactor; uniform float gammaFactor; uniform float gammaContrast; uniform sampler2D renderedTexture; vec3 filmic(vec3 value) { float A=0.22; float B=0.30; float C=0.1; float D=0.2; float E=0.01; float F=0.3; return ((value*(A*value+C*B)+D*E)/(value*(A*value+B)+D*F)) - E/F; } void main() { vec4 rgb = texture(renderedTexture, vec2((texCoord.x+1)*0.5, (texCoord.y+1)*0.5)); FragColor=rgb; // FragColor.rgb /= FragColor.a; // brightness/contrast float luminance = dot(FragColor.rgb, vec3(0.2126,0.7152,0.0722)); float luminanceOut = gammaFactor * pow(luminance, gammaContrast); float multiplier = (max(0, luminance) * luminanceOut) / (luminance * luminance); FragColor.rgb *= multiplier; if (mode>2.9 && mode<3.1) { //filmic https://www.slideshare.net/ozlael/hable-john-uncharted2-hdr-lighting FragColor.rgb = filmic(FragColor.rgb)/filmic(vec3(toneFactor)); } else if (mode>1.9 && mode<2.1) { //reinhard https://imdoingitwrong.wordpress.com/2010/08/19/why-reinhard-desaturates-my-blacks-3/ float nL = luminance * (1+luminance/(toneFactor*toneFactor)) / (1+luminance); FragColor.rgb *= nL; } else if (mode>0.9 && mode<1.1) { //exposure originally Matt Fairclough FragColor.rgb = 1 - exp(-FragColor.rgb * toneFactor); } else { FragColor.rgb /= toneFactor; } } "; shaderTransfer = new ShaderProgram(); shaderTransfer.Create(gl, ManifestResourceLoader.LoadTextFile(@"Shaders\RayMarch.vert"), fragShader, attributeLocations); CheckForError(gl); fragShader = @" #version 130 in vec2 texCoord; out vec4 FragColor; void main() { FragColor=vec4(0,0,0,0); } "; shaderClean = new ShaderProgram(); shaderClean.Create(gl, ManifestResourceLoader.LoadTextFile(@"Shaders\RayMarch.vert"), fragShader, attributeLocations); CheckForError(gl); // Create the transfer shader string fragShaderIntTransfer = @" #version 130 in vec2 texCoord; out vec4 FragColor; uniform sampler2D renderedTexture; void main() { vec4 rgb = texture(renderedTexture, vec2((texCoord.x+1)*0.5, (texCoord.y+1)*0.5)); FragColor=rgb; } "; shaderIntTransfer = new ShaderProgram(); shaderIntTransfer.Create(gl, ManifestResourceLoader.LoadTextFile(@"Shaders\RayMarch.vert"), fragShaderIntTransfer, attributeLocations); CheckForError(gl); Logger.Log("ShaderRenderer.Initialise Loading random numbers"); LoadRandomNumbers(gl); Logger.Log("ShaderRenderer.Initialise Finished loading random numbers"); float[] viewport = new float[4]; gl.GetFloat(OpenGL.GL_VIEWPORT, viewport); gl.GenFramebuffersEXT(2, _FrameBuffer); CheckForError(gl); gl.GenTextures(2, _RaytracerBuffer); CheckForError(gl); for (int i = 0; i < 2; i++) { gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _FrameBuffer[i]); gl.BindTexture(OpenGL.GL_TEXTURE_2D, _RaytracerBuffer[i]); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_EDGE); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_EDGE); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_GENERATE_MIPMAP_SGIS, OpenGL.GL_FALSE); // automatic mipmap // gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA, (int)viewport[2], (int)viewport[3], 0, // OpenGL.GL_RGBA, OpenGL.GL_FLOAT, null); gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA32F, _TargetWidth, _TargetHeight, 0, OpenGL.GL_RGBA, OpenGL.GL_FLOAT, null); CheckForError(gl); gl.FramebufferTexture2DEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, _RaytracerBuffer[i], 0); gl.FramebufferRenderbufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_DEPTH_ATTACHMENT_EXT, OpenGL.GL_RENDERBUFFER_EXT, 0); } gl.BindTexture(OpenGL.GL_TEXTURE_2D, 0); gl.GenFramebuffersEXT(2, _EffectFrameBuffer); CheckForError(gl); gl.GenTextures(2, _EffectRaytracerBuffer); CheckForError(gl); for (int i = 0; i < 2; i++) { gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _EffectFrameBuffer[i]); gl.BindTexture(OpenGL.GL_TEXTURE_2D, _EffectRaytracerBuffer[i]); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_EDGE); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_EDGE); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_GENERATE_MIPMAP_SGIS, OpenGL.GL_FALSE); // automatic mipmap gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA32F, _TargetWidth, _TargetHeight, 0, OpenGL.GL_RGBA, OpenGL.GL_FLOAT, null); CheckForError(gl); gl.FramebufferTexture2DEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, _EffectRaytracerBuffer[i], 0); gl.FramebufferRenderbufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_DEPTH_ATTACHMENT_EXT, OpenGL.GL_RENDERBUFFER_EXT, 0); } gl.BindTexture(OpenGL.GL_TEXTURE_2D, 0); // and now initialise the integer framebuffer gl.GenFramebuffersEXT(1, _IntFrameBuffer); CheckForError(gl); gl.GenTextures(1, _PostprocessBuffer); CheckForError(gl); gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _IntFrameBuffer[0]); gl.BindTexture(OpenGL.GL_TEXTURE_2D, _PostprocessBuffer[0]); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_EDGE); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_EDGE); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_GENERATE_MIPMAP_SGIS, OpenGL.GL_FALSE); // automatic mipmap gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA, _TargetWidth, _TargetHeight, 0, OpenGL.GL_RGBA, OpenGL.GL_UNSIGNED_BYTE, null); CheckForError(gl); gl.FramebufferTexture2DEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, _PostprocessBuffer[0], 0); gl.FramebufferRenderbufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_DEPTH_ATTACHMENT_EXT, OpenGL.GL_RENDERBUFFER_EXT, 0); gl.BindTexture(OpenGL.GL_TEXTURE_2D, 0); _PostProcess = new PostProcess(); _PostProcess.Initialise(gl); gl.GenFramebuffersEXT(1, _DepthFrameBuffer); gl.GenTextures(1, _DepthCalcBuffer); gl.BindFramebufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, _DepthFrameBuffer[0]); gl.BindTexture(OpenGL.GL_TEXTURE_2D, _DepthCalcBuffer[0]); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MAG_FILTER, OpenGL.GL_LINEAR); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_MIN_FILTER, OpenGL.GL_LINEAR_MIPMAP_LINEAR); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_S, OpenGL.GL_CLAMP_TO_EDGE); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_TEXTURE_WRAP_T, OpenGL.GL_CLAMP_TO_EDGE); gl.TexParameter(OpenGL.GL_TEXTURE_2D, OpenGL.GL_GENERATE_MIPMAP_SGIS, OpenGL.GL_TRUE); gl.TexImage2D(OpenGL.GL_TEXTURE_2D, 0, OpenGL.GL_RGBA32F, 1, 1, 0, OpenGL.GL_RGBA, OpenGL.GL_FLOAT, null); gl.FramebufferTexture2DEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_COLOR_ATTACHMENT0_EXT, OpenGL.GL_TEXTURE_2D, _DepthCalcBuffer[0], 0); gl.FramebufferRenderbufferEXT(OpenGL.GL_FRAMEBUFFER_EXT, OpenGL.GL_DEPTH_ATTACHMENT_EXT, OpenGL.GL_RENDERBUFFER_EXT, 0); _Initialised = true; /* * gl.GenRenderbuffersEXT(2, _RaytracerBuffer); * gl.BindRenderbufferEXT(OpenGL.GL_RENDERBUFFER_EXT, _RaytracerBuffer[0]); * gl.RenderbufferStorageEXT(OpenGL.GL_RENDERBUFFER_EXT, OpenGL.GL_RGBA32F, (int)viewport[2], (int)viewport[3]); * gl.BindRenderbufferEXT(OpenGL.GL_RENDERBUFFER_EXT, _RaytracerBuffer[1]); * gl.RenderbufferStorageEXT(OpenGL.GL_RENDERBUFFER_EXT, OpenGL.GL_RGBA32F, (int)viewport[2], (int)viewport[3]); */ // gl.GenRenderbuffersEXT(1, _RenderBuffer); //gl.BindRenderbufferEXT(OpenGL.GL_RENDERBUFFER_EXT, _RenderBuffer[0]); //gl.RenderbufferStorageEXT(OpenGL.GL_RENDERBUFFER_EXT, OpenGL.GL_RGBA, (int)viewport[2], (int)viewport[3]); Logger.Log("ShaderRenderer.Initialise Finished"); }
public FinalRender(ref Scene scene, ref Camera camera, ref PostProcess postprocess) { _Scene = scene; _Camera = camera; _Recursions = _Scene._Recursions; DataContext = this; InitializeComponent(); _MaxValue = 1; _Factor = 1; _ToneFactor = 1.4; _GammaFactor = 0.7; _GammaContrast = 0.7; if (_Camera._AAEnabled) checkBox1.IsChecked = true; if (_Camera._DOFEnabled) checkBox2.IsChecked = true; if (_Scene._PathTracer) checkBox3.IsChecked = true; if (_Scene._Caustics) checkBox4.IsChecked = true; _SamplesPerPixel = _Camera._MinSamples; _PostProcess = postprocess; BuildXML(); }
/* public void PostProcess(float[] targetBuffer, float[] sourceBuffer, float[] boostBuffer, float[] kernel, float boostPower, float kernelweighting, float sourceweighting, int iterations, int width, int height) * { * if (boostPower != 1) * { * double maxV = _MaxValue<0.001f ? 1 : _MaxValue; * double boostP = _BoostPower; * for (int i = 0; i < width * height * 3; i++) * { * boostBuffer[i] = (float)Math.Pow(sourceBuffer[i] / maxV, boostP); * } * } * else * { * boostBuffer = sourceBuffer; * } * * for (int iter = 0; iter < _Iterations; iter++) * { * for (int y = 0; y < height; y++) * { * for (int x = 0; x < width; x++) * { * int patchStartX = x - 2; * patchStartX = Math.Max(0, patchStartX) - x; * int patchEndX = x + 2; * patchEndX = Math.Min(patchEndX, width-1) - x; * int patchStartY = y - 2; * patchStartY = Math.Max(0, patchStartY) - y; * int patchEndY = y + 2; * patchEndY = Math.Min(patchEndY, height-1) - y; * * // iterate over a patch * float totalr = 0; * float totalg = 0; * float totalb = 0; * float totalweighting = 0; * for (int py = patchStartY; py <= patchEndY; py++) * { * for (int px = patchStartX; px <= patchEndX; px++) * { * int rx = px + x; * int ry = py + y; * float kernelW = kernel[(py+2) * 5 + px+2]; * totalr += boostBuffer[(ry * width + rx) * 3] * kernelW; * totalg += boostBuffer[(ry * width + rx) * 3 + 1] * kernelW; * totalb += boostBuffer[(ry * width + rx) * 3 + 2] * kernelW; * totalweighting += kernelW; * } * } * * // divide through * targetBuffer[(x + y * width) * 3] = totalr / totalweighting; * targetBuffer[(x + y * width) * 3 + 1] = totalg / totalweighting; * targetBuffer[(x + y * width) * 3 + 2] = totalb / totalweighting; * } * } * for (int i = 0; i < width * height * 3; i++) * { * boostBuffer[i] = targetBuffer[i]; * } * } * * // divide through * for (int y = 0; y < height; y++) * { * for (int x = 0; x < width; x++) * { * targetBuffer[(x + y * width) * 3] = _TargetWeight * targetBuffer[(x + y * width) * 3] + _SourceWeight * sourceBuffer[(x + y * width) * 3]; * targetBuffer[(x + y * width) * 3 + 1] = _TargetWeight * targetBuffer[(x + y * width) * 3 + 1] + _SourceWeight * sourceBuffer[(x + y * width) * 3 + 1]; * targetBuffer[(x + y * width) * 3 + 2] = _TargetWeight * targetBuffer[(x + y * width) * 3 + 2] + _SourceWeight * sourceBuffer[(x + y * width) * 3 + 2]; * } * } * } */ public void SetPostProcess(PostProcess postprocess) { _PostProcess = postprocess; }
/* public void PostProcess(float[] targetBuffer, float[] sourceBuffer, float[] boostBuffer, float[] kernel, float boostPower, float kernelweighting, float sourceweighting, int iterations, int width, int height) { if (boostPower != 1) { double maxV = _MaxValue<0.001f ? 1 : _MaxValue; double boostP = _BoostPower; for (int i = 0; i < width * height * 3; i++) { boostBuffer[i] = (float)Math.Pow(sourceBuffer[i] / maxV, boostP); } } else { boostBuffer = sourceBuffer; } for (int iter = 0; iter < _Iterations; iter++) { for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int patchStartX = x - 2; patchStartX = Math.Max(0, patchStartX) - x; int patchEndX = x + 2; patchEndX = Math.Min(patchEndX, width-1) - x; int patchStartY = y - 2; patchStartY = Math.Max(0, patchStartY) - y; int patchEndY = y + 2; patchEndY = Math.Min(patchEndY, height-1) - y; // iterate over a patch float totalr = 0; float totalg = 0; float totalb = 0; float totalweighting = 0; for (int py = patchStartY; py <= patchEndY; py++) { for (int px = patchStartX; px <= patchEndX; px++) { int rx = px + x; int ry = py + y; float kernelW = kernel[(py+2) * 5 + px+2]; totalr += boostBuffer[(ry * width + rx) * 3] * kernelW; totalg += boostBuffer[(ry * width + rx) * 3 + 1] * kernelW; totalb += boostBuffer[(ry * width + rx) * 3 + 2] * kernelW; totalweighting += kernelW; } } // divide through targetBuffer[(x + y * width) * 3] = totalr / totalweighting; targetBuffer[(x + y * width) * 3 + 1] = totalg / totalweighting; targetBuffer[(x + y * width) * 3 + 2] = totalb / totalweighting; } } for (int i = 0; i < width * height * 3; i++) { boostBuffer[i] = targetBuffer[i]; } } // divide through for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { targetBuffer[(x + y * width) * 3] = _TargetWeight * targetBuffer[(x + y * width) * 3] + _SourceWeight * sourceBuffer[(x + y * width) * 3]; targetBuffer[(x + y * width) * 3 + 1] = _TargetWeight * targetBuffer[(x + y * width) * 3 + 1] + _SourceWeight * sourceBuffer[(x + y * width) * 3 + 1]; targetBuffer[(x + y * width) * 3 + 2] = _TargetWeight * targetBuffer[(x + y * width) * 3 + 2] + _SourceWeight * sourceBuffer[(x + y * width) * 3 + 2]; } } } */ public void SetPostProcess(PostProcess postprocess) { _PostProcess = postprocess; }