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); }
protected override async Task LoadContent() { await base.LoadContent(); effectInstance = new DynamicEffectInstance("CustomEffect.CustomSubEffect"); effectInstance.Initialize(Services); }
protected override void InitializeCore() { base.InitializeCore(); _skyViewLutTexture = Texture.New2D(Context.GraphicsDevice, SkyViewLutSettings.Width, SkyViewLutSettings.Height, SkyViewLutSettings.Format, TextureFlags.RenderTarget | TextureFlags.ShaderResource); _atmosphereCameraScatteringVolumeTexture = Texture.New3D(Context.GraphicsDevice, AtmosphereCameraScatteringVolumeSettings.Size, AtmosphereCameraScatteringVolumeSettings.Size, AtmosphereCameraScatteringVolumeSettings.Slices, AtmosphereCameraScatteringVolumeSettings.Format, TextureFlags.RenderTarget | TextureFlags.ShaderResource); _multiScatteringTexture = Texture.New2D(Context.GraphicsDevice, MultiScatteringTextureSettings.Size, MultiScatteringTextureSettings.Size, MultiScatteringTextureSettings.Format, TextureFlags.UnorderedAccess | TextureFlags.ShaderResource); TransmittanceLutTexture = Texture.New2D(Context.GraphicsDevice, TransmittanceLutSettings.Width, TransmittanceLutSettings.Height, TransmittanceLutSettings.Format, TextureFlags.UnorderedAccess | TextureFlags.RenderTarget | TextureFlags.ShaderResource); _atmosphereCubeMapRenderTarget = Texture.New2D(Context.GraphicsDevice, 64, 64, PixelFormat.R16G16B16A16_Float, TextureFlags.RenderTarget | TextureFlags.ShaderResource); _atmosphereCubeMap = Texture.NewCube(Context.GraphicsDevice, 64, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource); _atmosphereCubeMapSpecular = Texture.NewCube(Context.GraphicsDevice, 64, MipMapCount.Auto, PixelFormat.R16G16B16A16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess); _transmittanceLutEffect = new ImageEffectShader("AtmosphereRenderTransmittanceLutEffect"); _skyViewLutEffect = new ImageEffectShader("AtmosphereRenderSkyViewLutEffect"); _renderMultipleScatteringTextureEffect = new ComputeEffectShader(Context) { ShaderSourceName = "AtmosphereMultipleScatteringTextureEffect" }; _renderAtmosphereScatteringVolumeEffect = new DynamicEffectInstance("AtmosphereRenderScatteringCameraVolumeEffect"); _renderAtmosphereScatteringVolumeEffect.Initialize(Context.Services); _renderAtmosphereScatteringVolumePipelineState = new MutablePipelineState(Context.GraphicsDevice); _renderAtmosphereScatteringVolumePipelineState.State.SetDefaults(); _renderAtmosphereScatteringVolumePipelineState.State.PrimitiveType = PrimitiveType.TriangleList; _atmosphereLogicalGroupKey = CreateDrawLogicalGroup("Atmosphere"); _spriteBatch = new SpriteBatch(Context.GraphicsDevice); }
protected override void InitializeCore() { base.InitializeCore(); // Initalize the shader _decalShader = new DynamicEffectInstance("DecalShader"); _decalShader.Initialize(Context.Services); }
/// <summary> /// Initializes a new instance of the <see cref="ImageEffectShader" /> class. /// </summary> public ImageEffectShader(string effectName = null, bool delaySetRenderTargets = false) { EffectInstance = new DynamicEffectInstance(effectName, Parameters); EnableSetRenderTargets = !delaySetRenderTargets; this.delaySetRenderTargets = delaySetRenderTargets; if (effectName != null) { Name = effectName; } }
//private Matrix viewprojection = new Matrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); protected override void InitializeCore() { base.InitializeCore(); myCustomShader = new DynamicEffectInstance("test_shader1"); myCustomShader.Initialize(Context.Services); pipelineState = new MutablePipelineState(Context.GraphicsDevice); pipelineState.State.SetDefaults(); pipelineState.State.InputElements = VertexDeclaration.CreateInputElements(); pipelineState.State.PrimitiveType = PrimitiveType.TriangleStrip; pipelineState.State.BlendState = BlendStates.Default; pipelineState.State.RasterizerState.CullMode = CullMode.None; }
protected override void InitializeCore() { base.InitializeCore(); // Light accumulation shader lightShaftsEffectShader = ToLoadAndUnload(new ImageEffectShader("LightShaftsEffect")); // Additive blending shader applyLightEffectShader = ToLoadAndUnload(new ImageEffectShader("AdditiveLightEffect")); applyLightEffectShader.BlendState = new BlendStateDescription(Blend.One, Blend.One); minmaxVolumeEffectShader = new DynamicEffectInstance("VolumeMinMaxShader"); minmaxVolumeEffectShader.Initialize(Context.Services); blur = ToLoadAndUnload(new GaussianBlur()); // Need the shadow map renderer in order to render light shafts var meshRenderFeature = Context.RenderSystem.RenderFeatures.OfType <MeshRenderFeature>().FirstOrDefault(); if (meshRenderFeature == null) { throw new InvalidOperationException("Missing mesh render feature"); } var forwardLightingFeature = meshRenderFeature.RenderFeatures.OfType <ForwardLightingRenderFeature>().FirstOrDefault(); if (forwardLightingFeature == null) { throw new InvalidOperationException("Missing forward lighting render feature"); } shadowMapRenderer = forwardLightingFeature.ShadowMapRenderer; for (int i = 0; i < 2; ++i) { var minmaxPipelineState = new MutablePipelineState(Context.GraphicsDevice); minmaxPipelineState.State.SetDefaults(); minmaxPipelineState.State.BlendState.RenderTarget0.BlendEnable = true; minmaxPipelineState.State.BlendState.RenderTarget0.ColorSourceBlend = Blend.One; minmaxPipelineState.State.BlendState.RenderTarget0.ColorDestinationBlend = Blend.One; minmaxPipelineState.State.BlendState.RenderTarget0.ColorBlendFunction = i == 0 ? BlendFunction.Min : BlendFunction.Max; minmaxPipelineState.State.BlendState.RenderTarget0.ColorWriteChannels = i == 0 ? ColorWriteChannels.Red : ColorWriteChannels.Green; minmaxPipelineState.State.DepthStencilState.DepthBufferEnable = false; minmaxPipelineState.State.DepthStencilState.DepthBufferWriteEnable = false; minmaxPipelineState.State.RasterizerState.DepthClipEnable = true; minmaxPipelineState.State.RasterizerState.CullMode = i == 0 ? CullMode.Back : CullMode.Front; minmaxPipelineStates[i] = minmaxPipelineState; } }
protected override void InitializeCore() { base.InitializeCore(); backgroundEffect = new DynamicEffectInstance("BackgroundShader"); skyboxBackgroundEffect = new DynamicEffectInstance("SkyboxShader"); backgroundEffect.Initialize(Context.Services); skyboxBackgroundEffect.Initialize(Context.Services); spriteBatch = new SpriteBatch(RenderSystem.GraphicsDevice) { VirtualResolution = new Vector3(1) }; }
protected override void InitializeCore() { // Initalize the shader myCustomShader = new DynamicEffectInstance("MyCustomShader"); myCustomShader.Initialize(Context.Services); // Create the pipeline state and set properties that won't change pipelineState = new MutablePipelineState(Context.GraphicsDevice); pipelineState.State.SetDefaults(); pipelineState.State.InputElements = MyRenderObject.VertexDeclaration.CreateInputElements(); pipelineState.State.PrimitiveType = MyRenderObject.PrimitiveType; pipelineState.State.BlendState = BlendStates.Default; pipelineState.State.RasterizerState.CullMode = CullMode.None; }
public ComputeEffectShader(RenderContext context) : base(context, null) { pipelineState = new MutablePipelineState(context.GraphicsDevice); // Setup the effect compiler EffectInstance = new DynamicEffectInstance("ComputeEffectShader", Parameters); EffectInstance.Initialize(context.Services); ThreadNumbers = new Int3(1); ThreadGroupCounts = new Int3(1); SetDefaultParameters(); }
protected override void InitializeCore() { base.InitializeCore(); // initialize shader shader = new DynamicEffectInstance("SinglePassWireframeShader"); shader.Initialize(Context.Services); // create the pipeline state and set properties that won't change pipelineState = new MutablePipelineState(Context.GraphicsDevice); pipelineState.State.SetDefaults(); pipelineState.State.InputElements = VertexPositionNormalTexture.Layout.CreateInputElements(); pipelineState.State.BlendState = BlendStates.AlphaBlend; pipelineState.State.RasterizerState.CullMode = CullMode.None; }
public CubemapFromTextureRenderer(IServiceRegistry services, RenderDrawContext renderDrawContext, Texture input, int outputSize, PixelFormat outputFormat) : base(renderDrawContext.GraphicsDevice, outputSize, outputFormat, false) { inputTexture = input; DrawContext = renderDrawContext; skyboxEffect = new DynamicEffectInstance("SkyboxShaderTexture"); skyboxEffect.Initialize(services); spriteBatch = new SpriteBatch(renderDrawContext.GraphicsDevice) { VirtualResolution = new Vector3(1) }; }
public ComputeEffectShader(RenderContext context) : base(context, null) { pipelineState = new MutablePipelineState(context.GraphicsDevice); // Setup the effect compiler EffectInstance = new DynamicEffectInstance("ComputeEffectShader", Parameters); EffectInstance.Initialize(context.Services); // We give ComputeEffectShader a higher priority, since they are usually executed serially and blocking EffectInstance.EffectCompilerParameters.TaskPriority = -1; ThreadNumbers = new Int3(1); ThreadGroupCounts = new Int3(1); SetDefaultParameters(); }
public override void Unload() { base.Unload(); _specularRadiancePrefilterGGX?.Dispose(); _specularRadiancePrefilterGGX = null; _lamberFiltering?.Dispose(); _lamberFiltering = null; _atmosphereCubeMapRenderTarget?.Dispose(); _atmosphereCubeMapRenderTarget = null; _atmosphereCubeMap?.Dispose(); _atmosphereCubeMap = null; _multiScatteringTexture?.Dispose(); _multiScatteringTexture = null; TransmittanceLutTexture?.Dispose(); TransmittanceLutTexture = null; _skyViewLutTexture?.Dispose(); _skyViewLutTexture = null; _atmosphereCameraScatteringVolumeTexture?.Dispose(); _atmosphereCameraScatteringVolumeTexture = null; _transmittanceLutEffect?.Dispose(); _transmittanceLutEffect = null; _skyViewLutEffect?.Dispose(); _skyViewLutEffect = null; _renderMultipleScatteringTextureEffect?.Dispose(); _renderMultipleScatteringTextureEffect = null; _renderAtmosphereScatteringVolumeEffect?.Dispose(); _renderAtmosphereScatteringVolumeEffect = null; _spriteBatch?.Dispose(); _spriteBatch = null; }
protected override void InitializeCore() { background2DEffect = new DynamicEffectInstance("BackgroundShader"); backgroundCubemapEffect = new DynamicEffectInstance("BackgroundCubemapShader"); skyboxTextureEffect = new DynamicEffectInstance("SkyboxShaderTexture"); skyboxTextureHorizonEffect = new DynamicEffectInstance("SkyboxShaderTextureHorizon"); skyboxCubemapEffect = new DynamicEffectInstance("SkyboxShaderCubemap"); background2DEffect.Initialize(Context.Services); backgroundCubemapEffect.Initialize(Context.Services); skyboxTextureEffect.Initialize(Context.Services); skyboxCubemapEffect.Initialize(Context.Services); skyboxTextureHorizonEffect.Initialize(Context.Services); spriteBatch = new SpriteBatch(RenderSystem.GraphicsDevice) { VirtualResolution = new Vector3(1) }; }
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> >; } }
/// <summary> /// Initializes a new instance of the <see cref="ImageEffectShader" /> class. /// </summary> public ImageEffectShader(string effectName = null) { EffectInstance = new DynamicEffectInstance(effectName, Parameters); }
/// <summary> /// Bake lightprobes into buffers compatible with <see cref="LightProbeRenderer"/> /// </summary> /// <param name="drawContext">The drawing context</param> private unsafe void BakeLightProbes(RenderContext context, RenderDrawContext drawContext) { Texture ibl = null; Buffer tetrahedronProbeIndices = null; Buffer tetrahedronMatrices = null; Buffer lightprobesCoefficients = null; var renderView = context.RenderView; var lightProbesData = context.VisibilityGroup.Tags.Get(LightProbeRenderer.CurrentLightProbes); if (lightProbesData == null || lightProbesData.Tetrahedra.Count == 0) { // No lightprobes, we still set GPU resources (otherwise rendering might fetch invalid data) goto SetGPUResources; } // First time initialization if (bakeLightProbes == null) { bakeLightProbes = new DynamicEffectInstance("XenkoBakeLightProbeEffect"); bakeLightProbes.Initialize(Services); bakeLightProbesPipeline = new MutablePipelineState(GraphicsDevice); bakeLightProbesPipeline.State.InputElements = LightProbeVertex.Layout.CreateInputElements(); bakeLightProbesPipeline.State.PrimitiveType = PrimitiveType.TriangleList; } // Render IBL tetrahedra ID so that we can assign them per pixel //ibl = PushScopedResource(Context.Allocator.GetTemporaryTexture2D(drawContext.CommandList.DepthStencilBuffer.Width, drawContext.CommandList.DepthStencilBuffer.Height, PixelFormat.R16_UInt)); ibl = PushScopedResource(Context.Allocator.GetTemporaryTexture2D(TextureDescription.New2D(drawContext.CommandList.DepthStencilBuffer.Width, drawContext.CommandList.DepthStencilBuffer.Height, 1, PixelFormat.R16_UInt, TextureFlags.ShaderResource | TextureFlags.RenderTarget, 1, GraphicsResourceUsage.Default, actualMultisampleCount))); using (drawContext.PushRenderTargetsAndRestore()) { drawContext.CommandList.Clear(ibl, Color4.Black); drawContext.CommandList.SetRenderTarget(drawContext.CommandList.DepthStencilBuffer, ibl); bakeLightProbes.UpdateEffect(GraphicsDevice); bakeLightProbesPipeline.State.RootSignature = bakeLightProbes.RootSignature; bakeLightProbesPipeline.State.EffectBytecode = bakeLightProbes.Effect.Bytecode; bakeLightProbesPipeline.State.RasterizerState.DepthClipEnable = false; bakeLightProbesPipeline.State.DepthStencilState = new DepthStencilStateDescription(true, false) { StencilEnable = true, FrontFace = new DepthStencilStencilOpDescription { StencilDepthBufferFail = StencilOperation.Keep, StencilFail = StencilOperation.Keep, StencilPass = StencilOperation.Increment, StencilFunction = CompareFunction.Equal, }, }; //bakeLightProbesPipeline.State.RasterizerState.DepthClipEnable = false; bakeLightProbesPipeline.State.Output.CaptureState(drawContext.CommandList); bakeLightProbesPipeline.Update(); drawContext.CommandList.SetPipelineState(bakeLightProbesPipeline.CurrentState); drawContext.CommandList.SetStencilReference(0); // Apply the effect bakeLightProbes.Parameters.Set(BakeLightProbeShaderKeys.MatrixTransform, ref renderView.ViewProjection); bakeLightProbes.Apply(drawContext.GraphicsContext); /*int tetrahedrawGridSize = 5; * Vector3 tetrahedraMin = new Vector3(-12.0f); * Vector3 tetrahedraMax = new Vector3(12.0f); * var lightprobePositions = new Vector3[tetrahedrawGridSize*tetrahedrawGridSize*tetrahedrawGridSize]; * * for (int i = 0; i < lightprobePositions.Length; ++i) * { * lightprobePositions[i] = new Vector3( * MathUtil.Lerp(tetrahedraMin.X, tetrahedraMax.X, (float)(i/(tetrahedrawGridSize*tetrahedrawGridSize))/(tetrahedrawGridSize - 1)), * MathUtil.Lerp(tetrahedraMin.Y, tetrahedraMax.Y, (float)((i/tetrahedrawGridSize)%tetrahedrawGridSize)/(tetrahedrawGridSize - 1)), * MathUtil.Lerp(tetrahedraMin.Z, tetrahedraMax.Z, (float)(i%tetrahedrawGridSize)/(tetrahedrawGridSize - 1))); * } * * var tetra = new BowyerWatsonTetrahedralization(); * var tetraResult = tetra.Compute(lightprobePositions);*/ Matrix.Invert(ref renderView.View, out var viewInverse); var eye = new Vector3(viewInverse.M41, viewInverse.M42, viewInverse.M43); var tetraResult = lightProbesData.Tetrahedra; var lightprobePositions = lightProbesData.Vertices; var lightprobeFaces = lightProbesData.Faces; // We build a graph of tetrahedron connectivity from back to front, then do a topological sort on top of it var tetraDepth = new TetrahedronSortKey[tetraResult.Count]; var faceDirection = new bool[lightprobeFaces.Count]; var incomingEdges = new byte[tetraResult.Count]; var processQueue = new Queue <int>(); int processedTetrahedra = 0; for (int i = 0; i < lightprobeFaces.Count; ++i) { var face = lightprobeFaces[i]; // Compute face orientations var vertex0 = lightprobePositions[face.Vertices[0]]; Vector3.Subtract(ref vertex0, ref eye, out vertex0); bool faceFrontFacing = Vector3.Dot(face.Normal, vertex0) >= 0.0f; faceDirection[i] = faceFrontFacing; // Only process edges that connect two tetrahedra (ignore boundaries for now) if (face.BackTetrahedron != -1) { // Build list of incoming edges (back to front) if (faceFrontFacing) { incomingEdges[face.FrontTetrahedron] |= (byte)(1 << face.FrontFace); } else { incomingEdges[face.BackTetrahedron] |= (byte)(1 << face.BackFace); } } } for (int i = 0; i < tetraResult.Count; ++i) { // Tetrahedron without any incoming edges means they should be drawn first (graph nodes with no incoming edges for our topological sort) if (incomingEdges[i] == 0) { processQueue.Enqueue(i); } } // Perform topological sort while (processQueue.Count > 0) { var tetrahedronIndex = processQueue.Dequeue(); tetraDepth[tetrahedronIndex] = new TetrahedronSortKey(tetrahedronIndex, processedTetrahedra++); var tetrahedron = tetraResult[tetrahedronIndex]; //var frontFacingFaces = frontFacing[tetrahedronIndex]; // Process each outgoing face (edges in the graph) for (int tetrahedronFace = 0; tetrahedronFace < 4; ++tetrahedronFace) { // Check if there is a neighbour if (tetrahedron.Neighbours[tetrahedronFace] == -1) { continue; } var faceIndex = tetrahedron.Faces[tetrahedronFace]; var realFaceIndex = faceIndex >= 0 ? faceIndex : ~faceIndex; // Only process faces going back to front (outgoing edges) if (faceDirection[realFaceIndex] == faceIndex >= 0) { continue; } var face = lightprobeFaces[realFaceIndex]; int tetrahedronNeighbourIndex; sbyte tetrahedronNeighbourFace; if (faceIndex >= 0) { tetrahedronNeighbourIndex = face.BackTetrahedron; tetrahedronNeighbourFace = face.BackFace; } else { tetrahedronNeighbourIndex = face.FrontTetrahedron; tetrahedronNeighbourFace = face.FrontFace; } var neighbourTraversedFaces = incomingEdges[tetrahedronNeighbourIndex]; var newNeighbourTraversedFaces = (byte)(neighbourTraversedFaces & ~(1 << tetrahedronNeighbourFace)); // Proceed only if something changed if (newNeighbourTraversedFaces != neighbourTraversedFaces) { incomingEdges[tetrahedronNeighbourIndex] = newNeighbourTraversedFaces; if (newNeighbourTraversedFaces == 0) // are all incoming edges already marked? If yes, go on { processQueue.Enqueue(tetrahedronNeighbourIndex); } } } } Array.Sort(tetraDepth); // Draw shape tetrahedronMatrices = PushScopedResource(Context.Allocator.GetTemporaryBuffer(new BufferDescription(tetraResult.Count * 3 * sizeof(Vector4), BufferFlags.ShaderResource, GraphicsResourceUsage.Default), PixelFormat.R32G32B32A32_Float)); tetrahedronProbeIndices = PushScopedResource(Context.Allocator.GetTemporaryBuffer(new BufferDescription(tetraResult.Count * 4 * sizeof(int), BufferFlags.ShaderResource, GraphicsResourceUsage.Default), PixelFormat.R32G32B32A32_UInt)); lightprobesCoefficients = PushScopedResource(Context.Allocator.GetTemporaryBuffer(new BufferDescription(lightProbesData.Coefficients.Length * sizeof(Color3), BufferFlags.ShaderResource, GraphicsResourceUsage.Default), PixelFormat.R32G32B32_Float)); var tetraInsideIndex = -1; fixed(Color3 *lightProbeCoefficients = lightProbesData.Coefficients) fixed(Vector4 * matrices = lightProbesData.Matrices) fixed(Int4 * probeIndices = lightProbesData.LightProbeIndices) { drawContext.CommandList.UpdateSubresource(lightprobesCoefficients, 0, new DataBox((IntPtr)lightProbeCoefficients, 0, 0)); drawContext.CommandList.UpdateSubresource(tetrahedronProbeIndices, 0, new DataBox((IntPtr)probeIndices, 0, 0)); drawContext.CommandList.UpdateSubresource(tetrahedronMatrices, 0, new DataBox((IntPtr)matrices, 0, 0)); // Find which probe we are currently in // TODO: Optimize (use previous coherency info?) for (int i = 0; i < tetraResult.Count; ++i) { // Get tetrahedra matrix var tetrahedraMatrix = Matrix.Identity; tetrahedraMatrix.Column1 = matrices[i * 3 + 0]; tetrahedraMatrix.Column2 = matrices[i * 3 + 1]; tetrahedraMatrix.Column3 = matrices[i * 3 + 2]; // Extract and zero-out position of 3rd vertex (we get the 3x3 matrix) var vertex3 = tetrahedraMatrix.TranslationVector; tetrahedraMatrix.TranslationVector = Vector3.Zero; Vector3 tetraFactors = Vector3.TransformCoordinate(eye - vertex3, tetrahedraMatrix); var tetraFactorW = 1.0f - tetraFactors.X - tetraFactors.Y - tetraFactors.Z; if (tetraFactors.X >= 0.0f && tetraFactors.X <= 1.0f && tetraFactors.Y >= 0.0f && tetraFactors.Y <= 1.0f && tetraFactors.Z >= 0.0f && tetraFactors.Z <= 1.0f && tetraFactorW >= 0.0f && tetraFactorW <= 1.0f) { tetraInsideIndex = i; break; } } } // Fill vertex/index buffers var vertexBuffer = PushScopedResource(Context.Allocator.GetTemporaryBuffer(new BufferDescription((tetraResult.Count * 4 + 3) * LightProbeVertex.Size, BufferFlags.VertexBuffer, GraphicsResourceUsage.Dynamic))); var indexBuffer = PushScopedResource(Context.Allocator.GetTemporaryBuffer(new BufferDescription(tetraResult.Count * 12 * sizeof(uint), BufferFlags.IndexBuffer, GraphicsResourceUsage.Dynamic))); var mappedVertexBuffer = drawContext.CommandList.MapSubresource(vertexBuffer, 0, MapMode.WriteDiscard); var vertices = (LightProbeVertex *)mappedVertexBuffer.DataBox.DataPointer; // Upload sorted tetrahedron indices for (int i = 0; i < tetraResult.Count; ++i) { var sortedIndex = tetraDepth[i].Index; var tetrahedra = tetraResult[sortedIndex]; for (int j = 0; j < 4; ++j) { vertices[i * 4 + j] = new LightProbeVertex(lightprobePositions[tetrahedra.Vertices[j]], (uint)sortedIndex); } } // Full screen pass if (tetraInsideIndex != -1) { vertices[tetraResult.Count * 4 + 0] = new LightProbeVertex(new Vector3(-1, 1, 0), (uint)tetraInsideIndex); vertices[tetraResult.Count * 4 + 1] = new LightProbeVertex(new Vector3(3, 1, 0), (uint)tetraInsideIndex); vertices[tetraResult.Count * 4 + 2] = new LightProbeVertex(new Vector3(-1, -3, 0), (uint)tetraInsideIndex); } drawContext.CommandList.UnmapSubresource(mappedVertexBuffer); var mappedIndexBuffer = drawContext.CommandList.MapSubresource(indexBuffer, 0, MapMode.WriteDiscard); var indices = (int *)mappedIndexBuffer.DataBox.DataPointer; for (int i = 0; i < tetraResult.Count; ++i) { indices[i * 12 + 0] = i * 4 + 0; indices[i * 12 + 1] = i * 4 + 2; indices[i * 12 + 2] = i * 4 + 1; indices[i * 12 + 3] = i * 4 + 1; indices[i * 12 + 4] = i * 4 + 2; indices[i * 12 + 5] = i * 4 + 3; indices[i * 12 + 6] = i * 4 + 3; indices[i * 12 + 7] = i * 4 + 2; indices[i * 12 + 8] = i * 4 + 0; indices[i * 12 + 9] = i * 4 + 3; indices[i * 12 + 10] = i * 4 + 0; indices[i * 12 + 11] = i * 4 + 1; } drawContext.CommandList.UnmapSubresource(mappedIndexBuffer); drawContext.CommandList.SetVertexBuffer(0, vertexBuffer, 0, LightProbeVertex.Size); drawContext.CommandList.SetIndexBuffer(indexBuffer, 0, true); // Draw until current tetrahedra drawContext.CommandList.DrawIndexed(tetraResult.Count * 12); // For now, drawing them one by one (easier to debug) //for (int i = 0; i < tetraResult.Count; ++i) //{ // context.CommandList.DrawIndexed(12, i * 12); //} // Draw current tetrahedron we are in as full screen (fill stencil holes) if (tetraInsideIndex != -1) { bakeLightProbesPipeline.State.DepthStencilState.DepthBufferEnable = false; bakeLightProbesPipeline.Update(); drawContext.CommandList.SetPipelineState(bakeLightProbesPipeline.CurrentState); // Apply the effect bakeLightProbes.Parameters.Set(BakeLightProbeShaderKeys.MatrixTransform, Matrix.Identity); bakeLightProbes.Apply(drawContext.GraphicsContext); drawContext.CommandList.Draw(3, tetraResult.Count * 4); } // TODO: Draw the tetrahedron we are in full screen // context.CommandList.Draw... } // Set LightProbes resources SetGPUResources: foreach (var renderFeature in context.RenderSystem.RenderFeatures) { if (!(renderFeature is RootEffectRenderFeature)) { continue; } var logicalKey = ((RootEffectRenderFeature)renderFeature).CreateViewLogicalGroup("LightProbes"); var viewFeature = renderView.Features[renderFeature.Index]; foreach (var viewLayout in viewFeature.Layouts) { var resourceGroup = viewLayout.Entries[renderView.Index].Resources; var logicalGroup = viewLayout.GetLogicalGroup(logicalKey); if (logicalGroup.Hash == ObjectId.Empty) { continue; } resourceGroup.DescriptorSet.SetShaderResourceView(logicalGroup.DescriptorSlotStart, ibl); resourceGroup.DescriptorSet.SetShaderResourceView(logicalGroup.DescriptorSlotStart + 1, tetrahedronProbeIndices); resourceGroup.DescriptorSet.SetShaderResourceView(logicalGroup.DescriptorSlotStart + 2, tetrahedronMatrices); resourceGroup.DescriptorSet.SetShaderResourceView(logicalGroup.DescriptorSlotStart + 3, lightprobesCoefficients); } } }
public TexturePreview() { currentEffect = new DynamicEffectInstance("PreviewTexture"); }
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); } } }