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); }
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(); }
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); }
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(); }
public void Update() { if (instance.UpdateEffect(graphicsDevice)) { foreach (var p in Inputs.OfType <ParameterPin>()) { p.Update(parameters); } } }
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(); }
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); }
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); } }
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> >; } }
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); } } }
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); } } }