Repository: pixijs/pixijs
File: src/culling/Culler.ts (TypeScript)

Code before:
     *     x: 0,
     *     y: 0,
     *     width: 800,
     *     height: 600
     * });
     *
     * // Culling to renderer screen
     * culler.cull(stage, renderer.screen, false);
     * ```
     * @remarks
     * - Recursively processes all cullable children
     * - Uses cullArea if defined, otherwise calculates bounds
     * - Performance depends on scene complexity
     * @see {@link CullingMixinConstructor.cullable} For enabling culling on objects
     * @see {@link CullingMixinConstructor.cullArea} For custom culling boundaries
     */
    public cull(container: Container, view: RectangleLike, skipUpdateTransform = true)
    {
        this._cullRecursive(container, view, skipUpdateTransform);
    }

    private _cullRecursive(container: Container, view: RectangleLike, skipUpdateTransform = true)
    {
        if (container.cullable && container.measurable && container.includeInBuild)
        {
            let bounds = new Bounds();

            if (container.cullArea)
            {
                const globalTL = container.toGlobal(
                    {
                        x: container.cullArea.x,
                        y: container.cullArea.y
                    },
                    new Point(),
                    skipUpdateTransform
                );

                const globalBR = container.toGlobal(
                    {
                        x: container.cullArea.x + container.cullArea.width,
                        y: container.cullArea.y + container.cullArea.height
                    },
                    new Point(),
                    skipUpdateTransform
                );

                bounds = new Bounds(globalTL.x, globalTL.y, globalBR.x, globalBR.y);
            }
            else
            {

Review comment (suggestion):
Since this code is called every frame on a render stage, it's worth making it allocation-free. 
You can reuse tempBounds and `Point.shared` to achieve zero allocations.

```typescript
const bounds = tempBounds;

if (container.cullArea) 
{
   const point = Point.shared;
   const cullArea = container.cullArea;

   // Top-left
   point.set(cullArea.left,  cullArea.top);
   container.toGlobal(point, point, skipUpdateTransform);

   bounds.minX = point.x;
   bounds.minY = point.y;

   // Bottom-right
   point.set(cullArea.right, cullArea.bottom);
   container.toGlobal(point, point, skipUpdateTransform);
 
   bounds.maxX = point.x;
   bounds.maxY = point.y;
} 
else 
{
   getGlobalBounds(container, skipUpdateTransform, bounds)
}
```

Code after:
     * // Basic culling with view bounds
     * const culler = new Culler();
     * culler.cull(stage, {
     *     x: 0,
     *     y: 0,
     *     width: 800,
     *     height: 600
     * });
     *
     * // Culling to renderer screen
     * culler.cull(stage, renderer.screen, false);
     * ```
     * @remarks
     * - Recursively processes all cullable children
     * - Uses cullArea if defined, otherwise calculates bounds
     * - Performance depends on scene complexity
     * @see {@link CullingMixinConstructor.cullable} For enabling culling on objects
     * @see {@link CullingMixinConstructor.cullArea} For custom culling boundaries
     */
    public cull(container: Container, view: RectangleLike, skipUpdateTransform = true)
    {
        this._cullRecursive(container, view, skipUpdateTransform);
    }

    private _cullRecursive(container: Container, view: RectangleLike, skipUpdateTransform = true)
    {
        if (container.cullable && container.measurable && container.includeInBuild)
        {
            if (container.cullArea)
            {
                tempRectangle.x = view.x;
                tempRectangle.y = view.y;
                tempRectangle.width = view.width;
                tempRectangle.height = view.height;

                const transform = skipUpdateTransform
                    ? container.worldTransform
                    : container.getGlobalTransform(tempMatrix, skipUpdateTransform);

                container.culled = !tempRectangle.intersects(
                    container.cullArea,
                    transform
                );
            }
            else
            {
                const bounds = getGlobalBounds(container, skipUpdateTransform, tempBounds);

                // check view intersection..
                container.culled = bounds.x >= view.x + view.width
                    || bounds.y >= view.y + view.height