p5.js
p5.js copied to clipboard
Line shaders not working on Chrome/Linux
Most appropriate sub-area of p5.js?
- [ ] Accessibility
- [ ] Color
- [ ] Core/Environment/Rendering
- [ ] Data
- [ ] DOM
- [ ] Events
- [ ] Image
- [ ] IO
- [ ] Math
- [ ] Typography
- [ ] Utilities
- [X] 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):
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:
https://github.com/processing/p5.js/blob/45ada83739efa51f6747fc037e95d4b7eb9b351f/src/webgl/shaders/line.vert#L21-L22
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
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.
Thanks @limzykenneth!
| Brave | 1.57.57 Chromium: 116.0.5845.163 (Official Build) (64-bit) |
|---|---|
| Revision | d85db1f5df3b20ffecf96ab3f0dc7fca1d536955 |
| OS | Linux |
| JavaScript | V8 11.6.189.19 |
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
}
Hey, little update to this: since https://github.com/processing/p5.js/commit/7cf062dc65204592d210041663e8d6a0cc468b5c 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?