コード例 #1
0
 public void AddAttributes(ShaderSourceCollection modifiers)
 {
     if (!Enabled)
     {
         return;
     }
     modifiers.Add(source);
 }
コード例 #2
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);
        }
コード例 #3
0
ファイル: VoxelRenderer.cs プロジェクト: hengtek/XenkoVoxelGI
        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);
            }
        }