Giter VIP home page Giter VIP logo

Comments (13)

GoodBoyDigital avatar GoodBoyDigital commented on April 28, 2024 3

found it! Will push a PR fix for this later today. 2000000 not a problem on either renderer now

from pixijs.

GoodBoyDigital avatar GoodBoyDigital commented on April 28, 2024

hey there! this was a conscious choice as we figured by limiting the complexity of the graphics - we could simplify the logic under the hood .

It would be good to understand the use case. Thanks!

from pixijs.

joergplewe avatar joergplewe commented on April 28, 2024

Hi Mat and thank you for caring.

Usecase: Many dashed/dotted lines.

I do so be using moveTo/lineTo pairs often on a Graphics for each gap/dash.
It worked fine with V7,

What jumps to my mind is that - reading the error message - 5000 moveTo/lineTo pairs require a 800.000.000 bytes buffer??
That is 160.000 bytes/pair. Sounds pretty much?
Second, just doing lineTo (without moveTo) can easily do 4.900.000 lines before buffer limits are reached.

In the end, it should look like this, rendered with v7:

image

This is the code:

import { Graphics, PointData } from "pixi.js";

function distance(p1: PointData, p2: PointData) {
  return Math.hypot(p2.x - p1.x, p2.y - p1.y);
}

export type DashGap = { dash: number, gap: number };

// V8 8.0.0-rc.11 moveTo/lineTo browser crash
// high numbers (>3000) of  moveTo/lineTo crash the browser
// https://github.com/pixijs/pixijs/issues/10265

export class DashedLine {
  startX = 0;
  startY = 0;
  dashGapIndex = 0;
  remaingDash = 0;
  remaingGap = 0;
  readonly #dashGaps: DashGap[];

  constructor(private graphics: Graphics, dashGaps: DashGap[], scale: number) {
    this.#dashGaps = dashGaps.map(dashGap => ({dash: dashGap.dash / scale, gap: dashGap.gap / scale}));
  }

  public moveTo(x: number, y: number) {
    this.dashGapIndex = 0;
    this.remaingDash = 0;
    this.remaingGap = 0;
    this.startX = x;
    this.startY = y;
  }

  public lineTo(x: number, y: number) {
    this.paint({x: this.startX, y: this.startY}, {x, y})

    this.startX = x;
    this.startY = y;
  }

  public paint(p1: PointData, p2: PointData) {
    const g     = this.graphics;
    const len   = distance(p1, p2);
    const norm  = { x: (p2.x - p1.x) / len, y: (p2.y - p1.y) / len };

    // start with the remaining gap
    let progress = this.remaingGap;

    // reduce remaining gap if line segment is very short and cannot complete the gap
    if (progress > len) {
      this.remaingGap = Math.max(0, this.remaingGap - len);
    }

    while (progress < len) {
      this.remaingGap = 0;
      const {dash, gap} = this.#dashGaps[this.dashGapIndex];

      g.moveTo(p1.x + progress * norm.x, p1.y + progress * norm.y);

      // set progress to the end of the dash
      progress += this.remaingDash || dash;

      if (progress > len) {
        // we cannot paint the dash completely
        this.remaingDash = progress - len;

        // do not paint beyond to end point
        progress = len;

        g.lineTo(p1.x + progress * norm.x, p1.y + progress * norm.y);
      } else {
        // switch dashgap only if the latest dash is complete
        this.dashGapIndex = ++this.dashGapIndex % this.#dashGaps.length;

        g.lineTo(p1.x + progress * norm.x, p1.y + progress * norm.y);

        // dash fully painted
        this.remaingDash = 0;

        // set progress to end of gap
        progress += gap;

        // can we complete the gap with this line segement?
        if (progress > len) {
          this.remaingGap = progress - len;
        }
      }
    }
  }
}

from pixijs.

GoodBoyDigital avatar GoodBoyDigital commented on April 28, 2024

this is super helpful - thanks for sharing this line drawing code - will have a play and get back to you! the buffer sizes do sound a bit high!

from pixijs.

joergplewe avatar joergplewe commented on April 28, 2024

The line drawing code finds a condensed, isolated form in the playground https://www.pixiplayground.com/#/edit/4M3bzWyTVU0_BFZLzD95I

from pixijs.

GoodBoyDigital avatar GoodBoyDigital commented on April 28, 2024

Hey @joergplewe - seems like a webGPU limitation rather than a pixi one. Using the WebGL renderer will provide a work around for now why we investigate at least!

https://www.pixiplayground.com/#/edit/4M3bzWyTVU0_BFZLzD95I

from pixijs.

joergplewe avatar joergplewe commented on April 28, 2024

Yeah thanks, that slightly shifts the limit from <2900 to <8200.

I did a crosscheck with a v7 version of the same, where the limit is well >2.000.000:

https://www.pixiplayground.com/#/edit/7pqux6HZlhr2M-wOaxhUw

(did you know that one cannot choose v7 version in the playground any more? I recycled on old one :) )

from pixijs.

GoodBoyDigital avatar GoodBoyDigital commented on April 28, 2024

looks like it WebGPU has a hard limit on buffers size. Figured most people would not need that much complexity in a single geometry!

perhaps i got that on wrong! For now, would this be enough to render your lines? (like as each full line is an individual graphics?)

thanks!

from pixijs.

GoodBoyDigital avatar GoodBoyDigital commented on April 28, 2024

oh, actually i think i can fix webGL easily.. will report back

from pixijs.

joergplewe avatar joergplewe commented on April 28, 2024

I'm optimistic finding a workaround.
Just ... why does that moderate set of moveTo/lineTo pairs require that huge buffersizes? While e.g. lineTo alone does not?

from pixijs.

GoodBoyDigital avatar GoodBoyDigital commented on April 28, 2024

i think there might be something wrong in how the buffer size is calculated for large graphics. Just verifying now

from pixijs.

joergplewe avatar joergplewe commented on April 28, 2024

Yeah, you are the man! :)

from pixijs.

GoodBoyDigital avatar GoodBoyDigital commented on April 28, 2024

haha! thanks :) - appreciate the help getting to the bottom of this one! Open source at its finest!

from pixijs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.