{
  "Name": "PerlinNoise",
  "_id": "34bc4620-7f89-4a28-b3dd-46bdd0fcaddf",
  "Namespace": "lib.image.generate",
  "Description": "",
  "Inputs": [
    {
      "Name": "Code",
      "MetaInstanceID": "0d74d949-a6fd-412c-94e4-95e4e71e18fb",
      "DefaultValue": {
        "Type": "Text",
        "Value": [
          "//>>> _common parameters\r",
          "float4x4 objectToWorldMatrix;",
          "float4x4 worldToCameraMatrix;",
          "float4x4 projMatrix;",
          "Texture2D txDiffuse;",
          "float2 RenderTargetSize;",
          "//<<< _common parameters\r",
          "\r",
          "//>>> _parameters\r",
          "float Scale;",
          "float NumOctaves;",
          "float Seed;",
          "//<<< _parameters\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 float3 grad3[] = {{1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},\r",
          "                         {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},\r",
          "                         {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}};\r",
          "\r",
          "\r",
          "cbuffer PermutationTable\r",
          "{ \r",
          "    int perm[512]; \r",
          "};\r",
          "\r",
          "\r",
          "\r",
          "int fastfloor(float x) \r",
          "{\r",
          "    return x > 0 ? (int) x : (int) x - 1;\r",
          "}\r",
          "\r",
          "float fade(float t) \r",
          "{\r",
          "    // polynomal 5th grade in order that 2nd deriative is continous\r",
          "    return t*t*t*(t*(t*6-15)+10); \r",
          " \r",
          "    // faster hermite interpolation but no continous 2nd deriative\r",
          "    return t*t*(3 - 2*t);\r",
          "}\r",
          "\r",
          "float noise2d(float x, float y, int per) \r",
          "{\r",
          "    // find unit grid cell containing point\r",
          "    int X = fastfloor(x);\r",
          "    int Y = fastfloor(y);\r",
          "\r",
          "    // get relative xy coordinates of point within that cell\r",
          "    x = x - X;\r",
          "    y = y - Y;\r",
          "\r",
          "    // wrap the integer cells at 255 (smaller integer period can be introduced here)\r",
          "    X = X & 255;\r",
          "    Y = Y & 255;\r",
          "\r",
          "    // Calculate a set of eight hashed gradient indices\r",
          "    int gi00 = perm[(X    )%per + perm[(Y    )%per]] % 12;\r",
          "    int gi01 = perm[(X    )%per + perm[(Y + 1)%per]] % 12;\r",
          "    int gi10 = perm[(X + 1)%per + perm[(Y    )%per]] % 12;\r",
          "    int gi11 = perm[(X + 1)%per + perm[(Y + 1)%per]] % 12;\r",
          "    // The gradients of each corner are now:\r",
          "    // g00 = grad2[gi00];\r",
          "    // g01 = grad2[gi01];\r",
          "    // g10 = grad2[gi10];\r",
          "    // g11 = grad2[gi11];\r",
          "\r",
          "    // Calculate noise contributions from each of the eight corners\r",
          "    float n00 = dot(grad3[gi00], float3(x,     y,     0));\r",
          "    float n10 = dot(grad3[gi10], float3(x - 1, y,     0));\r",
          "    float n01 = dot(grad3[gi01], float3(x,     y - 1, 0));\r",
          "    float n11 = dot(grad3[gi11], float3(x - 1, y - 1, 0));\r",
          "    \r",
          "    // Compute the fade curve value for each of x, y, z\r",
          "    float u = fade(x);\r",
          "    float v = fade(y);\r",
          "    \r",
          "    // Interpolate along x the contributions from each of the corners\r",
          "    float nx0 = lerp(n00, n10, u);\r",
          "    float nx1 = lerp(n01, n11, u);\r",
          "\r",
          "    // Interpolate the two results along y for final noise value\r",
          "    float nxy = lerp(nx0, nx1, v);\r",
          "\r",
          "    return nxy;\r",
          "}\r",
          "\r",
          "\r",
          "float fBm(float x, float y, float scale, int per, int octaves)\r",
          "{\r",
          "    float sum = 0;\r",
          "    for (int i = 0; i < octaves; ++i)\r",
          "    {\r",
          "        float s = 2 << i;\r",
          "        sum += noise2d(x*scale*s, y*scale*s, s)/s;\r",
          "    }    \r",
          "    return sum;\r",
          "}\r",
          "\r",
          "\r",
          "float4 PS(PS_IN input) : SV_Target\r",
          "{\r",
          "    float f = fBm(input.texCoord.x, input.texCoord.y, Scale, 2, NumOctaves) + 0.5;\r",
          "\r",
          "    return float4(f, f, f, 1);\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": "Scale",
      "MetaInstanceID": "e1e56494-22ba-44d8-bb54-feec33e43d9b",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0.001",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "NumOctaves",
      "MetaInstanceID": "4431d3cd-7f04-4fa7-9108-ecd834495389",
      "DefaultValue": {
        "Type": "Float",
        "Value": "6"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "1",
      "Max": "10",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Seed",
      "MetaInstanceID": "4081e2a3-a3c1-4b2a-a4d9-daf483afc620",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "100000",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    }
  ],
  "Outputs": [
    {
      "Name": "Image",
      "MetaInstanceID": "dff33e19-41aa-4ea9-a0cd-6e3069a8eac7",
      "MetaID": "9848060d-fd84-45b0-b658-d0d531c61dab"
    }
  ],
  "OperatorParts": [
    {
      "MetaInstanceID": "a16a05db-439c-4417-98a4-b1d48f16e509",
      "MetaID": "c7ee4db3-b926-415e-8158-a215b63d3635",
      "Name": "PerlinNoiseFunc",
      "Version": "00c0280c-a0f2-479e-9222-462e3b96782d",
      "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 System.Runtime.InteropServices;",
        "using Buffer = SharpDX.Direct3D11.Buffer;",
        "",
        "namespace Framefield.Core.IDc7ee4db3_b926_415e_8158_a215b63d3635",
        "{",
        "    public class Class_PerlinNoise : FXImageFunction",
        "    {",
        "        //>>> _inputids",
        "        private enum InputId",
        "        {",
        "            Code = 0,",
        "            Scale = 1,",
        "            NumOctaves = 2,",
        "            Seed = 3",
        "        }",
        "        //<<< _inputids",
        "",
        "        int[] _permutationTable = new int[512];",
        "        int _permutaionTableSize = 512 * 4 * 4; // 512 entries * intSize * 16byte alignment padding",
        "        Buffer _permutationTableConstBuffer;",
        "",
        "        public override void Dispose()",
        "        {",
        "            Utilities.DisposeObj(ref _permutationTableConstBuffer);",
        "            base.Dispose();",
        "        }",
        "",
        "        private void CalcPermutationTable(int seed)",
        "        {",
        "            var random = new Random(seed);",
        "            for (int i = 0; i < 256; ++i)",
        "            {",
        "                var value = random.Next(256);",
        "                _permutationTable[i] = value;",
        "                _permutationTable[i + 256] = value;",
        "            }",
        "        }",
        "",
        "        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 Scale = inputs[(int)InputId.Scale].Eval(context).Value;",
        "                var NumOctaves = inputs[(int)InputId.NumOctaves].Eval(context).Value;",
        "                var Seed = inputs[(int)InputId.Seed].Eval(context).Value;",
        "                //<<< _params",
        "",
        "                ClearRenderTarget(context, new SharpDX.Color4(0, 0, 0, 1));",
        "",
        "                CalcPermutationTable((int)Seed);",
        "",
        "                using (var data = new SharpDX.DataStream(_permutaionTableSize, true, true))",
        "                {",
        "                    foreach (var permutationEnty in _permutationTable)",
        "                    {",
        "                        data.Write(permutationEnty);",
        "                        data.Write(new Vector3(0, 0, 0)); // padding values",
        "                    }",
        "                    data.Position = 0;",
        "",
        "                    if (_permutationTableConstBuffer == null)",
        "                    {",
        "                        var bufferDesc = new BufferDescription",
        "                        {",
        "                            Usage = ResourceUsage.Default,",
        "                            SizeInBytes = _permutaionTableSize,",
        "                            BindFlags = BindFlags.ConstantBuffer",
        "                        };",
        "                        _permutationTableConstBuffer = new Buffer(context.D3DDevice, data, bufferDesc);",
        "                    }",
        "                    else",
        "                    {",
        "                        context.D3DDevice.ImmediateContext.UpdateSubresource(new DataBox(data.DataPointer, 0, 0), _permutationTableConstBuffer, 0);",
        "                    }",
        "                }",
        "                var constBuffer = _effect.GetConstantBufferByName(\"PermutationTable\");",
        "                if (constBuffer != null && constBuffer.IsValid)",
        "                {",
        "                    constBuffer.SetConstantBuffer(_permutationTableConstBuffer);",
        "                }",
        "",
        "                //>>> _setup",
        "                {",
        "                    _effect.GetVariableByName(\"RenderTargetSize\").AsVector().Set(new Vector2(_usedViewport.Width, _usedViewport.Height));",
        "                    _effect.GetVariableByName(\"Scale\").AsScalar().Set(Scale);",
        "                    _effect.GetVariableByName(\"NumOctaves\").AsScalar().Set(NumOctaves);",
        "                    _effect.GetVariableByName(\"Seed\").AsScalar().Set(Seed);",
        "                //<<< _setup",
        "",
        "                    Render(context);",
        "",
        "                //>>> _cleanup",
        "                }",
        "                //<<< _cleanup",
        "            });",
        "        }",
        "",
        "    }",
        "}",
        "",
        ""
      ],
      "AdditionalAssemblies": []
    }
  ],
  "Operators": [],
  "Connections": [
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "a16a05db-439c-4417-98a4-b1d48f16e509",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "dff33e19-41aa-4ea9-a0cd-6e3069a8eac7"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "0d74d949-a6fd-412c-94e4-95e4e71e18fb",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "a16a05db-439c-4417-98a4-b1d48f16e509"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "e1e56494-22ba-44d8-bb54-feec33e43d9b",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "a16a05db-439c-4417-98a4-b1d48f16e509"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "4431d3cd-7f04-4fa7-9108-ecd834495389",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "a16a05db-439c-4417-98a4-b1d48f16e509"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "4081e2a3-a3c1-4b2a-a4d9-daf483afc620",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "a16a05db-439c-4417-98a4-b1d48f16e509"
    }
  ]
}