Closed GoogleCodeExporter closed 8 years ago
"This can be fixed by using high precision (highp) for floats in the Android
vertex shaders."
- Do you have a quick fix for this?
Original comment by Adam.Hon...@gmail.com
on 27 Mar 2012 at 1:54
Original comment by ShadowIs...@gmail.com
on 6 Sep 2012 at 6:12
@Kirill there is no such thing as "the Android vertex shaders". vertex shaders
are common to Desktop and Android.
highp is only supported on opengl es so we can't use it on desktop.
How do you suggest we handle this?
Should we have separated shaders for android?
Original comment by remy.bou...@gmail.com
on 22 Dec 2012 at 3:27
@remy: In the OGLES renderer, we specify the directive "precision mediump
float" in all shaders:
http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/android/co
m/jme3/renderer/android/OGLESShaderRenderer.java#777
This tells GLSL to use medium precision for all variables without a precision
qualifier - the spec defines mediump float as having a range of -16384 to
16384. This is TOO LOW for many types of applications, such as space
simulators, and in general will result in odd artifacts in some cases. For
proper rendering, jME3 must use highp float for all POSITION vectors, in the
vertex or fragment shader. This includes point light positions, vertex
positions, etc, such that subtracting or computing the direction between
position vectors provides a usable result. As a proper solution to this issue,
I recommend specifying the "precision mediump float" ONLY in fragment shaders,
and not specify ANY precision qualifier for the vertex shader. Under the GLSL
spec, the default precision qualifier in the vertex shader is highp float
(whereas for fragment shaders, you must declare it manually).
As a better fix to this issue, I recommend defining new datatypes that indicate
high precision, e.g.
#ifdef GL_ES
#define highpfloat highp float
#define highpvec2 highp vec2
#define highpvec3 highp vec3
#define highpvec4 highp vec4
#else
#define highpfloat float
#define highpvec2 vec2
#define highpvec3 vec3
#define highpvec4 vec4
#endif
These new datatypes shall be used in all shaders for position vectors, to
ensure accurate computations where they are required.
Original comment by ShadowIs...@gmail.com
on 26 Dec 2012 at 4:37
sounds good
Original comment by remy.bou...@gmail.com
on 26 Dec 2012 at 6:39
Or...we use shader nodes and just have a glslEsGenerator that append the
precision qualifier.
This way it will only be appended to the shader if it's used with opengles.
Since those qualifiers have no effect on non ES glsl, we don't need them there.
Users will be able to set the precision in the j3md declaration.
Original comment by remy.bou...@gmail.com
on 8 Feb 2013 at 2:48
I dug more into this issue.
Actually it may be more difficult than that.
The problem is, devices don't always support high precision float for the
fragment shader because the specs make it optional.
Also specs requirement for range and precision are very low (16 bit float
minimum for highp). So even highp may be not enough on some devices.
you can check what's supported with a gles call to glGetShaderPrecisionFormat.
I've checked and for example, my Asus transformer table does not support highp
for fragment shader.
It supports it for vertex and has a 23 bit precision range for highp, 13 for
meduimp and 8 for lowp.
My nexus 4 however, supports everything and has the same precision bit size for
every precision qualifier (24 bits). (i guess newer device will tend to do the
same)
On the glsl spec side, default precision for vertex shader are
precision highp float;
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;
and for fragment
precision mediump int;
precision lowp sampler2D;
precision lowp samplerCube;
Also quoting the specs :
"4.5.4 Available Precision Qualifiers
The built-in macro GL_FRAGMENT_PRECISION_HIGH is defined to one on systems
supporting highp
precision in the fragment language
#define GL_FRAGMENT_PRECISION_HIGH 1
and is not defined on systems not supporting highp precision in the fragment
language. When defined,
this macro is available in both the vertex and fragment languages. The highp
qualifier is an optional
feature in the fragment language and is not enabled by #extension."
From that I don't really get if we have to define it when the drivers claim to
support it or if it's automatically defined...
So default mediump float for fragment only sounds good.
On a side note, i've notice precision issue on the fragment side when you use
scaled texture coordinates with repeated textures, or animated textures (by
offsetting the coord with the g_Time).
Original comment by remy.bou...@gmail.com
on 20 Feb 2013 at 10:09
Isn't 23 bits precision 32-bit float? Regardless of that, jME3 should *always*
use highp for vertex or light positions. Once that is done the issue is
resolved as far as I am concerned.
Original comment by ShadowIs...@gmail.com
on 21 Feb 2013 at 4:21
idk for 23 precision bits with 32 bits floats, sounds like it yeah.
I committed a fix yesterday. Vertex shader now has the default precision (highp
float as mentioned in my comment), fragment shader float precision is
explicitely set to mediump.
but for now our shaders still use default precision.
Original comment by remy.bou...@gmail.com
on 21 Feb 2013 at 4:35
OK, I am marking it as fixed then.
Using different precision in the shader is a separate issue and is not related
to this one.
Original comment by ShadowIs...@gmail.com
on 21 Feb 2013 at 4:47
Original issue reported on code.google.com by
ShadowIs...@gmail.com
on 26 Mar 2012 at 7:34