{
  "Name": "RadialReplicate(2)",
  "_id": "9221ded1-e79d-41cf-ad06-eebeee41e9c2",
  "Namespace": "projects.kitsch.helpers",
  "Description": "This shader replicates the incoming geometry by rotating it around the y-axis. It's used for the final part of [EternalDreamOfBeaty].\r\n\r\nBecause it is derived from [Phong] it requires at least one [PointLight] above.\r\n\r\nSee [KaleidoskopExample] to learn more.\r\n",
  "Inputs": [
    {
      "Name": "Code",
      "MetaInstanceID": "fa0e96a5-ab37-4d64-a17e-b31e05e1be83",
      "DefaultValue": {
        "Type": "Text",
        "Value": [
          "float4x4 objectToWorldMatrix;\r",
          "float4x4 worldToCameraMatrix;\r",
          "float4x4 cameraToObjectMatrix; // modelview inverse\r",
          "float4x4 projMatrix;\r",
          "float4x4 textureMatrix;\r",
          "\r",
          "\r",
          "//>>> _parameters\r",
          "float NumberOfCopies;",
          "float Id;",
          "float Rotate;",
          "//<<< _parameters\r",
          "\r",
          "struct PointLight\r",
          "{\r",
          "    float4 position;\r",
          "    float4 ambient;\r",
          "    float4 diffuse;\r",
          "    float4 specular;\r",
          "    float4 attenuation;\r",
          "};\r",
          "\r",
          "struct SpotLight\r",
          "{\r",
          "    float4 ambient;\r",
          "    float4 diffuse;\r",
          "    float4 specular;\r",
          "    float constantAttenuation;\r",
          "    float linearAttenuation;\r",
          "    float quadraticAttenuation;\r",
          "    float spotCutoff;\r",
          "    float spotCosCutoff;\r",
          "    float spotExponent;\r",
          "};\r",
          "\r",
          "cbuffer FogSettings\r",
          "{\r",
          "    float4 fogColor;\r",
          "    float fogStart;\r",
          "    float fogEnd;\r",
          "    float fogScale;\r",
          "}\r",
          "\r",
          "cbuffer MaterialBuffer\r",
          "{\r",
          "    float4 materialAmbient;\r",
          "    float4 materialDiffuse;\r",
          "    float4 materialSpecular;\r",
          "    float4 materialEmission;\r",
          "    float materialShininess;\r",
          "};\r",
          "\r",
          "\r",
          "cbuffer PointLightsBuffer\r",
          "{\r",
          "    int numPointLights;\r",
          "    PointLight pointLights[3];\r",
          "};\r",
          "\r",
          "\r",
          "Texture2D txDiffuse;\r",
          "\r",
          "SamplerState samLinear\r",
          "{\r",
          "    Filter = MIN_MAG_MIP_LINEAR;\r",
          "    AddressU = Wrap;\r",
          "    AddressV = Wrap;\r",
          "};\r",
          "\r",
          "\r",
          "struct VS_IN\r",
          "{\r",
          "    float4 pos : POSITION;\r",
          "    float3 normal : NORMAL;\r",
          "    float4 col : COLOR;\r",
          "    float2 texCoord : TEXCOORD0;\r",
          "    float3 tangent : TANGENT0;\r",
          "    float3 binormal : BINORMAL0;\r",
          "};\r",
          "\r",
          "\r",
          "struct PS_IN\r",
          "{\r",
          "    float4 pos : SV_POSITION;\r",
          "    float4 posInWorld  : WORLD_POS;\r",
          "    float3 normal : NORMAL;   \r",
          "    float2 texCoord : TEXCOORD0;\r",
          "    float4 vertexColor : COLOR;\r",
          "    float3 fragPosToCamPos : POS;\r",
          "    float fogFragCoord : FALLO;\r",
          "};\r",
          "\r",
          "\r",
          "float mod(float a, float b)\r",
          "{\r",
          "    return a - b*floor(a/b);\r",
          "}\r",
          "\r",
          "float3 mod(float3 a, float b)\r",
          "{\r",
          "    return a - b*floor(a/b);\r",
          "}\r",
          "\r",
          "\r",
          "//>>> VS\r",
          "PS_IN VS( VS_IN input )",
          "{",
          "    PS_IN output = (PS_IN)0;",
          "",
          "    output.posInWorld = mul(input.pos, objectToWorldMatrix);",
          "    output.pos = mul(output.posInWorld, worldToCameraMatrix);",
          "    output.normal = mul(input.normal, (float3x3)objectToWorldMatrix);",
          "    output.fogFragCoord = abs(output.pos.z / input.pos.w);",
          "    output.pos = mul(output.pos, projMatrix);",
          "    output.texCoord = mul(float4(input.texCoord, 0, 1), textureMatrix).xy;",
          "    output.fragPosToCamPos = normalize(mul(cameraToObjectMatrix[3], objectToWorldMatrix) - output.posInWorld);",
          "    output.vertexColor = input.col;",
          "      ",
          "    return output;",
          "}",
          "//<<< VS\r",
          "\r",
          "float4 calcLightSource(float3 fragPosInWorld, int lightIdx, float3 cameraVector, float3 norm, float4 baseColor)\r",
          "{\r",
          "    float3 lightVector = pointLights[lightIdx].position - fragPosInWorld;\r",
          "    float dist = length(lightVector);\r",
          "    lightVector = normalize(lightVector);\r",
          "    float nxDir = max(0.0, dot(norm, lightVector));\r",
          "    float4 diffuse = pointLights[lightIdx].diffuse * nxDir;\r",
          "    float specularPower = 0.0;\r",
          "    if (nxDir > 0.0)\r",
          "    {\r",
          "        float3 r = reflect(-lightVector, norm);\r",
          "        float rl = max(0.0, dot(r, cameraVector));\r",
          "        specularPower = pow(rl, materialShininess);\r",
          "    }\r",
          "\r",
          "    float attenuation = 1.0 / (pointLights[lightIdx].attenuation.x +\r",
          "                               pointLights[lightIdx].attenuation.y * dist +\r",
          "                               pointLights[lightIdx].attenuation.z * dist * dist);\r",
          "    float4 color = materialAmbient * pointLights[lightIdx].ambient * attenuation +\r",
          "                   materialDiffuse * (diffuse * baseColor * attenuation) +\r",
          "                   materialSpecular * pointLights[lightIdx].specular * specularPower * attenuation;\r",
          "                   \r",
          "    return color;\r",
          "}\r",
          "\r",
          "\r",
          "\r",
          "//>>> PS\r",
          "float4 PS( PS_IN input ) : SV_Target\r",
          "{\r",
          "    float2 newTexCoords = input.texCoord;\r",
          "    float3 norm = normalize(input.normal);\r",
          "    float4 baseColor = txDiffuse.Sample(samLinear, newTexCoords);\r",
          "  \r",
          "    float4 color = float4(0, 0, 0, 1);\r",
          "    for (int lightIdx = 0; lightIdx < numPointLights; ++lightIdx)\r",
          "    {\r",
          "        color += calcLightSource(input.posInWorld, lightIdx, input.fragPosToCamPos, norm, baseColor);\r",
          "    }\r",
          "\r",
          "    float fog = (fogEnd - input.fogFragCoord) * fogScale;\r",
          "    fog = clamp(fog, 0.0, 1.0);\r",
          "    \r",
          "    float angle = atan2(input.posInWorld.z, input.posInWorld.x);\r",
          "    if( angle < 0) {\r",
          "        angle = 2*3.14+angle;\r",
          "    }\r",
          "    \r",
          "    float beta= 2*3.141578 / NumberOfCopies;\r",
          "    \r",
          "    //if (mod(angle + Rotate, beta) < beta /2) {\r",
          "    angle= 2*3.141578-angle;\r",
          "    if (angle < beta* Id || angle > beta * (Id+1)) {\r",
          "        discard;\r",
          "    }\r",
          "    \r",
          "    //color += materialEmission*baseColor;\r",
          "   \r",
          "    color.a=1;\r",
          "        \r",
          "    color= float4(lerp(fogColor.rgb, color.rgb, fog), materialDiffuse.a * baseColor.a);\r",
          "    //color.r= angle/6.1415;\r",
          "    //color.gb=0;\r",
          "    return color;    \r",
          "\r",
          "}\r",
          "//<<< PS\r",
          "\r",
          "technique10 Render\r",
          "{\r",
          "    pass P0\r",
          "    {\r",
          "        SetGeometryShader( 0 );\r",
          "        SetVertexShader( CompileShader( vs_4_0, VS() ) );\r",
          "        SetPixelShader( CompileShader( ps_4_0, PS() ) );\r",
          "    }\r",
          "} "
        ]
      },
      "MetaID": "c522a66e-3260-4692-b3e3-79fd0361fa3d",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Scene",
      "MetaInstanceID": "8a3adae4-b763-4e3c-b489-acb61a90dea6",
      "DefaultValue": {
        "Type": "Scene",
        "Value": "Framefield.Core.Scene"
      },
      "MetaID": "79122951-7bc4-4c68-b085-866eab828248",
      "IsMultiInput": "False",
      "Relevance": "Required",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "0.1",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "NumberOfCopies",
      "MetaInstanceID": "9f3c0d31-0c6d-4ac5-931e-eba7534a7aac",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "10000",
      "Scale": "0.01",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Id",
      "MetaInstanceID": "f207c97d-5de9-4aa6-96b0-6d33d47bc97f",
      "DefaultValue": {
        "Type": "Float",
        "Value": "1"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "0",
      "Max": "10000",
      "Scale": "0.01",
      "ScaleType": "Linear",
      "EnumValues": []
    },
    {
      "Name": "Rotate",
      "MetaInstanceID": "79844cfa-e4b7-4b8d-b14b-8752ca40aa0a",
      "DefaultValue": {
        "Type": "Float",
        "Value": "0"
      },
      "MetaID": "3f76dee3-3897-44ac-82d6-25ce9f53a506",
      "IsMultiInput": "False",
      "Relevance": "Optional",
      "Description": "",
      "Min": "-100000",
      "Max": "100000",
      "Scale": "1",
      "ScaleType": "Linear",
      "EnumValues": []
    }
  ],
  "Outputs": [
    {
      "Name": "Scene",
      "MetaInstanceID": "846136f8-a8aa-45ee-8f6e-562ce6fd8420",
      "MetaID": "79122951-7bc4-4c68-b085-866eab828248"
    }
  ],
  "OperatorParts": [
    {
      "MetaInstanceID": "182aa7ce-ed45-4891-ac6a-26e123ceb2bb",
      "MetaID": "0bd3efd4-6d55-4e63-988f-859ab02f5f45",
      "Name": "RadialReplicate(2)Func",
      "Version": "6588f77c-b4a3-49a9-8567-0e365754ee01",
      "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 Framefield.Core.Rendering;",
        "",
        "namespace Framefield.Core.ID0bd3efd4_6d55_4e63_988f_859ab02f5f45",
        "{",
        "    public class Class_RadialReplicate_2_ : FXSourceCodeFunction",
        "    {",
        "        //>>> _inputids",
        "        private enum InputId",
        "        {",
        "            Code = 0,",
        "            Scene = 1,",
        "            NumberOfCopies = 2,",
        "            Id = 3,",
        "            Rotate = 4",
        "        }",
        "        //<<< _inputids",
        "        #region Renderer",
        "        public class Renderer : BaseRenderer",
        "        {",
        "            public override void SetupEffect(OperatorPartContext context)",
        "            {",
        "                base.SetupEffect(context);",
        "                try",
        "                {",
        "                    SetupMaterialConstBuffer(context);",
        "                    SetupFogSettingsConstBuffer(context);",
        "                    SetupPointLightsConstBuffer(context);",
        "                }",
        "                catch (Exception e)",
        "                {",
        "                    Logger.Error(ParentFunc,\"Error building constant buffer: {0} - Source: {1}\", e.Message, e.Source);",
        "                }",
        "            }",
        "            public OperatorPart.Function ParentFunc{get;set;}",
        "        }",
        "        #endregion",
        "",
        "        public Class_RadialReplicate_2_()",
        "        {",
        "            _renderer = new Renderer(){ParentFunc=this};",
        "        }",
        "",
        "        public override void Dispose()",
        "        {",
        "            Utilities.DisposeObj(ref _renderer);",
        "            base.Dispose();",
        "        }",
        "",
        "        bool _firstEval = true;",
        "        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)",
        "        {",
        "            // >>> _params",
        "            var Code = inputs[(int)InputId.Code].Eval(context).Text;",
        "            var Scene = inputs[(int)InputId.Scene];",
        "            var NumberOfCopies = inputs[(int)InputId.NumberOfCopies].Eval(context).Value;",
        "            var Id = inputs[(int)InputId.Id].Eval(context).Value;",
        "            var Rotate = inputs[(int)InputId.Rotate].Eval(context).Value;",
        "            // <<< _params",
        "",
        "            if (_firstEval)",
        "            {",
        "                for (int i = 0; i < NumCodes(); ++i)",
        "                    Compile(i);",
        "                _firstEval = false;",
        "                Changed = true;",
        "            }",
        "",
        "            using (new PropertyStasher<OperatorPartContext>(context, \"Effect\", \"Renderer\"))",
        "            {",
        "                //_effect.GetVariableByName(\"Range\").AsVector().Set(new Vector2(RangeX, RangeY));",
        "                _effect.GetVariableByName(\"NumberOfCopies\").AsScalar().Set(NumberOfCopies);",
        "                _effect.GetVariableByName(\"Id\").AsScalar().Set(Id);",
        "                _effect.GetVariableByName(\"Rotate\").AsScalar().Set(0);",
        "                context.Effect = _effect;",
        "                context.Renderer = _renderer;",
        "                ",
        "                var prevTransform = context.ObjectTWorld;",
        "                for(var i=0; i < NumberOfCopies; i++) {",
        "                    /*",
        "                    var transform = prevTransform * Matrix.Transformation(new Vector3(), ",
        "                                new Quaternion(), ",
        "                                new Vector3(1*i,1,1), ",
        "                                new Vector3(), ",
        "                                new Quaternion(), ",
        "                                new Matrix.Identity());",
        "                    */",
        "                    var r = Matrix.Identity;",
        "                    Matrix.RotationY( (float)(i*2*Math.PI/NumberOfCopies  +  ( -90+90/(NumberOfCopies/2) ) /360*Math.PI*2 )  , out r);                    ",
        "",
        "                    var t= prevTransform * Matrix.Identity;",
        "",
        "",
        "                    if( i % 2 > 0) {",
        "                        t = t * Matrix.Scaling(-1 , 1,1);",
        "                    }",
        "                    t *= r;",
        "                    ",
        "                    context.ObjectTWorld = t;",
        "                    ",
        "                    _effect.GetVariableByName(\"Id\").AsScalar().Set(i);",
        "                    ",
        "                    Scene.Eval(context);",
        "                }",
        "                    ",
        "                //transform *= prevTransform; ",
        "                //SceneInput.Connections[i%SceneInput.Connections.Count].Eval(context);",
        "                context.ObjectTWorld = prevTransform;",
        "                ",
        "                //SceneInput.Connections[i%SceneInput.Connections.Count].Eval(context);",
        "                //context.ObjectTWorld = prevTransform;",
        "",
        "",
        "            }",
        "",
        "            /*",
        "            //>>> _setup",
        "            {",
        "                _effect.GetVariableByName(\"RenderTargetSize\").AsVector().Set(new Vector2(_usedViewport.Width, _usedViewport.Height));",
        "                _effect.GetVariableByName(\"NumberOfCopies\").AsScalar().Set(NumberOfCopies);",
        "                _effect.GetVariableByName(\"Id\").AsScalar().Set(Id);",
        "                _effect.GetVariableByName(\"Rotate\").AsScalar().Set(Rotate);",
        "            //<<< _setup            ",
        "            */",
        "            return context;",
        "        }",
        "",
        "        Renderer _renderer;",
        "    }",
        "}",
        "",
        "",
        ""
      ],
      "AdditionalAssemblies": []
    }
  ],
  "Operators": [],
  "Connections": [
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "182aa7ce-ed45-4891-ac6a-26e123ceb2bb",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "846136f8-a8aa-45ee-8f6e-562ce6fd8420"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "fa0e96a5-ab37-4d64-a17e-b31e05e1be83",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "182aa7ce-ed45-4891-ac6a-26e123ceb2bb"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "8a3adae4-b763-4e3c-b489-acb61a90dea6",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "182aa7ce-ed45-4891-ac6a-26e123ceb2bb"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "9f3c0d31-0c6d-4ac5-931e-eba7534a7aac",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "182aa7ce-ed45-4891-ac6a-26e123ceb2bb"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "f207c97d-5de9-4aa6-96b0-6d33d47bc97f",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "182aa7ce-ed45-4891-ac6a-26e123ceb2bb"
    },
    {
      "SourceOp": "00000000-0000-0000-0000-000000000000",
      "SourceOpPart": "79844cfa-e4b7-4b8d-b14b-8752ca40aa0a",
      "TargetOp": "00000000-0000-0000-0000-000000000000",
      "TargetOpPart": "182aa7ce-ed45-4891-ac6a-26e123ceb2bb"
    }
  ]
}