private void BuildUnsortedVoxelParticlePairs( int particleCount, TypedComputeBuffer <SpatializerShaderParticlePosition> particlePositionsBuffer, float voxelSize) { SpatializerComputeShader.SetInt("u_particle_count", particleCount); SpatializerComputeShader.SetInt("u_voxel_count_per_axis", VoxelsPerAxis); SpatializerComputeShader.SetFloat("u_voxel_size", voxelSize); SpatializerComputeShader.SetBuffer( kernelForBuildUnsortedVoxelParticlePairs, "u_particle_positions", particlePositionsBuffer); SpatializerComputeShader.SetBuffer( kernelForBuildUnsortedVoxelParticlePairs, "u_out_next_sorted_voxel_particle_pairs", voxelParticlePairBuffers.CurrentComputeBuffer); SpatializerComputeShader.SetBuffer( kernelForBuildUnsortedVoxelParticlePairs, "u_out_neighborhoods", neighborhoodsBuffer); // NOTE: We'll initialize all particles that the sort-algorithm is going to touch. // Any exccess/waste particles will be initialized such that they sort to the end of the buffer. int sortableParticleCount = CeilingToPowerOfTwo(particleCount); ComputeShaderHelpers.DispatchLinearComputeShader( SpatializerComputeShader, kernelForBuildUnsortedVoxelParticlePairs, sortableParticleCount); }
private void BuildForcefieldsBuffer( out TypedComputeBuffer <SwarmShaderForcefieldState> outPooledForcefieldsBuffer, out int outActiveForcefieldCount) { // Grab the oldest buffer off the queue, and move it back to mark it as the most recently touched buffer. TypedComputeBuffer <SwarmShaderForcefieldState> targetForcefieldsBuffer = forcefieldsBufferQueue.Dequeue(); forcefieldsBufferQueue.Enqueue(targetForcefieldsBuffer); swarmForcefieldCollector.CollectForcefields( transform.localToWorldMatrix, ref scratchForcefieldStateList); if (scratchForcefieldStateList.Count > targetForcefieldsBuffer.count) { Debug.LogWarningFormat( "Discarding some forcefields since [{0}] were wanted, but only [{1}] can be passed to the shader.", scratchForcefieldStateList.Count, targetForcefieldsBuffer.count); scratchForcefieldStateList.RemoveRange( targetForcefieldsBuffer.count, (scratchForcefieldStateList.Count - targetForcefieldsBuffer.count)); } targetForcefieldsBuffer.SetData(scratchForcefieldStateList.ToArray()); outPooledForcefieldsBuffer = targetForcefieldsBuffer; outActiveForcefieldCount = scratchForcefieldStateList.Count; }
private void ReleaseBuffers() { if (scratchParticlePositionsBuffer != null) { scratchParticlePositionsBuffer.Release(); scratchParticlePositionsBuffer = null; } if (neighborhoodsBuffer != null) { neighborhoodsBuffer.Release(); neighborhoodsBuffer = null; } if (spatializationVoxelsBuffer != null) { spatializationVoxelsBuffer.Release(); spatializationVoxelsBuffer = null; } voxelParticlePairBuffers.ReleaseBuffers(); if (DebugLoggingEnabled) { Debug.LogFormat("Compute buffers released."); } }
private ParticleSpatializer.NeighborhoodResults BuildSwarmerNeighborhoods() { TypedComputeBuffer <SpatializerShaderParticlePosition> scratchParticlePositionsBuffer = particleSpatializer.GetScratchParticlePositionsComputeBuffer(SwarmerCount); // Extract the swarmer positions so the spatializer can stay generic. { CommonSwarmComputeShader.SetInt("u_swarmer_count", SwarmerCount); CommonSwarmComputeShader.SetBuffer( kernelForExtractSwarmerPositions, "u_readable_swarmers", swarmerStateBuffers.CurrentComputeBuffer); CommonSwarmComputeShader.SetBuffer( kernelForExtractSwarmerPositions, "u_out_swarmer_positions", scratchParticlePositionsBuffer); ComputeShaderHelpers.DispatchLinearComputeShader( CommonSwarmComputeShader, kernelForExtractSwarmerPositions, SwarmerCount); } ParticleSpatializer.NeighborhoodResults result = particleSpatializer.BuildNeighborhoodLookupBuffers( SwarmerCount, scratchParticlePositionsBuffer, SwarmerNeighborhoodRadius); return(result); }
public bool TryAllocateComputeBuffersWithGarbage( int elementCount) { bool result = false; if (!SystemInfo.supportsComputeShaders) { Debug.LogError("Compute shaders are not supported on this machine. Is DX11 or later installed?"); } else { if (CurrentComputeBuffer == null) { CurrentComputeBuffer = new TypedComputeBuffer <ElementType>(elementCount); } if (PreviousComputeBuffer == null) { PreviousComputeBuffer = new TypedComputeBuffer <ElementType>(elementCount); } if ((CurrentComputeBuffer != null) && (PreviousComputeBuffer != null)) { result = true; } } return(result); }
private void ReleaseBuffers() { if (swarmerModelVerticesBuffer != null) { swarmerModelVerticesBuffer.Release(); swarmerModelVerticesBuffer = null; allocatedModelColorationType = null; allocatedModelShapeType = null; } if (DebugLoggingEnabled) { Debug.LogFormat("Compute buffers released."); } }
public NeighborhoodResults BuildNeighborhoodLookupBuffers( int particleCount, TypedComputeBuffer <SpatializerShaderParticlePosition> particlePositionsBuffer, float neighborhoodRadius) { ValidateSufficientParticleCount(particleCount); float voxelSize = (2.0f * neighborhoodRadius); #pragma warning disable 0219 // Warning that variable is assigned but never referenced (these variables are for inspection in the debugger). SpatializerShaderParticlePosition[] debugParticlePositions = null; SpatializerShaderVoxelParticlePair[] debugUnsortedParticlePairs = null; SpatializerShaderNeighborhood[] debugNeighborhoods = null; List <SpatializerShaderVoxelParticlePair[]> debugVoxelParticlePairsPerSortStep = null; SpatializerShaderVoxelParticlePair[] debugSortedParticlePairs = null; SpatializerShaderSpatializationVoxel[] debugSpatializationVoxels = null; #pragma warning restore 0219 if (DebugCaptureSingleFrame) { debugParticlePositions = particlePositionsBuffer.DebugGetDataBlocking(); } BuildUnsortedVoxelParticlePairs( particleCount, particlePositionsBuffer, voxelSize); if (DebugCaptureSingleFrame) { debugUnsortedParticlePairs = voxelParticlePairBuffers.CurrentComputeBuffer.DebugGetDataBlocking(); debugNeighborhoods = neighborhoodsBuffer.DebugGetDataBlocking(); } SortVoxelParticlePairs( particleCount, out debugVoxelParticlePairsPerSortStep); if (DebugCaptureSingleFrame) { debugSortedParticlePairs = voxelParticlePairBuffers.CurrentComputeBuffer.DebugGetDataBlocking(); } BuildSpatializationVoxels(particleCount); if (DebugCaptureSingleFrame) { debugSpatializationVoxels = spatializationVoxelsBuffer.DebugGetDataBlocking(); } // TODO: Export: particle indices, neighborhoods if (DebugCaptureSingleFrame) { DebugCaptureSingleFrame = false; #pragma warning disable 0168 // Warning that variable is assigned but never referenced (these variables are for inspection in the debugger). var allPerParticleValues = DebugParticleBufferCombinedEnumeration.ZipParticleBuffers( debugParticlePositions, debugUnsortedParticlePairs, debugNeighborhoods).ToArray(); var sortStepsDebug = DebugSortStepKeys(debugVoxelParticlePairsPerSortStep).ToArray(); #pragma warning restore 0168 Debug.Assert(DebugSortedVoxelParticlePairsAreValid( particleCount, debugSortedParticlePairs)); Debug.Assert(DebugSpatializationVoxelsAreValid( particleCount, debugSortedParticlePairs, TotalVoxelCount, debugSpatializationVoxels)); Debug.LogWarning("Finished debug-dumping the compute buffers. Surprised? Attach the unity debugger and breakpoint this line."); } var result = new NeighborhoodResults() { VoxelParticlePairsBuffer = voxelParticlePairBuffers.CurrentComputeBuffer, SpatializationVoxelsBuffer = spatializationVoxelsBuffer, NeighborhoodsBuffer = neighborhoodsBuffer, }; return(result); }
private bool TryAllocateBuffers() { bool result = false; if (!SystemInfo.supportsComputeShaders) { Debug.LogError("Compute shaders are not supported on this machine. Is DX11 or later installed?"); } else if (MaxParticleCount <= 0) { if (DebugLoggingEnabled) { Debug.LogFormat("Buffer-allocation silently aborted because we haven't yet been given a maximum particle count."); } } else if (SpatializerComputeShader != null) { kernelForBuildUnsortedVoxelParticlePairs = SpatializerComputeShader.FindKernel("kernel_build_unsorted_voxel_particle_pairs"); kernelForAdvanceSortOfVoxelParticlePairs = SpatializerComputeShader.FindKernel("kernel_advance_sort_of_voxel_particle_pairs"); kernelForBuildSpatializationVoxels = SpatializerComputeShader.FindKernel("kernel_build_spatialization_voxels"); if (scratchParticlePositionsBuffer == null) { scratchParticlePositionsBuffer = new TypedComputeBuffer <SpatializerShaderParticlePosition>(MaxParticleCount); } if (neighborhoodsBuffer == null) { neighborhoodsBuffer = new TypedComputeBuffer <SpatializerShaderNeighborhood>(MaxParticleCount); } if (spatializationVoxelsBuffer == null) { spatializationVoxelsBuffer = new TypedComputeBuffer <SpatializerShaderSpatializationVoxel>(TotalVoxelCount); } voxelParticlePairBuffers.TryAllocateComputeBuffersWithGarbage(MaxParticleCount); if (IsInitialized) { result = true; } else { // Abort any partial-allocations. ReleaseBuffers(); } } if (DebugLoggingEnabled) { Debug.LogFormat("Compute buffer allocation attempted. [Success={0}]", result); } return(result); }
private bool TryAllocateBuffers() { bool result = false; if (!SystemInfo.supportsComputeShaders) { Debug.LogError("Compute shaders are not supported on this machine. Is DX11 or later installed?"); } else { if (swarmerModelVerticesBuffer == null) { var swarmerModelVertices = new List <SwarmShaderSwarmerModelVertex>(); switch (ModelShape) { case ModelShapeType.SimpleFlatTriangle: { AppendFlatDoubleSidedTriangleVerticesToModel( 0.0f, // leftSegmentFraction 0.0f, // rightSegmentFraction ModelColoration, Matrix4x4.identity, ref swarmerModelVertices); break; } case ModelShapeType.TriamondWing: { AppendTriangularBifrustumVerticesToModel( 0.0f, // leftSegmentFraction 0.0f, // rightSegmentFraction ModelColoration, FacetType.Generic, // Front-left (before rotation). FacetType.Generic, // Front-right (before rotation). FacetType.Front, // Rear (before rotation). Matrix4x4.TRS( new Vector3( 0.0f, 0.0f, (1.0f - Mathf.Sin(30.0f * Mathf.Deg2Rad))), Quaternion.AngleAxis(180, Vector3.up), Vector3.one), ref swarmerModelVertices); AppendTriangularBifrustumVerticesToModel( 0.0f, // leftSegmentFraction 1.0f, // rightSegmentFraction ModelColoration, FacetType.Generic, // Front-left (before rotation). FacetType.Front, // Front-right (before rotation). FacetType.Rear, // Rear (before rotation). Matrix4x4.TRS( new Vector3( (1.0f * Mathf.Cos(30.0f * Mathf.Deg2Rad)), 0.0f, 0.0f), Quaternion.identity, Vector3.one), ref swarmerModelVertices); AppendTriangularBifrustumVerticesToModel( 1.0f, // leftSegmentFraction 0.0f, // rightSegmentFraction ModelColoration, FacetType.Front, // Front-left (before rotation). FacetType.Generic, // Front-right (before rotation). FacetType.Rear, // Rear (before rotation). Matrix4x4.TRS( new Vector3( (-1.0f * Mathf.Cos(30.0f * Mathf.Deg2Rad)), 0.0f, 0.0f), Quaternion.identity, Vector3.one), ref swarmerModelVertices); break; } default: throw new System.ComponentModel.InvalidEnumArgumentException(); } swarmerModelVerticesBuffer = new TypedComputeBuffer <SwarmShaderSwarmerModelVertex>(swarmerModelVertices.Count); swarmerModelVerticesBuffer.SetData(swarmerModelVertices.ToArray()); allocatedModelColorationType = ModelColoration; allocatedModelShapeType = ModelShape; } if (swarmerModelVerticesBuffer != null) { result = true; } else { // Abort any partial-allocations. ReleaseBuffers(); } } if (DebugLoggingEnabled) { Debug.LogFormat("Compute buffer allocation attempted. [Success={0}]", result); } return(result); }