Open dmnsgn opened 5 years ago
Couple of notes:
getMaxPrecision
is one of a kind API (getSomething), what about exposing capabilities.maxPrecision
and letting the user handle that for now? What would be better pex-context
way?
It seems that the getMaxPrecision(precision) function is coming from ThreeJS where they issue a warning if the max precision doesn't match the requested material precision.
Are we sure our aim is to support such devices with no highp
? Can we do some more research when using mediump
is beneficial?
I exposed the getMaxPrecision
as the user needs it when overriding a material with a certain precision. See:
I agree it feels slightly weird because it is one of a kind but I couldn't find a better way to make it accessible to pex-renderer without having to duplicate the gl precision check code. Only other acceptable way I see so far would be to make the function a separate package.
Are we sure our aim is to support such devices with no highp? Can we do some more research when using mediump is beneficial?
We encountered some mobile devices with only mediump
available on cx.
It seems that the getMaxPrecision(precision) function is coming from ThreeJS where they issue a warning if the max precision doesn't match the requested material precision.
We can add a warning as well or use a debug feature somehow.
I feel like we are trying to make things complicated here. In somehow controversial discussions like this one it's useful to think i case of scenarios.
From my understanding some older devices might not support highp
. I've never heard of a device not supporting mediump
. I would imagine the getShaderPrecisionFormat
for all precisions is there only for completeness.
I would suggest leaving only capabilities.maxPrecision
renamed tocapabilities.maxFragmentPrecision
. One issue with that is we introduce string values e.g. "highp". Those while same as glsl code should probably be enums (pex-context way). I assume strings are use for pex-renderer
convenience.
There is actually built-in glsl constant GL_FRAGMENT_PRECISION_HIGH
as explained in "How to write portable WebGL". So you can query highp availability in the shader:
#if GL_FRAGMENT_PRECISION_HIGH == 1
// highp is supported
#else
// high is not supported
#endif
That means we could potentially have matching
capabilities.fragmentPrecisionHigh = true/false
From my understanding some older devices might not support
highp
. I've never heard of a device not supportingmediump
. I would imagine thegetShaderPrecisionFormat
for all precisions is there only for completeness.
We can get rid of 'lowp'.
I would suggest leaving only
capabilities.maxPrecision
renamed tocapabilities.maxFragmentPrecision
. One issue with that is we introduce string values e.g. "highp". Those while same as glsl code should probably be enums (pex-context way). I assume strings are use forpex-renderer
convenience.
getMaxPrecision actually checks for both vertex and fragment precision (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT)
) so I would keep maxPrecision
. I am not aware of any case where it would be different from vert to frag but then why does the API exists in this way?
There is actually built-in glsl constant
GL_FRAGMENT_PRECISION_HIGH
as explained in "How to write portable WebGL". So you can query highp availability in the shader:#if GL_FRAGMENT_PRECISION_HIGH == 1 // highp is supported #else // high is not supported #endif
So that kind of make useless to have it in pex-context? We could just add a direct replacement if highp is not supported in pex-renderer shaders:
#ifndef GL_FRAGMENT_PRECISION_HIGH
#define highp mediump
#endif
varying highp vec3 vPositionWorld;
// would become
varying mediump vec3 vPositionWorld;
That means we could potentially have matching
capabilities.fragmentPrecisionHigh = true/false
You mean no ctx. capabilities.maxPrecision
but just ctx. capabilities.fragmentPrecisionHigh
instead?
https://google.github.io/filament/webgl/suzanne.html
No checks in GLSL but it doesn't mean they don't do them in JS. As mentioned in docs they default to mediump
but specify highp
for position related data attributes
#version 300 es
precision mediump float;
precision mediump int;
layout(std140) uniform FrameUniforms
{
highp mat4 viewFromWorldMatrix;
highp mat4 worldFromViewMatrix;
highp mat4 clipFromViewMatrix;
highp mat4 viewFromClipMatrix;
highp mat4 clipFromWorldMatrix;
highp mat4 worldFromClipMatrix;
highp mat4 lightFromWorldMatrix;
highp vec4 resolution;
highp vec3 cameraPosition;
highp float time;
Yes, only fragmentPrecisionHigh=true/false
. Eg. BabylonJS has highPrecisionShaderSupported
. This avoids confusion with maxFragmentPrecision
as gl.getShaderPrecisionFormat
is precision is not just high/med/low but high with 32 bits or high with 24 bits etc..
We would then use GL_FRAGMENT_PRECISION_HIGH
to fallback to mediump
when we write cross platform code in pex-renderer.
This flag would be used more for low end device sniffing than overwriting shader precisions as doing it automatically and globally most likely will not work and just cause artifacts to show up.
ctx.capabilities.maxPrecision
mediump
orlowp
precision
parameter allows override even if a higher precision is availableGround work for: https://github.com/pex-gl/pex-renderer/issues/122