예제 #1
0
    public JobHandle OnPerformCulling(BatchRendererGroup rendererGroup, BatchCullingContext cullingContext, BatchCullingOutput cullingOutput, IntPtr userContext)
    {
        if (!m_initialized)
        {
            return(new JobHandle());
        }

#if ENABLE_PICKING
        bool isPickingCulling = cullingContext.viewType == BatchCullingViewType.Picking;
#endif

        var splitCounts = new NativeArray <int>(cullingContext.cullingSplits.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
        for (int i = 0; i < splitCounts.Length; ++i)
        {
            var split = cullingContext.cullingSplits[i];
            splitCounts[i] = split.cullingPlaneCount;
        }

        var planes = FrustumPlanes.BuildSOAPlanePacketsMulti(cullingContext.cullingPlanes, splitCounts, Allocator.TempJob);

        BatchCullingOutputDrawCommands drawCommands = new BatchCullingOutputDrawCommands();
        drawCommands.drawRanges   = Malloc <BatchDrawRange>(m_drawRanges.Length);
        drawCommands.drawCommands = Malloc <BatchDrawCommand>(m_drawBatches.Length *
                                                              splitCounts.Length * 10); // TODO: Multiplying the DrawCommand count by splitCount*10 is NOT an conservative upper bound. But in practice is enough. Sorting would give us a real conservative bound...

        drawCommands.visibleInstances = Malloc <int>(m_instanceIndices.Length);
#if ENABLE_PICKING
        drawCommands.drawCommandPickingInstanceIDs = isPickingCulling ? Malloc <int>(m_drawBatches.Length) : null;
#endif

        // Zero init: Culling job sets the values!
        drawCommands.drawRangeCount       = 0;
        drawCommands.drawCommandCount     = 0;
        drawCommands.visibleInstanceCount = 0;

        drawCommands.instanceSortingPositions          = null;
        drawCommands.instanceSortingPositionFloatCount = 0;

        cullingOutput.drawCommands[0] = drawCommands;

        var visibilityLength   = (m_renderers.Length + 7) / 8;
        var rendererVisibility = new NativeArray <ulong>(visibilityLength, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);

        var cullingJob = new CullingJob
        {
            planes             = planes,
            splitCounts        = splitCounts,
            renderers          = m_renderers,
            rendererVisibility = rendererVisibility
        };

        var drawOutputJob = new DrawCommandOutputJob
        {
            batchID            = m_batchID,
            rendererVisibility = rendererVisibility,
            instanceIndices    = m_instanceIndices,
            drawBatches        = m_drawBatches,
            drawRanges         = m_drawRanges,
            drawIndices        = m_drawIndices,
            drawCommands       = cullingOutput.drawCommands
        };

        var jobHandleCulling = cullingJob.Schedule(visibilityLength, 8);
        var jobHandleOutput  = drawOutputJob.Schedule(jobHandleCulling);

        return(jobHandleOutput);
    }
예제 #2
0
    public JobHandle OnPerformCulling(BatchRendererGroup rendererGroup, BatchCullingContext cullingContext, BatchCullingOutput cullingOutput, IntPtr userContext)
    {
        if (!m_initialized)
        {
            return(new JobHandle());
        }

        BatchCullingOutputDrawCommands drawCommands = new BatchCullingOutputDrawCommands();

        drawCommands.drawRangeCount = 1;
        drawCommands.drawRanges     = Malloc <BatchDrawRange>(1);
        drawCommands.drawRanges[0]  = new BatchDrawRange
        {
            drawCommandsBegin = 0,
            drawCommandsCount = 1,
            filterSettings    = new BatchFilterSettings
            {
                renderingLayerMask = 1,
                layer              = 0,
                motionMode         = m_motionVectorTest ? MotionVectorGenerationMode.Object : MotionVectorGenerationMode.Camera,
                shadowCastingMode  = ShadowCastingMode.On,
                receiveShadows     = true,
                staticShadowCaster = false,
                allDepthSorted     = false
            }
        };

        drawCommands.visibleInstances = Malloc <int>(m_itemCount);
        int n       = 0;
        int radius  = (itemGridSize / 2) * (itemGridSize / 2);      // (grid/2)^2
        int radiusO = (radius * 90) / 100;
        int radiusI = (radiusO * 85) / 100;

        for (int r = 0; r < itemGridSize; r++)
        {
            for (int i = 0; i < itemGridSize; i++)
            {
                bool visible = true;
                if (m_cullTest)
                {
                    int dist = (r - itemGridSize / 2) * (r - itemGridSize / 2) + (i - itemGridSize / 2) * (i - itemGridSize / 2);
                    if ((dist >= radiusI) && (dist <= radiusO))
                    {
                        visible = false;
                    }
                }
                if (visible)
                {
                    drawCommands.visibleInstances[n++] = r * itemGridSize + i;
                }
            }
        }
        drawCommands.visibleInstanceCount = n;

        drawCommands.drawCommandCount = 1;
        drawCommands.drawCommands     = Malloc <BatchDrawCommand>(1);
        drawCommands.drawCommands[0]  = new BatchDrawCommand
        {
            visibleOffset       = 0,
            visibleCount        = (uint)n,
            batchID             = m_batchID,
            materialID          = m_materialID,
            meshID              = m_meshID,
            submeshIndex        = 0,
            splitVisibilityMask = 0xff,
            flags           = m_motionVectorTest ? BatchDrawCommandFlags.HasMotion : BatchDrawCommandFlags.None,
            sortingPosition = 0
        };


        drawCommands.instanceSortingPositions          = null;
        drawCommands.instanceSortingPositionFloatCount = 0;

        cullingOutput.drawCommands[0] = drawCommands;
        return(new JobHandle());
    }