Three.js: UTF-8 material names cause glsl shader errors

Created on 20 Jul 2020  路  4Comments  路  Source: mrdoob/three.js

Description of the problem

Loading 3D models with non-ascii material names causes WebGL to throw the following error:

WebGL: INVALID_VALUE: shaderSource: string not ASCII
three.module.js:19048 THREE.WebGLProgram: shader error:  1281 35715 false gl.getProgramInfoLog invalid shaders THREE.WebGLShader: gl.getShaderInfoLog() vertex
ERROR: 1:1: '' : syntax error
1:  THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 1:1: '' : syntax error
1: 
WebGL: INVALID_OPERATION: useProgram: program not valid

This happens because of these two lines in WebGLProgram where the shader is composited:
https://github.com/mrdoob/three.js/blob/0de94ab9574097328db6cab0dddd98786bb16fca/src/renderers/webgl/WebGLProgram.js#L446
https://github.com/mrdoob/three.js/blob/0de94ab9574097328db6cab0dddd98786bb16fca/src/renderers/webgl/WebGLProgram.js#L575

The model I first noticed this on is available here https://nazrin.net/Hub/models/house.dae but it likely affects any model with non-ascii material names.

We're taking the shader name directly out of the material file and putting it into the shader. However, some models in the wild were authored by non-english-speakers, and they named their materials using special characters (in this case Japanese). OpenGL only started supporting unicode strings for shaders with version 4.20, anything before that (including WebGL) requires shaders to contain only ASCII characters.

Removing the #define SHADER_NAME line fixes the problem and the model renders as expected. It doesn't seem that define is used anywhere, possibly it's only there for debug purposes? My suggestion would be to either leave the line out, or do some sanitizing of the material names before putting them in the shader, but I'm curious to hear what everyone else thinks.

Three.js version
  • [x] Dev
  • [x] r118
  • [ ] ...
Browser
  • [x] All of them
  • [ ] Chrome
  • [ ] Firefox
  • [ ] Internet Explorer
OS
  • [x] All of them
  • [ ] Windows
  • [ ] macOS
  • [ ] Linux
  • [ ] Android
  • [ ] iOS
Hardware Requirements (graphics card, VR Device, ...)

Most helpful comment

Yep. My fault 馃槄
I think it'll be simpler to just revert that change.

All 4 comments

For reproduction: https://jsfiddle.net/b7op6yku/1/

Interesting that this issue did not pop up earlier^^.

or do some sanitizing of the material names before putting them in the shader

Maybe via encodeURIComponent()? https://jsfiddle.net/b7op6yku/

It looks like about 7 months ago there was a change to use parameters.shaderName rather than shader.name - not sure what the shader.name value looked like before the change, but perhaps it was an autogenerated name rather than coming straight from the model file?

https://github.com/mrdoob/three.js/commit/e1dc982cb9c39fe61f39667a4ecec99da7f0597c#diff-58e8247d21441c70f4f66e068eac5bfaL439

I think you are looking for this change: 7b361d7765a9527296315238fab747c273c27657

Yep. My fault 馃槄
I think it'll be simpler to just revert that change.

Was this page helpful?
0 / 5 - 0 ratings