{
  "Name": "DepthOfField",
  "_id": "891f9149-7f10-43fa-b4c8-6b06de535150",
  "Namespace": "lib.image.blur",
  "Description": "Simple depth of field.",
  "Inputs": [
    {
      "Name": "Code",
      "MetaInstanceID": "7227b45b-b8ed-4b60-8118-29aad14efd1b",
      "DefaultValue": {
        "Type": "Text",
        "Value": [
          "//>>> _common parameters\r",
          "float4x4 objectToWorldMatrix;",
          "float4x4 worldToCameraMatrix;",
          "float4x4 projMatrix;",
          "Texture2D txDiffuse;",
          "float2 RenderTargetSize;",
          "//<<< _common parameters\r",
          "\r",
          "//>>> _parameters\r",
          "Texture2D Image;",
          "float Glow;",
          "float Offset;",
          "float Size;",
          "float NumberOfSamples;",
          "float Focus;",
          "float Range;",
          "//<<< _parameters\r",
          "float4x4 viewToCamera;\r",
          "Texture2D txDepth;\r",
          "float widthToHeight;\r",
          "float2 direction;\r",
          "\r",
          "//>>> _setup\r",
          "SamplerState samLinear",
          "{",
          "    Filter = MIN_MAG_MIP_LINEAR;",
          "    AddressU = Clamp;",
          "    AddressV = Clamp;",
          "};",
          "//<<< _setup\r",
          "\r",
          "//>>> _declarations\r",
          "struct VS_IN",
          "{",
          "    float4 pos : POSITION;",
          "    float2 texCoord : TEXCOORD;",
          "};",
          "",
          "struct PS_IN",
          "{",
          "    float4 pos : SV_POSITION;",
          "    float2 texCoord: TEXCOORD0;",
          "};",
          "//<<< _declarations\r",
          "\r",
          "//>>> _GS\r",
          "",
          "//<<< _GS\r",
          "\r",
          "//>>> _VS \r",
          "PS_IN VS( VS_IN input )",
          "{",
          "    PS_IN output = (PS_IN)0;",
          "",
          "    output.pos = mul(input.pos, worldToCameraMatrix);",
          "    output.pos = mul(output.pos, projMatrix);",
          "    output.texCoord = input.texCoord;",
          "",
          "    return output;",
          "}",
          "//<<< _VS\r",
          "\r",
          "//>>> PS\r",
          "static const int NUMWT = 10;\r",
          "static const float Gauss[NUMWT] = { 0.93, 0.86, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1 };\r",
          "\r",
          "float4 PS( PS_IN input ) : SV_Target\r",
          "{\r",
          "    float4 c = txDiffuse.Sample(samLinear, input.texCoord);\r",
          "    float depth = txDepth.Sample(samLinear, input.texCoord).r;\r",
          "    if (depth > 0.999)\r",
          "        return c;\r",
          "    float4 viewTFragPos = float4(input.texCoord.x*2.0 - 1.0, input.texCoord.y*2.0 - 1.0, depth, 1.0);\r",
          "    float4 cameraTFragPos = mul(viewTFragPos, viewToCamera);\r",
          "    cameraTFragPos /= cameraTFragPos.w;\r",
          "\r",
          "    float2 dir = direction;\r",
          "    dir *= Size*abs(Focus - cameraTFragPos.z)/Range*0.001;\r",
          "    dir /= NumberOfSamples;\r",
          "    dir.y *= widthToHeight;\r",
          "\r",
          "    float2 pos = dir;\r",
          "    float totalWeight = 1;\r",
          "    for (int i = 0; i < NumberOfSamples; ++i)\r",
          "    {\r",
          "        float index = (float)i*(NUMWT - 1)/NumberOfSamples;\r",
          "        float weight = lerp(Gauss[(int)index], Gauss[(int)index + 1], frac(index));\r",
          "        c += txDiffuse.SampleLevel(samLinear, input.texCoord + pos, 0)*weight;\r",
          "        c += txDiffuse.SampleLevel(samLinear, input.texCoord - pos, 0)*weight;\r",
          "        pos += dir;\r",
          "        totalWeight += 2*weight;\r",
          "    }\r",
          "\r",
          "    c.rgb = float3(Offset, Offset, Offset) + c.rgb/totalWeight*Glow;\r",
          "    c.a = 1.0;\r",
          "\r",
          "    return c;\r",
          "}\r",
          "//<<< PS\r",
          "\r",
          "//>>> _technique\r",
          "technique10 Render",
          "{",
          "    pass P0",
          "    {",
          "        SetGeometryShader( 0 );",
          "        SetVertexShader( CompileShader( vs_4_0, VS() ) );",
          "        SetPixelShader( CompileShader( ps_4_0, PS() ) );",
          "    }",
          "}",
          "//<<< _technique\r",
          ""
        ]
      },
      "MetaID": "c522a66e-3260-4692-b3e3-79fd0361fa3d",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Image",
      "MetaInstanceID": "f2502bc5-6f0a-455e-b425-79836718f08b",
      "DefaultValue": {
        "Type": "Image",
        "Value": "Framefield.Core.Image"
      },
      "MetaID": "9848060d-fd84-45b0-b658-d0d531c61dab",
      "IsMultiInput": "False",
      "Relevance": "Required",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Camera",
      "MetaInstanceID": "dac2128e-8792-49e8-950c-676c6f1e1408",
      "DefaultValue": {
        "Type": "Dynamic",
        "Value": "Framefield.Core.Dynamic"
      },
      "MetaID": "9701d534-b3ff-4889-a250-84aece4a7d76",
      "IsMultiInput": "False",
      "Relevance": "Required",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Glow",
      "MetaInstanceID": "793f434f-74fa-486d-b3bb-f5e9abdf177c",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0.001",
      "Max": "1000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Offset",
      "MetaInstanceID": "c675f060-1f25-4a9a-8c79-1e5ada1715d3",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-10",
      "Max": "1000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Size",
      "MetaInstanceID": "cceb5c7f-6be0-4639-8850-0570a4688c3a",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0.2"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "100",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Number Of Samples",
      "MetaInstanceID": "0c119b52-8abb-4cf7-b342-cfc9168fffdf",
      "DefaultValue": {
        "Type": "Float",
        "Value": "9"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "100",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Focus",
      "MetaInstanceID": "12c2616e-1069-4144-82ae-69265ad3ae41",
      "DefaultValue": {
        "Type": "Float",
        "Value": "10"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-1000",
      "Max": "1000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Range",
      "MetaInstanceID": "06f71a0a-910e-4a9e-a1a0-f753242c1b19",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "100",
      "Scale": "0.01",
      "ScaleType": "Linear",
      "EnumValues": []
    }
  ],
  "Outputs": [
    {
      "Name": "Image",
      "MetaInstanceID": "efe25165-2b4e-4cf9-8c77-0bcde2d49da0",
      "MetaID": "9848060d-fd84-45b0-b658-d0d531c61dab"
    }
  ],
  "OperatorParts": [
    {
      "MetaInstanceID": "611076db-f6a1-4313-b5b2-1a5f21bca33c",
      "MetaID": "0ac6623c-f64d-41a9-b30d-d8f4fcb84943",
      "Name": "DepthOfFieldFunc",
      "Version": "4848c14f-3e70-47fd-bd85-7f9da4d0cda7",
      "Type": "Float",
      "IsMultiInput": "True",
      "Script": [
        "//>>> _using",
        "using System;",
        "using System.Collections.Generic;",
        "using System.Linq;",
        "using System.Text;",
        "using SharpDX;",
        "using SharpDX.Direct3D11;",
        "using SharpDX.Windows;",
        "//<<< _using",
        "using SharpDX.Direct3D;",
        "using SharpDX.DXGI;",
        "",
        "namespace Framefield.Core.ID0ac6623c_f64d_41a9_b30d_d8f4fcb84943",
        "{",
        "    public class Class_DepthOfField : FXImageFunction",
        "    {",
        "        protected override bool NeedsDepth { get { return false; } }",
        "",
        "        //>>> _inputids",
        "        private enum InputId",
        "        {",
        "            Code = 0,",
        "            Image = 1,",
        "            Camera = 2,",
        "            Glow = 3,",
        "            Offset = 4,",
        "            Size = 5,",
        "            NumberOfSamples = 6,",
        "            Focus = 7,",
        "            Range = 8",
        "        }",
        "        //<<< _inputids",
        "",
        "        protected override bool BuildRenderTarget(SharpDX.DXGI.Format imageBufferFormat)",
        "        {",
        "            var pass1ResourceChanged = ResourceManager.ValidateRenderTargetResource(ref _pass1RenderTargetResource, OperatorPart, D3DDevice.Device,",
        "                                                                                    (int)_usedViewport.Width, (int)_usedViewport.Height);",
        "            if (pass1ResourceChanged)",
        "            {",
        "                Utilities.DisposeObj(ref _pass1RenderTargetView);",
        "                _pass1RenderTargetView = new RenderTargetView(D3DDevice.Device, _pass1RenderTargetResource.Texture);",
        "            }",
        "",
        "            return base.BuildRenderTarget(imageBufferFormat) || pass1ResourceChanged;",
        "        }",
        "",
        "        public override void Dispose()",
        "        {",
        "            ResourceManager.Dispose(_pass1RenderTargetResource);",
        "            Utilities.DisposeObj(ref _pass1RenderTargetView);",
        "            base.Dispose();",
        "        }",
        "",
        "        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)",
        "        {",
        "            return PrepareAndEvalOnChange(context, () =>",
        "            {",
        "                //>>> __params",
        "                var Code = inputs[(int)InputId.Code].Eval(context).Text;",
        "                var resultContextOfImageInput = inputs[(int)InputId.Image].Eval(context);",
        "                var Image = resultContextOfImageInput.Image;",
        "                var DepthImage = resultContextOfImageInput.DepthImage;",
        "                var Camera = inputs[(int)InputId.Camera].Eval(context).Dynamic;",
        "                var Glow = inputs[(int)InputId.Glow].Eval(context).Value;",
        "                var Offset = inputs[(int)InputId.Offset].Eval(context).Value;",
        "                var Size = inputs[(int)InputId.Size].Eval(context).Value;",
        "                var NumberOfSamples = inputs[(int)InputId.NumberOfSamples].Eval(context).Value;",
        "                var Focus = inputs[(int)InputId.Focus].Eval(context).Value;",
        "                var Range = inputs[(int)InputId.Range].Eval(context).Value;",
        "                //<<< __params",
        "",
        "                if (Image == null || DepthImage == null || Camera == null)",
        "                {",
        "                    Logger.Error(this, \"color or depth image or camera is not available\");",
        "                    return;",
        "                }",
        "",
        "                Framefield.Core.OperatorPartTraits.ICameraProvider camProvider = Camera.This as Framefield.Core.OperatorPartTraits.ICameraProvider;",
        "                if (camProvider == null)",
        "                {",
        "                    Logger.Error(this, \"camera not defined\");",
        "                    return;",
        "                }",
        "",
        "                var D3DDevice = context.D3DDevice;",
        "                var proj = Matrix.OrthoLH(1, 1, -100, 100);",
        "                var worldToCamera = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), new Vector3(0, 1, 0));",
        "",
        "                var shaderDesc = new ShaderResourceViewDescription();",
        "                shaderDesc.Format = Format.R32_Float;",
        "                shaderDesc.Dimension = ShaderResourceViewDimension.Texture2D;",
        "                shaderDesc.Texture2D.MipLevels = 1;",
        "                using (var depthTexture = new ShaderResourceView(D3DDevice, DepthImage, shaderDesc))",
        "                {",
        "                    var viewToCamera = Matrix.Invert(camProvider.CalculateCameraToView(context));",
        "",
        "                    _effect.GetVariableByName(\"viewToCamera\").AsMatrix().SetMatrix(viewToCamera);",
        "                    _effect.GetVariableByName(\"txDepth\").AsShaderResource().SetResource(depthTexture); ",
        "                    _effect.GetVariableByName(\"widthToHeight\").AsScalar().Set((float)_usedViewport.Width/_usedViewport.Height);",
        "                    _effect.GetVariableByName(\"Size\").AsScalar().Set(Size);",
        "                    _effect.GetVariableByName(\"Glow\").AsScalar().Set(Glow);",
        "                    _effect.GetVariableByName(\"Offset\").AsScalar().Set(Offset);",
        "                    _effect.GetVariableByName(\"NumberOfSamples\").AsScalar().Set(NumberOfSamples);",
        "                    _effect.GetVariableByName(\"Focus\").AsScalar().Set(Focus);",
        "                    _effect.GetVariableByName(\"Range\").AsScalar().Set(Range);",
        "",
        "                    //pass 1 (horizontal)",
        "                    D3DDevice.ImmediateContext.ClearRenderTargetView(_pass1RenderTargetView, new SharpDX.Color4(0, 0, 0, 1));",
        "",
        "                    var pass1SubContext = new OperatorPartContext(context);",
        "                    pass1SubContext.DepthStencilView = null;",
        "                    pass1SubContext.RenderTargetView = _pass1RenderTargetView;",
        "                    pass1SubContext.Effect = _effect;",
        "                    pass1SubContext.InputLayout = context.Renderer.ScreenQuadInputLayout;",
        "                    pass1SubContext.CameraProjection = proj;",
        "                    pass1SubContext.WorldToCamera = worldToCamera;",
        "                    using (var textureView = new ShaderResourceView(D3DDevice, Image))",
        "                    {",
        "                        pass1SubContext.Texture0 = textureView;",
        "                        pass1SubContext.Renderer.SetupEffect(pass1SubContext);",
        "",
        "                        _effect.GetVariableByName(\"direction\").AsVector().Set(new Vector2(1, 0));",
        "",
        "                        pass1SubContext.Renderer.Render(pass1SubContext.Renderer._screenQuadMesh, pass1SubContext);",
        "                    }",
        "",
        "                    //pass 2 (vertical)",
        "                    D3DDevice.ImmediateContext.ClearRenderTargetView(_renderTargetView, new SharpDX.Color4(0, 0, 0, 1));",
        "",
        "                    var pass2SubContext = new OperatorPartContext(context);",
        "                    pass2SubContext.DepthStencilView = null;",
        "                    pass2SubContext.RenderTargetView = _renderTargetView;",
        "                    pass2SubContext.Effect = _effect;",
        "                    pass2SubContext.InputLayout = context.Renderer.ScreenQuadInputLayout;",
        "                    pass2SubContext.CameraProjection = proj;",
        "                    pass2SubContext.WorldToCamera = worldToCamera;",
        "                    using (var textureView = new ShaderResourceView(D3DDevice, _pass1RenderTargetResource.Texture))",
        "                    {",
        "                        pass2SubContext.Texture0 = textureView;",
        "                        pass2SubContext.Renderer.SetupEffect(pass2SubContext);",
        "",
        "                        _effect.GetVariableByName(\"direction\").AsVector().Set(new Vector2(0, 1));",
        "",
        "                        pass2SubContext.Renderer.Render(pass2SubContext.Renderer._screenQuadMesh, pass2SubContext);",
        "                    }",
        "                }",
        "            });",
        "        }",
        "",
        "        Resource _pass1RenderTargetResource = null;",
        "        RenderTargetView _pass1RenderTargetView = null;",
        "    }",
        "}",
        ""
      ],
      "AdditionalAssemblies": []
    }
  ],
  "Operators": [],
  "Connections": [
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "efe25165-2b4e-4cf9-8c77-0bcde2d49da0"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "7227b45b-b8ed-4b60-8118-29aad14efd1b",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "f2502bc5-6f0a-455e-b425-79836718f08b",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "dac2128e-8792-49e8-950c-676c6f1e1408",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "793f434f-74fa-486d-b3bb-f5e9abdf177c",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "c675f060-1f25-4a9a-8c79-1e5ada1715d3",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "cceb5c7f-6be0-4639-8850-0570a4688c3a",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "0c119b52-8abb-4cf7-b342-cfc9168fffdf",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "12c2616e-1069-4144-82ae-69265ad3ae41",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "06f71a0a-910e-4a9e-a1a0-f753242c1b19",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "611076db-f6a1-4313-b5b2-1a5f21bca33c"
    }
  ]
}