Example #1
0
        public void UpdateTempStorage(VoxelStorageContext context)
        {
            storageUints       = (tempStorageCounter + 31) / 32;
            tempStorageCounter = 0;

            var resolution = ClipMapResolution;
            int fragments  = (int)(resolution.X * resolution.Y * resolution.Z) * ClipMapCount;

            if (VoxelUtils.DisposeBufferBySpecs(FragmentsBuffer, storageUints * fragments) && storageUints * fragments > 0)
            {
                FragmentsBuffer = Xenko.Graphics.Buffer.Typed.New(context.device, storageUints * fragments, PixelFormat.R32_UInt, true);
            }
        }
        public void UpdateTexture(VoxelStorageContext context, ref IVoxelStorageTexture texture, Xenko.Graphics.PixelFormat pixelFormat, int layoutCount)
        {
            VoxelStorageTextureClipmap clipmap = texture as VoxelStorageTextureClipmap;

            if (clipmap == null)
            {
                clipmap = new VoxelStorageTextureClipmap();
            }

            Vector3 ClipMapTextureResolution = new Vector3(ClipMapResolution.X, ClipMapResolution.Y * ClipMapCount * layoutCount, ClipMapResolution.Z);
            Vector3 MipMapResolution         = new Vector3(ClipMapResolution.X / 2, ClipMapResolution.Y / 2 * layoutCount, ClipMapResolution.Z / 2);
            Vector3 MipMapNoLayoutResolution = new Vector3(ClipMapResolution.X / 2, ClipMapResolution.Y / 2, ClipMapResolution.Z / 2);

            if (NeedToRecreateTexture(clipmap.ClipMaps, ClipMapTextureResolution, pixelFormat))
            {
                clipmap.ClipMaps = Xenko.Graphics.Texture.New3D(context.device, (int)ClipMapTextureResolution.X, (int)ClipMapTextureResolution.Y, (int)ClipMapTextureResolution.Z, new MipMapCount(false), pixelFormat, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);
            }
            if (NeedToRecreateTexture(clipmap.MipMaps, MipMapResolution, pixelFormat))
            {
                if (clipmap.TempMipMaps != null)
                {
                    for (int i = 0; i < clipmap.TempMipMaps.Length; i++)
                    {
                        clipmap.TempMipMaps[i].Dispose();
                    }
                }


                Vector3 MipMapResolutionMax = MipMapResolution;
                int     mipCount            = 1 + (int)Math.Floor(Math.Log(Math.Min(MipMapNoLayoutResolution.X, Math.Min(MipMapNoLayoutResolution.Y, MipMapNoLayoutResolution.Z)), 2));

                clipmap.MipMaps = Xenko.Graphics.Texture.New3D(context.device, (int)MipMapResolution.X, (int)MipMapResolution.Y, (int)MipMapResolution.Z, new MipMapCount(true), pixelFormat, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);

                clipmap.TempMipMaps = new Xenko.Graphics.Texture[mipCount];

                for (int i = 0; i < clipmap.TempMipMaps.Length; i++)
                {
                    clipmap.TempMipMaps[i] = Xenko.Graphics.Texture.New3D(context.device, (int)MipMapResolutionMax.X, (int)MipMapResolutionMax.Y, (int)MipMapResolutionMax.Z, false, pixelFormat, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess);

                    MipMapResolutionMax /= 2;
                }
            }
            clipmap.MipmapInner       = MipmapInner;
            clipmap.ClipMapResolution = ClipMapResolution;
            clipmap.ClipMapCount      = ClipMapCount;
            clipmap.LayoutSize        = layoutCount;
            clipmap.VoxelMatrix       = InnerTextureMatrix;
            clipmap.VoxelSize         = context.RealVoxelSize();

            texture = clipmap;
        }
        public void Render(VoxelStorageContext context, RenderDrawContext drawContext, RenderView view)
        {
            var renderSystem = drawContext.RenderContext.RenderSystem;

            var resolution = ClipMapResolution;


            float maxResolution = Math.Max(Math.Max(resolution.X, resolution.Y), resolution.Z);

            drawContext.CommandList.SetViewport(new Viewport(0, 0, (int)maxResolution, (int)maxResolution));

            if (RenderMethod == RenderMethods.GeometryShader)
            {
                renderSystem.Draw(drawContext, view, renderSystem.RenderStages[view.RenderStages[0].Index]);
            }
        }
        public RenderView CollectViews(VoxelStorageContext context, RenderContext RenderContext, RenderView view)
        {
            if (RenderMethod == RenderMethods.GeometryShader)
            {
                float  maxRes      = Math.Max(ClipMapResolution.X, Math.Max(ClipMapResolution.Y, ClipMapResolution.Z));
                Matrix aspectScale = Matrix.Scaling(ClipMapResolution / maxRes);
                view.Projection    *= aspectScale;
                view.ViewProjection = view.View * view.Projection;

                view.ViewSize = new Vector2(maxRes * 8, maxRes * 8);// * 8 improves shadow quality drastically, TODO: maybe should be configurable?
                RenderContext.RenderSystem.Views.Add(view);
                RenderContext.VisibilityGroup.TryCollect(view);
                return(view);
            }
            return(null);
        }
        public void PrepareLocalStorage(VoxelStorageContext context, IVoxelStorage storage)
        {
            StorageMethod.PrepareLocalStorage(context, storage, 4, 1);

            Graphics.PixelFormat format = Graphics.PixelFormat.R16G16B16A16_Float;
            switch (StorageFormat)
            {
            case StorageFormats.RGBA8:
                format = Graphics.PixelFormat.R8G8B8A8_UNorm;
                break;

            case StorageFormats.R10G10B10A2:
                format = Graphics.PixelFormat.R10G10B10A2_UNorm;
                break;

            case StorageFormats.RGBA16F:
                format = Graphics.PixelFormat.R16G16B16A16_Float;
                break;
            }
            storage.UpdateTexture(context, ref IsotropicTex, format, 1);
        }
        public void UpdateFromContext(VoxelStorageContext context, RenderVoxelVolumeData data)
        {
            VoxelMatrix = context.Matrix;

            var resolution = context.Resolution();
            var maxRes     = (double)Math.Max(resolution.X, Math.Max(resolution.Y, resolution.Z));

            ClipMapCount      = (int)Math.Log(maxRes / Math.Min(maxRes, (double)ClipResolution), 2) + 1;
            InnerClipMapScale = (float)Math.Pow(2, ClipMapCount - 1);
            ClipMapResolution = new Vector3(resolution.X, resolution.Y, resolution.Z) / InnerClipMapScale;

            var viewToTexTrans = Matrix.Translation(0.5f, 0.5f, 0.5f);
            var viewToTexScale = Matrix.Scaling(0.5f, 0.5f, 0.5f);

            Matrix BaseVoxelMatrix = VoxelMatrix;

            BaseVoxelMatrix.Invert();
            BaseVoxelMatrix = BaseVoxelMatrix * Matrix.Scaling(2f, 2f, 2f);

            TextureMatrix      = BaseVoxelMatrix * viewToTexScale * viewToTexTrans;
            InnerTextureMatrix = BaseVoxelMatrix * Matrix.Scaling(InnerClipMapScale) * viewToTexScale * viewToTexTrans;
        }
        public void Render(VoxelStorageContext storageContext, RenderDrawContext drawContext, RenderView view)
        {
            RenderView voxelizationView = view;
            Int2       ViewSize         = VoxelizationViewSizes[view];

            if (VoxelUtils.DisposeTextureBySpecs(MSAARenderTarget, new Vector3(ViewSize.X, ViewSize.Y, 1), PixelFormat.R8G8B8A8_UNorm, MultisampleCount))
            {
                MSAARenderTarget = Texture.New(storageContext.device, TextureDescription.New2D(ViewSize.X, ViewSize.Y, new MipMapCount(false), PixelFormat.R8G8B8A8_UNorm, TextureFlags.RenderTarget, 1, GraphicsResourceUsage.Default, MultisampleCount), null);
            }

            drawContext.CommandList.ResetTargets();
            if (MSAARenderTarget != null)
            {
                drawContext.CommandList.SetRenderTarget(null, MSAARenderTarget);
            }

            var renderSystem = drawContext.RenderContext.RenderSystem;

            drawContext.CommandList.SetViewport(new Viewport(0, 0, ViewSize.X, ViewSize.Y));

            renderSystem.Draw(drawContext, voxelizationView, renderSystem.RenderStages[voxelizationView.RenderStages[0].Index]);
        }
Example #8
0
        public virtual void Collect(RenderContext Context, Shadows.IShadowMapRenderer ShadowMapRenderer)
        {
            renderVoxelVolumes    = Context.VisibilityGroup.Tags.Get(CurrentRenderVoxelVolumes);
            renderVoxelVolumeData = Context.VisibilityGroup.Tags.Get(CurrentProcessedVoxelVolumes);

            if (renderVoxelVolumes == null || renderVoxelVolumes.Count == 0)
            {
                return;
            }

            if (Context.RenderSystem.GraphicsDevice.Features.CurrentProfile < GraphicsProfile.Level_11_0)
            {
                throw new ArgumentOutOfRangeException("Graphics Profile Level 11 or higher required for Voxelization.");
            }

            //Setup per volume passes and texture allocations
            foreach (var pair in renderVoxelVolumes)
            {
                var dataVolume = pair.Value;
                var bounds     = dataVolume.VolumeSize;

                ProcessedVoxelVolume processedVolume;
                if (!renderVoxelVolumeData.TryGetValue(pair.Key, out processedVolume))
                {
                    processedVolume = new ProcessedVoxelVolume();
                    renderVoxelVolumeData.Add(pair.Key, processedVolume);
                }


                //Setup matrix
                Vector3 matScale = dataVolume.VolumeSize;
                Vector3 matTrans = dataVolume.VolumeTranslation;

                Matrix corMatrix = Matrix.Scaling(matScale) * Matrix.Translation(matTrans);
                VoxelStorageContext storageContext = new VoxelStorageContext
                {
                    device    = Context.GraphicsDevice,
                    Extents   = bounds,
                    VoxelSize = dataVolume.AproxVoxelSize,
                    Matrix    = corMatrix
                };

                if (dataVolume.VoxelGridSnapping)
                {
                    matTrans  /= storageContext.RealVoxelSize();
                    matTrans.X = (float)Math.Floor(matTrans.X);
                    matTrans.Y = (float)Math.Floor(matTrans.Y);
                    matTrans.Z = (float)Math.Floor(matTrans.Z);
                    matTrans  *= storageContext.RealVoxelSize();

                    corMatrix             = Matrix.Scaling(matScale) * Matrix.Translation(matTrans);
                    storageContext.Matrix = corMatrix;
                }
                storageContext.Translation           = matTrans;
                storageContext.VoxelSpaceTranslation = matTrans / storageContext.RealVoxelSize();

                //Update storage
                dataVolume.Storage.UpdateFromContext(storageContext);

                //Transfer voxelization info
                processedVolume.VisualizeVoxels        = dataVolume.VisualizeVoxels;
                processedVolume.Storage                = dataVolume.Storage;
                processedVolume.StorageContext         = storageContext;
                processedVolume.VoxelizationMethod     = dataVolume.VoxelizationMethod;
                processedVolume.VoxelVisualization     = dataVolume.VoxelVisualization;
                processedVolume.VisualizationAttribute = dataVolume.VisualizationAttribute;
                processedVolume.Voxelize               = dataVolume.Voxelize;
                processedVolume.OutputAttributes       = dataVolume.Attributes;

                processedVolume.Attributes.Clear();
                processedVolume.passList.Clear();
                processedVolume.groupedPasses.Clear();

                processedVolume.passList.defaultVoxelizationMethod = dataVolume.VoxelizationMethod;


                //Create final list of attributes (including temporary ones)
                foreach (var attr in dataVolume.Attributes)
                {
                    attr.CollectAttributes(processedVolume.Attributes, VoxelizationStage.Initial, true);
                }

                //Allocate textures and space in the temporary buffer
                foreach (var attr in processedVolume.Attributes)
                {
                    attr.Attribute.PrepareLocalStorage(storageContext, dataVolume.Storage);
                    if (attr.Output)
                    {
                        attr.Attribute.PrepareOutputStorage(storageContext, dataVolume.Storage);
                    }
                    else
                    {
                        attr.Attribute.ClearOutputStorage();
                    }
                }
                dataVolume.Storage.UpdateTempStorage(storageContext);

                //Create list of voxelization passes that need to be done
                dataVolume.Storage.CollectVoxelizationPasses(processedVolume, storageContext);

                //Group voxelization passes where the RenderStage can be shared
                //TODO: Group identical attributes
                for (int i = 0; i < processedVolume.passList.passes.Count; i++)
                {
                    bool added = false;
                    var  passA = processedVolume.passList.passes[i];
                    for (int group = 0; group < processedVolume.groupedPasses.Count; group++)
                    {
                        var passB = processedVolume.groupedPasses[group][0];
                        if (
                            passB.storer.CanShareRenderStage(passA.storer) &&
                            passB.method.CanShareRenderStage(passA.method) &&
                            passB.AttributesDirect.SequenceEqual(passA.AttributesDirect) &&
                            passB.AttributesIndirect.SequenceEqual(passA.AttributesIndirect) &&
                            passB.AttributesTemp.SequenceEqual(passA.AttributesTemp)
                            )
                        {
                            processedVolume.groupedPasses[group].Add(passA);
                            added = true;
                            break;
                        }
                    }
                    if (!added)
                    {
                        List <VoxelizationPass> newGroup = new List <VoxelizationPass>
                        {
                            passA
                        };
                        processedVolume.groupedPasses.Add(newGroup);
                    }
                }

                if (VoxelStages.Count < processedVolume.groupedPasses.Count)
                {
                    throw new ArgumentOutOfRangeException(processedVolume.groupedPasses.Count.ToString() + " Render Stages required for voxelization, only " + VoxelStages.Count.ToString() + " provided.");
                }

                //Finish preparing the passes, collecting views and setting up shader sources and shadows
                for (int group = 0; group < processedVolume.groupedPasses.Count; group++)
                {
                    foreach (var pass in processedVolume.groupedPasses[group])
                    {
                        pass.renderStage = VoxelStages[group];
                        pass.source      = pass.storer.GetVoxelizationShader(pass, processedVolume);
                        pass.view.RenderStages.Add(pass.renderStage);

                        Context.RenderSystem.Views.Add(pass.view);
                        Context.VisibilityGroup.TryCollect(pass.view);

                        if (pass.requireShadows)
                        {
                            ShadowMapRenderer?.RenderViewsWithShadows.Add(pass.view);
                        }
                    }
                }
            }
        }
Example #9
0
        public virtual void Draw(RenderDrawContext drawContext, Shadows.IShadowMapRenderer ShadowMapRenderer)
        {
            if (renderVoxelVolumes == null || renderVoxelVolumes.Count == 0)
            {
                return;
            }

            if (drawContext.GraphicsDevice.Features.CurrentProfile < GraphicsProfile.Level_11_0)
            {
                return;
            }

            var context = drawContext;

            using (drawContext.PushRenderTargetsAndRestore())
            {
                // Draw all shadow views generated for the current view
                foreach (var processedVolumeKeyValue in renderVoxelVolumeData)
                {
                    var processedVolume = processedVolumeKeyValue.Value;
                    if (!processedVolume.Voxelize)
                    {
                        continue;
                    }

                    VoxelStorageContext storageContext = processedVolume.StorageContext;

                    using (drawContext.QueryManager.BeginProfile(Color.Black, PassesVoxelizationProfilingKey))
                    {
                        foreach (VoxelizationPass pass in processedVolume.passList.passes)
                        {
                            RenderView voxelizeRenderView = pass.view;

                            if (pass.requireShadows)
                            {
                                //Render Shadow Maps
                                RenderView oldView = drawContext.RenderContext.RenderView;

                                drawContext.RenderContext.RenderView = voxelizeRenderView;
                                ShadowMapRenderer.Draw(drawContext);
                                drawContext.RenderContext.RenderView = oldView;
                            }

                            //Render/Collect voxel fragments
                            using (drawContext.QueryManager.BeginProfile(Color.Black, FragmentVoxelizationProfilingKey))
                            {
                                using (drawContext.PushRenderTargetsAndRestore())
                                {
                                    pass.method.Render(storageContext, context, pass.view);
                                }
                            }
                        }
                        foreach (VoxelizationPass pass in processedVolume.passList.passes)
                        {
                            pass.method.Reset();
                        }
                    }

                    //Fill and write to voxel volume
                    using (drawContext.QueryManager.BeginProfile(Color.Black, BufferProcessingVoxelizationProfilingKey))
                    {
                        processedVolume.Storage.PostProcess(storageContext, context, processedVolume);
                    }

                    //Mipmap
                    using (drawContext.QueryManager.BeginProfile(Color.Black, MipmappingVoxelizationProfilingKey))
                    {
                        foreach (var attr in processedVolume.Attributes)
                        {
                            if (attr.Output)
                            {
                                attr.Attribute.PostProcess(context);
                            }
                        }
                    }
                }
            }
        }
Example #10
0
 public abstract void PrepareOutputStorage(VoxelStorageContext context, IVoxelStorage storage);
Example #11
0
 public override void PrepareLocalStorage(VoxelStorageContext context, IVoxelStorage storage)
 {
     BufferOffset = storage.RequestTempStorage(64);
 }
Example #12
0
        public void UpdateFromContext(VoxelStorageContext context)
        {
            var virtualResolution = context.Resolution();
            var largestDimension  = (double)Math.Max(virtualResolution.X, Math.Max(virtualResolution.Y, virtualResolution.Z));

            ClipMapCount = (int)Math.Log(largestDimension / Math.Min(largestDimension, (double)ClipResolution), 2) + 1;

            ClipMapCurrent++;
            if (ClipMapCurrent >= ClipMapCount)
            {
                ClipMapCurrent = 0;
            }

            float FinestClipMapScale = (float)Math.Pow(2, ClipMapCount - 1);

            ClipMapResolution = new Vector3(virtualResolution.X, virtualResolution.Y, virtualResolution.Z) / FinestClipMapScale;
            MipMapCount       = (int)Math.Floor(Math.Log(Math.Min(ClipMapResolution.X, Math.Min(ClipMapResolution.Y, ClipMapResolution.Z)), 2));

            int voxelScale = 1;

            for (int i = 0; i < (ClipMapCount + MipMapCount); i++)
            {
                Vector3 SnappedVolumeTranslation = context.VoxelSpaceTranslation;
                SnappedVolumeTranslation.X = (float)Math.Floor(SnappedVolumeTranslation.X / voxelScale) * voxelScale;
                SnappedVolumeTranslation.Y = (float)Math.Floor(SnappedVolumeTranslation.Y / voxelScale) * voxelScale;
                SnappedVolumeTranslation.Z = (float)Math.Floor(SnappedVolumeTranslation.Z / voxelScale) * voxelScale;

                if (ShouldUpdateClipIndex(i))
                {
                    PerMapSnappingOffset[i] = -SnappedVolumeTranslation *context.RealVoxelSize();

                    MippingOffsetTranslation[i] = new Int3((int)SnappedVolumeTranslation.X, (int)SnappedVolumeTranslation.Y, (int)SnappedVolumeTranslation.Z);
                }

                voxelScale *= 2;
            }

            float extentScale = (float)Math.Pow(2f, ClipMapCount - 1);

            voxelScale = 1;

            for (int i = 0; i < (ClipMapCount + MipMapCount); i++)
            {
                if (ShouldUpdateClipIndex(i))
                {
                    Vector3 offset = (PerMapSnappingOffset[i]) * extentScale / context.Extents + 0.5f;
                    PerMapOffsetScale[i] = new Vector4(offset, (1.0f / context.Extents.X) * extentScale);
                }

                if (i + 1 == ClipMapCurrent || ShouldUpdateClipIndex(i))
                {
                    MippingOffset[i] = (Vector3)((MippingOffsetTranslation[i] - MippingOffsetTranslation[i + 1]) / voxelScale);
                }

                if (i < ClipMapCount - 1)
                {
                    extentScale /= 2;
                }
                voxelScale *= 2;
            }
        }
Example #13
0
        public virtual void Collect(RenderContext Context, Shadows.IShadowMapRenderer ShadowMapRenderer)
        {
            renderVoxelVolumes = Context.VisibilityGroup.Tags.Get(CurrentRenderVoxelVolumes);

            if (renderVoxelVolumes == null || renderVoxelVolumes.Count == 0)
            {
                return;
            }

            List <VoxelVolumeComponent> toRemove = new List <VoxelVolumeComponent>();

            foreach (var pair in renderVoxelVolumeData)
            {
                bool used = false;
                foreach (var pair2 in renderVoxelVolumes)
                {
                    if (pair2.Key == pair.Key)
                    {
                        used = true;
                    }
                }
                if (!used)
                {
                    toRemove.Add(pair.Key);
                }
            }
            foreach (var comp in toRemove)
            {
                renderVoxelVolumeDataList.Remove(renderVoxelVolumeData[comp]);
                renderVoxelVolumeData.Remove(comp);
                renderVoxelVolumes.Remove(comp);
            }
            //Create per-volume textures
            foreach (var pair in renderVoxelVolumes)
            {
                var volume = pair.Value;
                var bounds = volume.VoxelMatrix.ScaleVector;

                RenderVoxelVolumeData data;
                if (!renderVoxelVolumeData.TryGetValue(pair.Key, out data))
                {
                    data = new RenderVoxelVolumeData();
                    renderVoxelVolumeDataList.Add(data);
                    renderVoxelVolumeData.Add(pair.Key, data);
                }

                VoxelStorageContext storageContext = new VoxelStorageContext
                {
                    device    = Context.GraphicsDevice,
                    Extents   = bounds,
                    VoxelSize = volume.AproxVoxelSize,
                    Matrix    = volume.VoxelMatrix
                };

                volume.Storage.UpdateFromContext(storageContext, data);

                foreach (var attr in volume.Attributes)
                {
                    attr.PrepareLocalStorage(storageContext, volume.Storage);
                }
                volume.Storage.UpdateTempStorage(storageContext);

                ShaderSourceCollection AttributeIndirect  = new ShaderSourceCollection();
                ShaderSourceCollection AttributeModifiers = new ShaderSourceCollection();
                foreach (var attr in volume.Attributes)
                {
                    AttributeIndirect.Add(attr.GetShader());
                    attr.AddAttributes(AttributeModifiers);
                }
                if (AttributeModifiers != data.AttributeModifiers)
                {
                    data.AttributeModifiers = AttributeModifiers;
                }

                if (AttributeIndirect != data.AttributeIndirect)
                {
                    data.AttributeIndirect = AttributeIndirect;
                }
                data.VisualizeVoxels    = volume.VisualizeVoxels;
                data.Attributes         = volume.Attributes;
                data.Storage            = volume.Storage;
                data.StorageContext     = storageContext;
                data.VoxelizationMethod = volume.VoxelizationMethod;
                data.VoxelVisualization = volume.VoxelVisualization;
                data.Voxelize           = volume.Voxelize;

                data.ReprView = volume.VoxelizationMethod.CollectViews(VoxelStage, volume, storageContext, Context);

                ShadowMapRenderer?.RenderViewsWithShadows.Add(data.ReprView);
            }
        }
Example #14
0
 public void PrepareLocalStorage(VoxelStorageContext context, IVoxelStorage storage, int channels, int layoutCount)
 {
     storage.RequestTempStorage(TempStorageFormat.GetBits(channels) * layoutCount);
 }
Example #15
0
 public override void PrepareLocalStorage(VoxelStorageContext context, IVoxelStorage storage)
 {
     BufferOffset = VoxelLayout.PrepareLocalStorage(context, storage);
 }
Example #16
0
 public override void PrepareOutputStorage(VoxelStorageContext context, IVoxelStorage storage)
 {
     VoxelLayout.PrepareOutputStorage(context, storage);
 }
 public void Render(VoxelStorageContext storageContext, RenderDrawContext drawContext, RenderView view)
 {
 }
Example #18
0
        public void PostProcess(VoxelStorageContext storageContext, RenderDrawContext drawContext, ProcessedVoxelVolume data)
        {
            if (Math.Max(Math.Max(ClipMapResolution.X, ClipMapResolution.Y), ClipMapResolution.Z) < 32)
            {
                return;
            }
            if (FragmentsBuffer == null)
            {
                return;
            }
            var context = drawContext.RenderContext;

            if (ClearBuffer == null)
            {
                ClearBuffer = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(context)
                {
                    ShaderSourceName = "ClearBuffer"
                };
                BufferToTexture = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(context)
                {
                    ShaderSourceName = "BufferToTextureEffect"
                };
                BufferToTextureColumns = new Xenko.Rendering.ComputeEffect.ComputeEffectShader(context)
                {
                    ShaderSourceName = "BufferToTextureColumnsEffect"
                };
            }

            bool VoxelsAreIndependent = true;

            List <VoxelAttribute>  IndirectVoxels = new List <VoxelAttribute>();
            List <VoxelAttribute>  TempVoxels     = new List <VoxelAttribute>();
            ShaderSourceCollection Indirect       = new ShaderSourceCollection();
            ShaderSourceCollection Temp           = new ShaderSourceCollection();

            //Assign sample indices and check whether voxels can be calculated independently
            int sampleIndex = 0;

            foreach (var attr in data.Attributes)
            {
                attr.Attribute.LocalSamplerID = sampleIndex;
                VoxelsAreIndependent         &= !attr.Attribute.RequiresColumns();
                sampleIndex++;
            }

            //Populate ShaderSourceCollections and temp lists
            foreach (var attr in data.Attributes)
            {
                if (attr.Stage != VoxelizationStage.Post)
                {
                    continue;
                }
                if (attr.Output)
                {
                    Indirect.Add(attr.Attribute.GetVoxelizationShader());
                    IndirectVoxels.Add(attr.Attribute);
                }
                else
                {
                    Temp.Add(attr.Attribute.GetVoxelizationShader());
                    TempVoxels.Add(attr.Attribute);
                }
            }

            var BufferWriter = VoxelsAreIndependent ? BufferToTexture : BufferToTextureColumns;

            for (int i = 0; i < IndirectVoxels.Count; i++)
            {
                var attr = IndirectVoxels[i];
                attr.UpdateVoxelizationLayout($"AttributesIndirect[{i}]");
            }
            for (int i = 0; i < TempVoxels.Count; i++)
            {
                var attr = TempVoxels[i];
                attr.UpdateVoxelizationLayout($"AttributesTemp[{i}]");
            }
            foreach (var attr in data.Attributes)
            {
                attr.Attribute.ApplyVoxelizationParameters(BufferWriter.Parameters);
            }


            int processYSize = VoxelsAreIndependent ? (int)ClipMapResolution.Y : 1;

            processYSize *= (UpdatesPerFrame == UpdateMethods.SingleClipmap) ? 1 : ClipMapCount;

            BufferWriter.ThreadGroupCounts = VoxelsAreIndependent ? new Int3(32, 32, 32) : new Int3(32, 1, 32);
            BufferWriter.ThreadNumbers     = new Int3((int)ClipMapResolution.X / BufferWriter.ThreadGroupCounts.X, processYSize / BufferWriter.ThreadGroupCounts.Y, (int)ClipMapResolution.Z / BufferWriter.ThreadGroupCounts.Z);

            BufferWriter.Parameters.Set(BufferToTextureKeys.VoxelFragments, FragmentsBuffer);
            BufferWriter.Parameters.Set(BufferToTextureKeys.clipMapResolution, ClipMapResolution);
            BufferWriter.Parameters.Set(BufferToTextureKeys.storageUints, storageUints);

            BufferWriter.Parameters.Set(BufferToTextureKeys.clipOffset, (uint)(UpdatesPerFrame == UpdateMethods.SingleClipmap ? ClipMapCurrent : 0));


            //Modifiers are stored within attributes, yet need to be able to query their results.
            //Ideally a stage stream could resolve this, however due to the lack of pointers, there would be a cyclic dependency of AttributesList->Attribute->Modifier->AttributesList->...
            //So instead the results will be stored within a second array that only contains float4s. Unfortunately the only way to iterate through the AttributesList is by foreach, which
            //makes it difficult to access the results array (AttributeLocalSamples) by index. So instead it's just all done through this macro...
            string IndirectReadAndStoreMacro = "";
            string IndirectStoreMacro        = "";

            for (int i = 0; i < Temp.Count; i++)
            {
                string iStr           = i.ToString();
                string sampleIndexStr = TempVoxels[i].LocalSamplerID.ToString();
                IndirectReadAndStoreMacro += $"AttributesTemp[{iStr}].InitializeFromBuffer(VoxelFragments, VoxelFragmentsIndex + {TempVoxels[i].BufferOffset}, uint2({TempVoxels[i].BufferOffset} + initialVoxelFragmentsIndex, yStride));\n" +
                                             $"streams.LocalSample[{sampleIndexStr}] = AttributesTemp[{iStr}].SampleLocal();\n\n";
                IndirectStoreMacro += $"streams.LocalSample[{sampleIndexStr}] = AttributesTemp[{iStr}].SampleLocal();\n";
            }
            for (int i = 0; i < Indirect.Count; i++)
            {
                string iStr           = i.ToString();
                string sampleIndexStr = IndirectVoxels[i].LocalSamplerID.ToString();
                IndirectReadAndStoreMacro += $"AttributesIndirect[{iStr}].InitializeFromBuffer(VoxelFragments, VoxelFragmentsIndex + {IndirectVoxels[i].BufferOffset}, uint2({IndirectVoxels[i].BufferOffset} + initialVoxelFragmentsIndex, yStride));\n" +
                                             $"streams.LocalSample[{sampleIndexStr}] = AttributesIndirect[{iStr}].SampleLocal();\n\n";
                IndirectStoreMacro += $"streams.LocalSample[{sampleIndexStr}] = AttributesIndirect[{iStr}].SampleLocal();\n";
            }



            BufferWriter.Parameters.Set(BufferToTextureKeys.AttributesIndirect, Indirect);
            BufferWriter.Parameters.Set(BufferToTextureKeys.AttributesTemp, Temp);
            BufferWriter.Parameters.Set(BufferToTextureKeys.IndirectReadAndStoreMacro, IndirectReadAndStoreMacro);
            BufferWriter.Parameters.Set(BufferToTextureKeys.IndirectStoreMacro, IndirectStoreMacro);

            ((RendererBase)BufferWriter).Draw(drawContext);



            ClearBuffer.Parameters.Set(ClearBufferKeys.buffer, FragmentsBuffer);

            if (UpdatesPerFrame != UpdateMethods.SingleClipmap)
            {
                //Clear all
                ClearBuffer.ThreadNumbers     = new Int3(1024, 1, 1);
                ClearBuffer.ThreadGroupCounts = new Int3(FragmentsBuffer.ElementCount / 1024, 1, 1);
                ClearBuffer.Parameters.Set(ClearBufferKeys.offset, 0);
            }
            else
            {
                //Clear next clipmap buffer
                ClearBuffer.ThreadNumbers     = new Int3(1024, 1, 1);
                ClearBuffer.ThreadGroupCounts = new Int3((int)(ClipMapResolution.X * ClipMapResolution.Y * ClipMapResolution.Z * storageUints) / 1024, 1, 1);
                ClearBuffer.Parameters.Set(ClearBufferKeys.offset, (int)(((ClipMapCurrent + 1) % ClipMapCount) * ClipMapResolution.X * ClipMapResolution.Y * ClipMapResolution.Z * storageUints));
            }
            ((RendererBase)ClearBuffer).Draw(drawContext);
        }
Example #19
0
 virtual public int PrepareLocalStorage(VoxelStorageContext context, IVoxelStorage storage)
 {
     return(StorageMethod.PrepareLocalStorage(context, storage, 4, LayoutCount));
 }
Example #20
0
 public void PostProcess(VoxelStorageContext context, RenderDrawContext drawContext, ProcessedVoxelVolume data)
 {
 }
Example #21
0
 virtual public void PrepareOutputStorage(VoxelStorageContext context, IVoxelStorage storage)
 {
     storage.UpdateTexture(context, ref storageTex, StorageFormatToPixelFormat(), LayoutCount);
 }
Example #22
0
 public override void PrepareOutputStorage(VoxelStorageContext context, IVoxelStorage storage)
 {
     storage.UpdateTexture(context, ref SolidityTex, Graphics.PixelFormat.R8_UNorm, 1);
 }
 public override void PrepareOutputStorage(VoxelStorageContext context, IVoxelStorage storage)
 {
     storage.UpdateTexture(context, ref CoverageTex, Graphics.PixelFormat.R11G11B10_Float, 1);
 }
 public void PrepareLocalStorage(VoxelStorageContext context, IVoxelStorage storage)
 {
     StorageMethod.PrepareLocalStorage(context, storage, 4, 6);
     storage.UpdateTexture(context, ref IsotropicTex, Graphics.PixelFormat.R16G16B16A16_Float, 6);
 }
Example #25
0
 public abstract void PrepareLocalStorage(VoxelStorageContext context, IVoxelStorage storage);