[SOLVED]Qml OpenGL Shaders requirements
-
wrote on 25 Apr 2014, 22:44 last edited by
I made litle shaders example on Qml (QtQuick 2.2). It runs perfectly on my desktop. Then i deployed it on my phone (HTC One V, Android 4.1). All looks fine, but shader effect just draws pink rectangle instead of himself. Graphics processor on the phone Adreno 205, i believe. It supports OpenGL ES 2.0. So im interested if is it normal? Am i missing something? What is requirements of shaders?
-
On Desktop you are problably using OpenGL (not ES!) and on Android you are using OpenGL ES. They have different shader syntax.
-
wrote on 26 Apr 2014, 14:05 last edited by
Here is code, that i used:
@ ShaderEffect {
id: shader... <some code> .... fragmentShader: " #define M_PI 3.1415926535897932384626433832795 varying highp vec2 qt_TexCoord0; uniform lowp sampler2D source; uniform highp float range; uniform highp float maxRange; uniform highp float cX; uniform highp float cY; uniform highp float depth; uniform highp float shift; float f(float x) { return -sin(x/M_PI*10); } void main() { highp float x = qt_TexCoord0.x - cX; highp float y = qt_TexCoord0.y - cY; highp float r = sqrt( pow(y, 2) + pow(x, 2) ); if ( r < (range - depth) || r > (range + depth) ) return; highp float ang; highp float dr; ang = atan(y/x); if (x < 0) ang += M_PI; highp float k = (r - range) / depth; dr = f(k) * depth * shift * (1 - (r/maxRange)); highp float dx = dr * cos(ang); highp float dy = dr * sin(ang); highp vec4 texpixel = texture2D( source, vec2( qt_TexCoord0.x + 0, qt_TexCoord0.y + dy ) ); gl_FragColor = texpixel; } " }@
Can i use it on android? or what i need to use istead of it?
-
wrote on 29 Apr 2014, 08:13 last edited by
It should work, but try verifying your device with a simple shader first. (e.g. start with having nothing but the texture2D call, and once that's proven to work, try restoring the other calculations gradually)
-
Hi,
Try using medium precision.
-
wrote on 30 Apr 2014, 14:04 last edited by
[quote author="p3c0" date="1398761747"]Hi,
Try using medium precision.[/quote]
I made all lowp, no result.
@
varying highp vec2 qt_TexCoord0;
uniform highp sampler2D src;void main(void) { highp float x = qt_TexCoord0.x; highp float y = qt_TexCoord0.y; highp float dx = x * 0.1; highp vec4 texpixel = texture2D(src, vec2(x + dx, y) ); gl_FragColor = texpixel; }
@
This looks fine. Looking for bad code...
-
wrote on 30 Apr 2014, 16:40 last edited by
It toke frome me 1.5 hours to find out, that type conversion do not working on my phone. Had to replace 3 to 3.0, 0 to 0.0 etc. But picture on the phone looks like this anyway >_<
!http://data3.floomby.com/files/share/30_4_2014/18/1v0Yg5pYcEuzXlqVpF4NMw.png(screen)!
Shader itself looks fine, but not the picture under it... strange. Is it means phone just cant draw shaders properly? -
wrote on 30 Apr 2014, 17:24 last edited by
Got it! there was another compiler difference. I always have to initialize gl_FragColor.
This code works perfectly fine:
@ #define M_PI 3.14varying highp vec2 qt_TexCoord0; uniform mediump sampler2D source; uniform lowp float range; uniform lowp float maxRange; uniform lowp float cX; uniform lowp float cY; uniform lowp float depth; uniform lowp float shift; float f(float x) { return -sin(x/M_PI*10.0); } void main() { lowp float x = qt_TexCoord0.x - cX; lowp float y = qt_TexCoord0.y - cY; lowp float r = sqrt( x*x + y*y ); lowp float dx; lowp float dy; if ( r > (range - depth * 3.0) && r < (range + depth) ) { lowp float ang; lowp float dr; ang = atan(y/x); if (x < 0.0) ang += M_PI; lowp float k = (r - range) / depth; dr = f(k) * depth * shift * (1.0 - (r/maxRange)); dx = dr * cos(ang); dy = dr * sin(ang); } else { dx = 0.0; dy = 0.0; } lowp vec4 texpixel = texture2D( source, vec2( qt_TexCoord0.x + dx, qt_TexCoord0.y + dy ) ); gl_FragColor = texpixel; } @
Thanks all for helping!
-
wrote on 7 May 2014, 20:47 last edited by
all of these are no surprise. whatever driver you're using on desktop, it sucks. likely it's nvidia, and they let just about any bad-behavior code go..
if ( r < (range - depth) || r > (range + depth) ) return;
^ that should result in garbage data, which it did. either you always define gl_fragcolor, or you use discard and the fragment shader will not run for that fragment.(which could potentially result in garbage).
same with the explicit type usages, one should always be explicit in any type conversions. it's just the way glsl is, and nvidia is very annoying in the sense that they allow broken code.