예제 #1
0
    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);
    }
예제 #2
0
    public TypedComputeBuffer <SwarmShaderSwarmerState> TryBuildSwarmersForRenderFrameIndex(
        int frameIndex)
    {
        // If the swarm needs to be advanced to the requested frame.
        if ((BehaviorComputeShader != null) &&
            (lastRenderedFrameIndex != frameIndex) &&
            particleSpatializer.IsInitialized)
        {
            DateTime currentTime = DateTime.UtcNow;

            bool applicationIsPaused =
#if UNITY_EDITOR
                EditorApplication.isPaused;
#else
                false;
#endif

            // The editor doesn't alter the timescale for us when the sim is paused, so we need to do it ourselves.
            float timeScale = (
                LocalTimeScale *
                (applicationIsPaused ? 0.0f : Time.timeScale));

            // Step ourselves based on the *graphics* framerate (since we're part of the rendering pipeline),
            // but make sure to avoid giant steps whenever rendering is paused.
            float localDeltaTime =
                Mathf.Min(
                    (float)(timeScale * (currentTime - lastRenderedDateTime).TotalSeconds),
                    Time.maximumDeltaTime);

            ParticleSpatializer.NeighborhoodResults swarmerNeighborhoods = BuildSwarmerNeighborhoods();

            audioShaderUniformCollector.CollectComputeShaderUniforms(BehaviorComputeShader);

            AdvanceSwarmers(localDeltaTime, swarmerNeighborhoods);

            lastRenderedFrameIndex = frameIndex;
            lastRenderedDateTime   = currentTime;
        }

        return(swarmerStateBuffers.CurrentComputeBuffer);
    }
예제 #3
0
    private void AdvanceSwarmers(
        float localDeltaTime,
        ParticleSpatializer.NeighborhoodResults swarmerNeighborhoods)
    {
        // Bind the swarmers.
        {
            BehaviorComputeShader.SetInt("u_swarmer_count", SwarmerCount);

            swarmerStateBuffers.SwapBuffersAndBindToShaderKernel(
                BehaviorComputeShader,
                advanceSwarmersKernel,
                "u_readable_swarmers",
                "u_out_next_swarmers");
        }

        // Bind the spatialization results.
        {
            BehaviorComputeShader.SetInt("u_voxel_count_per_axis", particleSpatializer.VoxelsPerAxis);
            BehaviorComputeShader.SetInt("u_total_voxel_count", particleSpatializer.TotalVoxelCount);

            BehaviorComputeShader.SetBuffer(advanceSwarmersKernel, "u_spatialization_voxel_particle_pairs", swarmerNeighborhoods.VoxelParticlePairsBuffer);
            BehaviorComputeShader.SetBuffer(advanceSwarmersKernel, "u_spatialization_voxels", swarmerNeighborhoods.SpatializationVoxelsBuffer);
            BehaviorComputeShader.SetBuffer(advanceSwarmersKernel, "u_spatialization_neighborhoods", swarmerNeighborhoods.NeighborhoodsBuffer);
        }

        // Bind the forcefields.
        {
            TypedComputeBuffer <SwarmShaderForcefieldState> forcefieldsComputeBuffer;
            int activeForcefieldCount;
            BuildForcefieldsBuffer(
                out forcefieldsComputeBuffer,
                out activeForcefieldCount);

            BehaviorComputeShader.SetInt("u_forcefield_count", activeForcefieldCount);

            BehaviorComputeShader.SetBuffer(advanceSwarmersKernel, "u_forcefields", forcefieldsComputeBuffer);
        }

        // Bind behavior/advancement constants.
        {
            BehaviorComputeShader.SetFloat("u_neighborhood_radius", SwarmerNeighborhoodRadius);
            BehaviorComputeShader.SetInt("u_max_neighbor_count", MaxNeighborCount);

            BehaviorComputeShader.SetFloat("u_swarmer_speed_min", SwarmerSpeedMin);
            BehaviorComputeShader.SetFloat("u_swarmer_speed_idle", SwarmerSpeedIdle);
            BehaviorComputeShader.SetFloat("u_swarmer_speed_max", SwarmerSpeedMax);
            BehaviorComputeShader.SetFloat("u_swarmer_speed_blending_rate", SwarmerSpeedBlendingRate);

            BehaviorComputeShader.SetFloat("u_swarmer_steering_yaw_rate", SteeringYawRate);
            BehaviorComputeShader.SetFloat("u_swarmer_steering_pitch_rate", SteeringPitchRate);
            BehaviorComputeShader.SetFloat("u_swarmer_steering_roll_rate", SteeringRollRate);
            BehaviorComputeShader.SetFloat("u_swarmer_steering_roll_uprighting_scalar", SteeringRollUprightingScalar);

            BehaviorComputeShader.SetFloat("u_swarmer_swim_upwards_blending_rate", SwimAnimation.UpwardsBlendingRate);
            BehaviorComputeShader.SetFloat("u_swarmer_swim_downwards_blending_rate", SwimAnimation.DownwardsBlendingRate);
            BehaviorComputeShader.SetFloat("u_swarmer_swim_idle_amplitude", SwimAnimation.IdleAmplitude);
            BehaviorComputeShader.SetFloat("u_swarmer_swim_idle_rate", SwimAnimation.IdleRate);
            BehaviorComputeShader.SetFloat("u_swarmer_swim_bursting_max_accel_input", SwimAnimation.BurstingMaxAccelInput);
            BehaviorComputeShader.SetFloat("u_swarmer_swim_bursting_amplitude", SwimAnimation.BurstingAmplitude);
            BehaviorComputeShader.SetFloat("u_swarmer_swim_bursting_rate", SwimAnimation.BurstingRate);
            BehaviorComputeShader.SetFloat("u_swarmer_swim_center_counter_rotation_amplitude_fraction", SwimAnimation.CenterCounterRotationAmplitudeFraction);
            BehaviorComputeShader.SetVector("u_swarmer_swim_center_counter_rotation_pivot_point", SwimAnimation.CenterCounterRotationPivotPoint);
            BehaviorComputeShader.SetVector("u_swarmer_swim_center_counter_rotation_pivot_axis", SwimAnimation.CenterCounterRotationPivotAxis);

            BehaviorComputeShader.SetFloat("u_neighbor_attraction_scalar", NeighborAttractionScalar);
            BehaviorComputeShader.SetFloat("u_neighbor_collision_avoidance_scalar", NeighborCollisionAvoidanceScalar);
            BehaviorComputeShader.SetFloat("u_neighbor_alignment_scalar", NeighborAlignmentScalar);

            BehaviorComputeShader.SetFloat("u_swarmer_model_scale", SwarmerModelScale);

            BehaviorComputeShader.SetVector("u_swarmer_model_left_segment_pivot_point", swarmerModel.SwarmerLeftSegmentPivotPoint);
            BehaviorComputeShader.SetVector("u_swarmer_model_left_segment_pivot_axis", swarmerModel.SwarmerLeftSegmentPivotAxis);
            BehaviorComputeShader.SetVector("u_swarmer_model_right_segment_pivot_point", swarmerModel.SwarmerRightSegmentPivotPoint);
            BehaviorComputeShader.SetVector("u_swarmer_model_right_segment_pivot_axis", swarmerModel.SwarmerRightSegmentPivotAxis);

            BehaviorComputeShader.SetFloat("u_swarmer_segment_pitch_effect_scalar", SegmentPitchEffectScalar);
            BehaviorComputeShader.SetFloat("u_swarmer_segment_roll_effect_scalar", SegmentRollEffectScalar);
            BehaviorComputeShader.SetFloat("u_swarmer_segment_max_angle_magnitude", (SegmentMaxAngleMagnitude * Mathf.Deg2Rad));
            BehaviorComputeShader.SetFloat("u_swarmer_segment_angle_blending_rate", SegmentAngleBlendingRate);

            BehaviorComputeShader.SetFloat("u_delta_time", localDeltaTime);
        }

        ComputeShaderHelpers.DispatchLinearComputeShader(
            BehaviorComputeShader,
            advanceSwarmersKernel,
            swarmerStateBuffers.ElementCount);
    }