public virtual void Draw(RenderDrawContext drawContext, Shadows.IShadowMapRenderer ShadowMapRenderer) { if (renderVoxelVolumes == null || renderVoxelVolumes.Count == 0) { return; } var context = drawContext; using (drawContext.PushRenderTargetsAndRestore()) { // Draw all shadow views generated for the current view foreach (var data in renderVoxelVolumeDataList) { if (!data.Voxelize) { continue; } RenderView voxelizeRenderView = data.ReprView; //Render Shadow Maps RenderView oldView = drawContext.RenderContext.RenderView; drawContext.RenderContext.RenderView = voxelizeRenderView; ShadowMapRenderer.Draw(drawContext); drawContext.RenderContext.RenderView = oldView; VoxelStorageContext storageContext = data.StorageContext; //Render/Collect voxel fragments using (drawContext.QueryManager.BeginProfile(Color.Black, FragmentVoxelizationProfilingKey)) { data.VoxelizationMethod.Render(storageContext, data.Storage, context); } //Fill and write to voxel volume using (drawContext.QueryManager.BeginProfile(Color.Black, ArrangementVoxelizationProfilingKey)) { data.Storage.PostProcess(storageContext, context, data); } //Mipmap using (drawContext.QueryManager.BeginProfile(Color.Black, MipmappingVoxelizationProfilingKey)) { foreach (var attr in data.Attributes) { attr.PostProcess(context); } } } } }
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 = MathF.Floor(matTrans.X); matTrans.Y = MathF.Floor(matTrans.Y); matTrans.Z = MathF.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); } } } } }
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); } } } } } }
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); } }