Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line shaders not working on Chrome/Linux #6386

Open
1 of 17 tasks
davepagurek opened this issue Aug 31, 2023 · 5 comments
Open
1 of 17 tasks

Line shaders not working on Chrome/Linux #6386

davepagurek opened this issue Aug 31, 2023 · 5 comments

Comments

@davepagurek
Copy link
Contributor

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build Process
  • Unit Testing
  • Internalization
  • Friendly Errors
  • Other (specify if possible)

p5.js version

1.7.0

Web browser and version

Chrome 108

Operating System

Amazon Linux

Steps to reproduce this

At work we do some cloud rendering of p5 via Chome/Puppeteer in AWS Batch. I noticed that WebGL lines were not showing up in our cloud exports (left) compared to in-browser on Chrome for Mac (right):
image

This is a screenshot of chrome://gpu from the cloud environment (click to expand):

We were able to fix our issue by changing the precision in the line vertex/fragment shader to be highp instead of mediump:

precision mediump float;
precision mediump int;

As I only have access to my Mac locally, what I don't know is if this is an issue with our setup on AWS or if this is a general issue on Linux. Is anyone else able to run this on Chrome for Linux and let me know if the line renders for you or not? If this is a general issue, then maybe we should update the line shader. But it might be a bug specifically in the drivers for this environment.

Snippet:

function setup() {
  createCanvas(400, 400, WEBGL);
}

function draw() {
  background(220);
  noFill();
  strokeWeight(5);
  bezier(
    -100, 100,
    -50, -100,
    50, -100,
    100, 100
  );
}

Live: https://editor.p5js.org/davepagurek/sketches/rhLpTaCeX

@davepagurek davepagurek changed the title Line shaders not working on Line shaders not working on Chrome/Linux Aug 31, 2023
@limzykenneth
Copy link
Member

I'll have access to my Linux machine by end of next week and can help test this if no one else get to this before then. Just ping me in case I forgot.

@davepagurek
Copy link
Contributor Author

Thanks @limzykenneth!

@asukaminato0721
Copy link
Contributor

image

Brave 1.57.57 Chromium: 116.0.5845.163 (Official Build) (64-bit)
Revision d85db1f5df3b20ffecf96ab3f0dc7fca1d536955
OS Linux
JavaScript V8 11.6.189.19

@davepagurek
Copy link
Contributor Author

Thanks @asukaminato0721! Looks like this may be a very specific driver bug then. I'm going to close this issue, but in case anyone else needs to work around this for their specific setup, I added this chunk of code to use highp precision lines:

const prevGetLineShader = p5.RendererGL.prototype._getLineShader
p5.RendererGL.prototype._getLineShader = function () {
  if (!this._defaultLineShader) {
    this._defaultLineShader = prevGetLineShader.call(this)
    this._defaultLineShader._vertSrc = this._defaultLineShader._vertSrc.replace(
      /mediump/g,
      'highp',
    )
    this._defaultLineShader._fragSrc = this._defaultLineShader._fragSrc.replace(
      /mediump/g,
      'highp',
    )
  }

  return this._defaultLineShader
}

@davepagurek
Copy link
Contributor Author

davepagurek commented Jan 25, 2024

Hey, little update to this: since 7cf062d I've been finding that on AWS linux, the color shader also doesn't work reliably, and shapes are disappearing. This definitely feels like a driver bug, and the combination of using GL ES 300 + mediump precision is causing it to break. The solution for me was to adapt the above comment to just replace mediump with highp everywhere:

const shadersToReplace = [
  ['_getImmediateModeShader', '_defaultImmediateModeShader'],
  ['_getNormalShader', '_defaultNormalShader'],
  ['_getColorShader', '_defaultColorShader'],
  ['_getPointShader', '_defaultPointShader'],
  ['_getLineShader', '_defaultLineShader'],
  ['_getFontShader', '_defaultFontShader'],
]

for (const [method, cacheKey] of shadersToReplace) {
  const prevMethod = P5.RendererGL.prototype[method]
  p5.RendererGL.prototype[method] = function () {
    if (!this[cacheKey]) {
      this[cacheKey] = prevMethod.call(this)
      this[cacheKey]._vertSrc = this[cacheKey]._vertSrc.replace(
        /mediump/g,
        'highp',
      )
      this[cacheKey]._fragSrc = this[cacheKey]._fragSrc.replace(
        /mediump/g,
        'highp',
      )
    }

    return this[cacheKey]
  }
}

At least for this use case of mine of cloud exports, a way to tell p5 to use highp everywhere would be useful. Has anyone else encountered anything similar?

I think when I asked before if this is reproducible on Linux, that might not have been enough, since most? all? desktop drivers ignore mediump and use highp. Maybe we should be testing this on mobile to see if we notice anything, since that's typically where shader precision actually does something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants