Пример #1
0
        public ComputeEffectNode(NodeContext nodeContext, EffectNodeDescription description) : base(nodeContext, description)
        {
            graphicsDevice = description.Factory.DeviceManager.GraphicsDevice;
            instance       = new DynamicEffectInstance("ComputeEffectShader");
            // TODO: Same code as in description
            instance.Parameters.Set(ComputeEffectShaderKeys.ComputeShaderName, description.Name);
            instance.Parameters.Set(ComputeEffectShaderKeys.ThreadNumbers, new Int3(1));
            instance.Initialize(description.Factory.ServiceRegistry);
            instance.UpdateEffect(graphicsDevice);
            parameters     = instance.Parameters;
            Inputs         = description.CreateNodeInputs(this, parameters);
            Outputs        = description.CreateNodeOutputs(this, parameters);
            perFrameParams = parameters.GetWellKnownParameters(WellKnownParameters.PerFrameMap).ToArray();
            perViewParams  = parameters.GetWellKnownParameters(WellKnownParameters.PerViewMap).ToArray();
            perDrawParams  = parameters.GetWellKnownParameters(WellKnownParameters.PerDrawMap).ToArray();
            if (perDrawParams.Length > 0)
            {
                worldPin = Inputs.OfType <ConvertedValueParameterPin <Matrix, SharpDX.Matrix> >().FirstOrDefault(p => p.Key == TransformationKeys.World);
            }

            Inputs.SelectPin(EffectNodeDescription.ComputeDispatchCountInput, ref dispatchCountPin);
            Inputs.SelectPin(EffectNodeDescription.ComputeThreadNumbersInput, ref threadNumbersPin);
            Inputs.SelectPin(EffectNodeDescription.ComputeIterationCountInput, ref iterationCountPin);
            Inputs.SelectPin(EffectNodeDescription.ParameterSetterInput, ref parameterSetterPin);
            Inputs.SelectPin(EffectNodeDescription.ComputeIterationParameterSetterInput, ref iterationParameterSetterPin);
            Inputs.SelectPin(EffectNodeDescription.ComputeEnabledInput, ref enabledPin);
        }
Пример #2
0
        private void Draw3D([NotNull] RenderDrawContext context, [NotNull] RenderView renderView, [NotNull] RenderBackground renderBackground)
        {
            var graphicsDevice = context.GraphicsDevice;
            var destination    = new RectangleF(0, 0, 1, 1);

            var texture = renderBackground.Texture;

            // Setup the effect depending on the type of texture
            if (renderBackground.Texture.ViewDimension == TextureDimension.Texture2D)
            {
                skyboxTextureEffect.UpdateEffect(graphicsDevice);
                spriteBatch.Begin(context.GraphicsContext, SpriteSortMode.FrontToBack, BlendStates.Opaque, null, DepthStencilStates.DepthRead, null, skyboxTextureEffect);
                spriteBatch.Parameters.Set(SkyboxShaderTextureKeys.Texture, renderBackground.Texture);
            }
            else if (renderBackground.Texture.ViewDimension == TextureDimension.TextureCube)
            {
                skyboxCubemapEffect.UpdateEffect(graphicsDevice);
                spriteBatch.Begin(context.GraphicsContext, SpriteSortMode.FrontToBack, BlendStates.Opaque, null, DepthStencilStates.DepthRead, null, skyboxCubemapEffect);
                spriteBatch.Parameters.Set(SkyboxShaderCubemapKeys.CubeMap, renderBackground.Texture);
            }
            else
            {
                return; // not supported for the moment.
            }
            spriteBatch.Parameters.Set(SkyboxShaderBaseKeys.Intensity, renderBackground.Intensity);
            spriteBatch.Parameters.Set(SkyboxShaderBaseKeys.ViewInverse, Matrix.Invert(renderView.View));
            spriteBatch.Parameters.Set(SkyboxShaderBaseKeys.ProjectionInverse, Matrix.Invert(renderView.Projection));
            spriteBatch.Parameters.Set(SkyboxShaderBaseKeys.SkyMatrix, Matrix.Invert(Matrix.RotationQuaternion(renderBackground.Rotation)));
            spriteBatch.Draw(texture, destination, null, Color.White, 0, Vector2.Zero, layerDepth: -0.5f);
            spriteBatch.End();
        }
Пример #3
0
        protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
        {
            var graphicsDevice  = drawContext.GraphicsDevice;
            var graphicsContext = drawContext.GraphicsContext;
            var commandList     = drawContext.GraphicsContext.CommandList;

            myCustomShader.UpdateEffect(graphicsDevice);
            var normal = new Vector3(1, 0, 0);

            VertexBuffer = Buffer.New(graphicsDevice, new[] { new VertexPositionNormalColor(new Vector3(-0.5f, -0.5f, 0.5f), normal, Color.Red), new VertexPositionNormalColor(new Vector3(0, 0.4f, -0.5f), normal, Color.Red), new VertexPositionNormalColor(new Vector3(10, 10f, 0f), normal, Color.Red), }, BufferFlags.VertexBuffer, GraphicsResourceUsage.Immutable);



            drawContext.CommandList.Clear(drawContext.CommandList.RenderTarget, Color.Green);
            drawContext.CommandList.Clear(drawContext.CommandList.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer);

            myCustomShader.Parameters.Set(TransformationKeys.WorldViewProjection, WorldMatrix);
            myCustomShader.Parameters.Set(test_shader1Keys.Color, Color.Red);

            pipelineState.State.RootSignature  = myCustomShader.RootSignature;
            pipelineState.State.EffectBytecode = myCustomShader.Effect.Bytecode;
            pipelineState.State.Output.CaptureState(commandList);
            pipelineState.Update();
            ;
            commandList.SetPipelineState(pipelineState.CurrentState);

            myCustomShader.Apply(graphicsContext);

            commandList.SetVertexBuffer(0, VertexBuffer, 0, VertexDeclaration.VertexStride);
            commandList.Draw(3);
        }
Пример #4
0
        private void Draw2D(RenderDrawContext context, RenderBackground renderBackground)
        {
            var target         = context.CommandList.RenderTarget;
            var graphicsDevice = context.GraphicsDevice;
            var destination    = new RectangleF(0, 0, 1, 1);

            var texture             = renderBackground.Texture;
            var textureIsLoading    = texture.ViewType == ViewType.Full && texture.FullQualitySize.Width != texture.ViewWidth;
            var textureSize         = textureIsLoading ? texture.FullQualitySize: new Size3(texture.ViewWidth, texture.ViewHeight, texture.ViewDepth);
            var imageBufferMinRatio = Math.Min(textureSize.Width / (float)target.ViewWidth, textureSize.Height / (float)target.ViewHeight);
            var sourceSize          = new Vector2(target.ViewWidth * imageBufferMinRatio, target.ViewHeight * imageBufferMinRatio);
            var source = new RectangleF((textureSize.Width - sourceSize.X) / 2, (textureSize.Height - sourceSize.Y) / 2, sourceSize.X, sourceSize.Y);

            if (textureIsLoading)
            {
                var verticalRatio   = texture.ViewHeight / (float)textureSize.Height;
                var horizontalRatio = texture.ViewWidth / (float)textureSize.Width;
                source.X      *= horizontalRatio;
                source.Width  *= horizontalRatio;
                source.Y      *= verticalRatio;
                source.Height *= verticalRatio;
            }

            backgroundEffect.UpdateEffect(graphicsDevice);
            spriteBatch.Begin(context.GraphicsContext, SpriteSortMode.FrontToBack, BlendStates.Opaque, graphicsDevice.SamplerStates.LinearClamp, DepthStencilStates.DepthRead, null, backgroundEffect);
            spriteBatch.Parameters.Set(BackgroundShaderKeys.Intensity, renderBackground.Intensity);
            spriteBatch.Draw(texture, destination, source, Color.White, 0, Vector2.Zero, layerDepth: -0.5f);
            spriteBatch.End();
        }
Пример #5
0
 public void Update()
 {
     if (instance.UpdateEffect(graphicsDevice))
     {
         foreach (var p in Inputs.OfType <ParameterPin>())
         {
             p.Update(parameters);
         }
     }
 }
Пример #6
0
 protected override void DrawImpl()
 {
     skyboxEffect.UpdateEffect(DrawContext.GraphicsDevice);
     spriteBatch.Begin(DrawContext.GraphicsContext, depthStencilState: DepthStencilStates.None, effect: skyboxEffect);
     spriteBatch.Parameters.Set(SkyboxShaderTextureKeys.Texture, inputTexture);
     spriteBatch.Parameters.Set(SkyboxShaderBaseKeys.Intensity, 1);
     spriteBatch.Parameters.Set(SkyboxShaderBaseKeys.ViewInverse, Matrix.Invert(Camera.ViewMatrix));
     spriteBatch.Parameters.Set(SkyboxShaderBaseKeys.ProjectionInverse, Matrix.Invert(Camera.ProjectionMatrix));
     spriteBatch.Parameters.Set(SkyboxShaderBaseKeys.SkyMatrix, Matrix.Identity);
     spriteBatch.Draw(inputTexture, new RectangleF(0, 0, 1, 1), null, Color.White, 0, Vector2.Zero);
     spriteBatch.End();
 }
Пример #7
0
        public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            // First do everything that doesn't change per individual render object
            var graphicsDevice  = context.GraphicsDevice;
            var graphicsContext = context.GraphicsContext;
            var commandList     = context.GraphicsContext.CommandList;

            // Refresh shader, might have changed during runtime
            _decalShader.UpdateEffect(graphicsDevice);

            // Set common shader parameters if needed
            _decalShader.Parameters.Set(TransformationKeys.ViewProjection, renderView.ViewProjection);
            _decalShader.Parameters.Set(TransformationKeys.ViewInverse, Matrix.Invert(renderView.View));

            // Important to release it at the end of the draw, otherwise you'll run out of memory!
            //var depthStencil = context.Resolver.ResolveDepthStencil(commandList.DepthStencilBuffer);
            var depthStencil = context.Resolver.ResolveDepthStencil(graphicsDevice.Presenter.DepthStencilBuffer);       // Must use the Presenter's depth buffer, otherwise it won't appear in the Game Studio

            _decalShader.Parameters.Set(DepthBaseKeys.DepthStencil, depthStencil);

            _decalShader.Parameters.Set(CameraKeys.ViewSize, renderView.ViewSize);
            _decalShader.Parameters.Set(CameraKeys.ZProjection, CameraKeys.ZProjectionACalculate(renderView.NearClipPlane, renderView.FarClipPlane));
            _decalShader.Parameters.Set(CameraKeys.NearClipPlane, renderView.NearClipPlane);
            _decalShader.Parameters.Set(CameraKeys.FarClipPlane, renderView.FarClipPlane);

            for (int index = startIndex; index < endIndex; index++)
            {
                var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode;
                var renderNode          = GetRenderNode(renderNodeReference);
                var decalRendObj        = (DecalRenderObject)renderNode.RenderObject;

                if (decalRendObj.RenderCube == null)
                {
                    continue;   // Next render object
                }

                // Assign shader parameters
                _decalShader.Parameters.Set(TransformationKeys.WorldInverse, Matrix.Invert(decalRendObj.WorldMatrix));
                _decalShader.Parameters.Set(TransformationKeys.WorldViewProjection, decalRendObj.WorldMatrix * renderView.ViewProjection);
                _decalShader.Parameters.Set(TransformationKeys.WorldView, decalRendObj.WorldMatrix * renderView.View);
                _decalShader.Parameters.Set(DecalShaderKeys.DecalTexture, decalRendObj.Texture);
                _decalShader.Parameters.Set(DecalShaderKeys.TextureScale, decalRendObj.TextureScale);
                _decalShader.Parameters.Set(DecalShaderKeys.DecalColor, decalRendObj.Color);

                decalRendObj.RenderCube.Draw(graphicsContext, _decalShader);
            }

            context.Resolver.ReleaseDepthStenctilAsShaderResource(depthStencil);
        }
Пример #8
0
        private void DrawCube(RenderDrawContext context, RenderView renderView, RenderBackground renderBackground)
        {
            var graphicsDevice = context.GraphicsDevice;
            var destination    = new RectangleF(0, 0, 1, 1);

            var texture = renderBackground.Texture;

            skyboxBackgroundEffect.UpdateEffect(graphicsDevice);
            spriteBatch.Begin(context.GraphicsContext, SpriteSortMode.FrontToBack, BlendStates.Opaque, graphicsDevice.SamplerStates.LinearClamp, DepthStencilStates.DepthRead, null, skyboxBackgroundEffect);
            spriteBatch.Parameters.Set(SkyboxShaderKeys.Intensity, renderBackground.Intensity);
            spriteBatch.Parameters.Set(SkyboxShaderKeys.ViewInverse, Matrix.Invert(renderView.View));
            spriteBatch.Parameters.Set(SkyboxShaderKeys.ProjectionInverse, Matrix.Invert(renderView.Projection));
            spriteBatch.Parameters.Set(SkyboxShaderKeys.SkyMatrix, Matrix.Invert(Matrix.RotationQuaternion(renderBackground.Rotation)));
            spriteBatch.Parameters.Set(SkyboxShaderKeys.CubeMap, renderBackground.Texture);
            spriteBatch.Draw(texture, destination, null, Color.White, 0, Vector2.Zero, layerDepth: -0.5f);
            spriteBatch.End();
        }
        public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            // First do everything that doesn't change per individual render object
            var graphicsDevice  = context.GraphicsDevice;
            var graphicsContext = context.GraphicsContext;
            var commandList     = context.GraphicsContext.CommandList;

            // Refresh shader, might have changed during runtime
            myCustomShader.UpdateEffect(graphicsDevice);

            // Set common shader parameters if needed
            //myCustomShader.Parameters.Set(TransformationKeys.ViewProjection, renderView.ViewProjection);

            for (int index = startIndex; index < endIndex; index++)
            {
                var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode;
                var renderNode          = GetRenderNode(renderNodeReference);
                var myRenderObject      = (MyRenderObject)renderNode.RenderObject;

                if (myRenderObject.VertexBuffer == null)
                {
                    continue; //next render object
                }
                // Assign shader parameters
                myCustomShader.Parameters.Set(TransformationKeys.WorldViewProjection, myRenderObject.WorldMatrix * renderView.ViewProjection);
                myCustomShader.Parameters.Set(TexturingKeys.Texture0, myRenderObject.Texture);
                myCustomShader.Parameters.Set(MyCustomShaderKeys.TextureScale, myRenderObject.TextureScale);
                myCustomShader.Parameters.Set(MyCustomShaderKeys.Color, myRenderObject.Color);

                // Prepare pipeline state
                pipelineState.State.RootSignature  = myCustomShader.RootSignature;
                pipelineState.State.EffectBytecode = myCustomShader.Effect.Bytecode;
                pipelineState.State.Output.CaptureState(commandList);
                pipelineState.Update();
                commandList.SetPipelineState(pipelineState.CurrentState);

                // Apply the effect
                myCustomShader.Apply(graphicsContext);

                // Set vertex buffer and draw
                commandList.SetVertexBuffer(0, myRenderObject.VertexBuffer, 0, MyRenderObject.VertexDeclaration.VertexStride);
                commandList.Draw(MyRenderObject.VertexCount, 0);
            }
        }
Пример #10
0
 public EffectNode(NodeContext nodeContext, EffectNodeDescription description) : base(nodeContext, description)
 {
     graphicsDevice = description.Factory.DeviceManager.GraphicsDevice;
     instance       = new DynamicEffectInstance(description.Name);
     instance.Initialize(description.Factory.ServiceRegistry);
     instance.UpdateEffect(graphicsDevice);
     parameters     = instance.Parameters;
     Inputs         = description.CreateNodeInputs(this, parameters);
     Outputs        = description.CreateNodeOutputs(this, parameters);
     perFrameParams = parameters.GetWellKnownParameters(WellKnownParameters.PerFrameMap).ToArray();
     perViewParams  = parameters.GetWellKnownParameters(WellKnownParameters.PerViewMap).ToArray();
     perDrawParams  = parameters.GetWellKnownParameters(WellKnownParameters.PerDrawMap).ToArray();
     if (perDrawParams.Length > 0)
     {
         worldPin = Inputs.OfType <ConvertedValueParameterPin <Matrix, SharpDX.Matrix> >().FirstOrDefault(p => p.Key == TransformationKeys.World);
     }
     if (Inputs.Length > 0)
     {
         customParameterSetterPin = Inputs[Inputs.Length - 1] as Pin <Action <ParameterCollection, RenderView, RenderDrawContext> >;
     }
 }
Пример #11
0
        void ILowLevelAPIRender.Draw(RenderContext renderContext, RenderDrawContext drawContext, RenderView renderView, RenderViewStage renderViewStage, CommandList commandList)
        {
            if (!enabledPin.Value)
            {
                return;
            }

            try
            {
                var pipelineState = this.pipelineState ?? (this.pipelineState = new MutablePipelineState(renderContext.GraphicsDevice));

                // TODO1: PerFrame could be done in Update if we'd have access to frame time
                // TODO2: This code can be optimized by using parameter accessors and not parameter keys
                parameters.SetPerFrameParameters(perFrameParams, drawContext.RenderContext);
                parameters.SetPerViewParameters(perViewParams, renderView);

                if (worldPin != null)
                {
                    var world = worldPin.ShaderValue;
                    parameters.SetPerDrawParameters(perDrawParams, renderView, ref world);
                }

                // Set permutation parameters before updating the effect (needed by compiler)
                parameters.Set(ComputeEffectShaderKeys.ThreadNumbers, threadNumbersPin.Value);

                // Give user chance to override
                parameterSetterPin?.Value.Invoke(parameters, renderView, drawContext);

                if (instance.UpdateEffect(renderContext.GraphicsDevice) || pipelineStateDirty)
                {
                    threadGroupCountAccessor = parameters.GetAccessor(ComputeShaderBaseKeys.ThreadGroupCountGlobal);
                    foreach (var p in Inputs.OfType <ParameterPin>())
                    {
                        p.Update(parameters);
                    }
                    pipelineState.State.SetDefaults();
                    pipelineState.State.RootSignature  = instance.RootSignature;
                    pipelineState.State.EffectBytecode = instance.Effect.Bytecode;
                    pipelineState.Update();
                    pipelineStateDirty = false;
                }

                // Apply pipeline state
                commandList.SetPipelineState(pipelineState.CurrentState);

                // Set thread group count as provided by input pin
                var threadGroupCount = dispatchCountPin.Value;
                parameters.Set(ComputeShaderBaseKeys.ThreadGroupCountGlobal, threadGroupCount);

                // TODO: This can be optimized by uploading only parameters from the PerDispatch groups - look in Xenkos RootEffectRenderFeature
                var iterationCount = Math.Max(iterationCountPin.Value, 1);
                for (int i = 0; i < iterationCount; i++)
                {
                    // Give user chance to override
                    iterationParameterSetterPin.Value?.Invoke(parameters, renderView, drawContext, i);

                    // The thread group count can be set for each dispatch
                    threadGroupCount = parameters.Get(threadGroupCountAccessor);

                    // Upload the parameters
                    instance.Apply(drawContext.GraphicsContext);

                    // Draw a full screen quad
                    commandList.Dispatch(threadGroupCount.X, threadGroupCount.Y, threadGroupCount.Z);
                }
            }
            catch (Exception e)
            {
                var re = new RuntimeException(e.InnermostException(), this);
                RuntimeGraph.ReportException(re);
            }
        }
        public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage)
        {
            shader.UpdateEffect(context.GraphicsDevice);

            foreach (var renderNode in renderViewStage.SortedRenderNodes)
            {
                var renderMesh = renderNode.RenderObject as RenderMesh;
                if (renderMesh == null)
                {
                    continue;
                }

                // get wireframe script
                WireframeScript wireframeScript = null;
                if (renderMesh.Source is ModelComponent)
                {
                    wireframeScript = (renderMesh.Source as ModelComponent).Entity.Get <WireframeScript>();
                }

                if (wireframeScript == null || !wireframeScript.Enabled)
                {
                    continue;
                }

                MeshDraw drawData = renderMesh.ActiveMeshDraw;

                // bind VB
                for (int slot = 0; slot < drawData.VertexBuffers.Length; slot++)
                {
                    var vertexBuffer = drawData.VertexBuffers[slot];
                    context.CommandList.SetVertexBuffer(slot, vertexBuffer.Buffer, vertexBuffer.Offset, vertexBuffer.Stride);
                }

                // set shader parameters
                shader.Parameters.Set(TransformationKeys.WorldViewProjection, renderMesh.World * renderView.ViewProjection); // matrix
                shader.Parameters.Set(TransformationKeys.WorldScale, new Vector3(ScaleAdjust + 1.0f));                       // increase size to avoid z-fight
                shader.Parameters.Set(SinglePassWireframeShaderKeys.Viewport, new Vector4(context.RenderContext.RenderView.ViewSize, 0, 0));
                shader.Parameters.Set(SinglePassWireframeShaderKeys.LineWidth, wireframeScript.LineWidth);
                shader.Parameters.Set(SinglePassWireframeShaderKeys.LineColor, (Vector3)wireframeScript.Color);

                // prepare pipeline state
                pipelineState.State.RootSignature  = shader.RootSignature;
                pipelineState.State.EffectBytecode = shader.Effect.Bytecode;
                pipelineState.State.PrimitiveType  = drawData.PrimitiveType;

                pipelineState.State.Output.CaptureState(context.CommandList);
                pipelineState.Update();

                context.CommandList.SetIndexBuffer(drawData.IndexBuffer.Buffer, drawData.IndexBuffer.Offset, drawData.IndexBuffer.Is32Bit);
                context.CommandList.SetPipelineState(pipelineState.CurrentState);

                // apply the effect
                shader.Apply(context.GraphicsContext);

                if (drawData.IndexBuffer != null)
                {
                    context.CommandList.DrawIndexed(drawData.DrawCount, drawData.StartLocation);
                }
                else
                {
                    context.CommandList.Draw(drawData.DrawCount, drawData.StartLocation);
                }
            }
        }
Пример #13
0
        IEnumerable <EffectPinDescription> GetInputs()
        {
            var effectName = IsCompute ? "ComputeEffectShader" : Name;

            using (var dummyInstance = new DynamicEffectInstance(effectName))
            {
                var parameters = dummyInstance.Parameters;
                if (IsCompute)
                {
                    parameters.Set(ComputeEffectShaderKeys.ComputeShaderName, Name);
                    parameters.Set(ComputeEffectShaderKeys.ThreadNumbers, new Int3(1));
                }
                dummyInstance.Initialize(Factory.ServiceRegistry);
                dummyInstance.UpdateEffect(Factory.DeviceManager.GraphicsDevice);

                var usedNames = new HashSet <string>();
                usedNames.Add(ParameterSetterInput.Name);
                if (IsCompute)
                {
                    usedNames.Add(ComputeDispatchCountInput.Name);
                    usedNames.Add(ComputeThreadNumbersInput.Name);
                    usedNames.Add(ComputeIterationCountInput.Name);
                    usedNames.Add(ComputeIterationParameterSetterInput.Name);
                    usedNames.Add(ComputeEnabledInput.Name);
                    // Thread numbers and thread group count pins
                    yield return(ComputeThreadNumbersInput);

                    yield return(ComputeDispatchCountInput);
                }

                // Permutation parameters
                foreach (var parameter in parameters.ParameterKeyInfos)
                {
                    var key = parameter.Key;
                    if (key == ComputeEffectShaderKeys.ComputeShaderName)
                    {
                        continue;
                    }
                    if (key == ComputeEffectShaderKeys.ThreadNumbers)
                    {
                        continue;
                    }
                    yield return(new ParameterPinDescription(usedNames, key, isPermutationKey: true));
                }

                // Resource and value parameters
                var byteCode    = dummyInstance.Effect.Bytecode;
                var layoutNames = byteCode.Reflection.ResourceBindings.Select(x => x.ResourceGroup ?? "Globals").Distinct().ToList();
                var needsWorld  = false;
                foreach (var parameter in parameters.Layout.LayoutParameterKeyInfos)
                {
                    var key  = parameter.Key;
                    var name = key.Name;

                    // Skip constant buffers
                    if (layoutNames.Contains(name))
                    {
                        continue;
                    }

                    // Skip compiler injected paddings
                    if (name.Contains("_padding_"))
                    {
                        continue;
                    }

                    // Skip well known parameters
                    if (WellKnownParameters.PerFrameMap.ContainsKey(name) || WellKnownParameters.PerViewMap.ContainsKey(name))
                    {
                        continue;
                    }

                    if (WellKnownParameters.PerDrawMap.ContainsKey(name))
                    {
                        // Expose World only - all other world dependent parameters we can compute on our own
                        needsWorld = true;
                        continue;
                    }

                    if (key == ComputeShaderBaseKeys.ThreadGroupCountGlobal)
                    {
                        continue; // Already handled
                    }
                    yield return(new ParameterPinDescription(usedNames, key, parameter.Count));
                }

                if (needsWorld)
                {
                    yield return(new ParameterPinDescription(usedNames, TransformationKeys.World));
                }

                yield return(ParameterSetterInput);

                if (IsCompute)
                {
                    yield return(ComputeIterationCountInput);

                    yield return(ComputeIterationParameterSetterInput);

                    yield return(ComputeEnabledInput);
                }
            }
        }