Intereting Posts
Новая активность в Android «введите со стороны» Андроид – просто выцветать и исчезать в анимации для просмотра Наследование фрагментов Android Приложение не настроено для выставления счетов через Google Play О проекте android launchmode "singleTask" Как получить slf4j-android для оценки уровня ведения журнала Logcat? Вызов onBindViewHolder при прокрутке просмотра Recycler Android Espresso: как я могу протестировать определенный фрагмент при выполнении одного действия для нескольких фрагментарных архитектур Как отображать математические уравнения в Android Android: textColor отключенной кнопки в селекторе не отображается? Android – Пользовательский агент по умолчанию для URLConnection? Android не может получить текущую позицию (Appcelerator Titanium) Есть ли способ проверить, установлен ли будильник? Google-клавиатура испортила мой собственный диапазон В титане, можно ли получить доступ к файлам ресурсов (xml) сторонних баннеров из модуля android?

LibGDX – Shader работает на рабочем столе, но не на Android

Я написал простую программу, которая отображает сферу в 3d-среде и раскрашивает ее в соответствии с четырьмя источниками света вокруг сферы. Когда я запускаю программу на рабочем столе, она работает отлично, но на Android-устройстве сфера просто цветная.

Вот изображения, чтобы проиллюстрировать то, о чем я говорю:

Введите описание изображения здесь -> Рабочий стол

Введите описание изображения здесь -> Android

И вот код шейдера:

sphere.vert

#ifdef GL_ES precision mediump float; #endif uniform mat4 u_projectionMatrix; uniform mat3 u_normalMatrix; uniform mat4 u_modelViewMatrix; const int MAX_LIGHTS = 8; uniform int u_lights_active; uniform vec3 u_ambient; uniform vec3 u_position[ MAX_LIGHTS ]; uniform vec3 u_diffuse[ MAX_LIGHTS ]; uniform vec3 u_att_coeffs[ MAX_LIGHTS ]; // since builtins aren't used, we use attributes as substitute attribute vec2 a_texCoord0; attribute vec4 a_position; attribute vec3 a_normal; // outputs to fragment shader varying vec2 v_tex_coord; varying vec4 v_color; void main() { vec3 tempColor = u_ambient; vec3 ecPosition = vec3( u_modelViewMatrix * a_position ); vec3 viewVec = normalize( -ecPosition ); vec3 tnorm = normalize( u_normalMatrix * a_normal ); for ( int i = 0; i < u_lights_active; ++i ) { float dist = length( ecPosition - u_position[i] ); // distance from light to fragment float att = 1.0 / ( u_att_coeffs[i].x + u_att_coeffs[i].y*dist + u_att_coeffs[i].z*dist*dist ); vec3 lightVec = normalize( u_position[i] - ecPosition ); float diffuse = max( dot( lightVec, tnorm ), 0.0 ); tempColor += att * u_diffuse[i] * diffuse; } tempColor = clamp( tempColor, 0.0, 1.0 ); v_color = vec4( tempColor, 0.0 ); gl_Position = u_projectionMatrix * vec4( ecPosition, 1.0 ); v_tex_coord = a_texCoord0.xy; } 

sphere.frag

 #ifdef GL_ES precision mediump float; #endif uniform sampler2D u_texture; varying vec2 v_tex_coord; varying vec4 v_color; void main() { vec4 texColor = texture2D( u_texture, v_tex_coord ); gl_FragColor = texColor * v_color; } 

Я очень надеюсь, что один из вас, ребята, может объяснить мне, что я делаю неправильно.

Номера версий:

LibGDX: 0,9,8

ADT: Build v22.0.1-685705

Android-устройство: Sony Xperia S, Android 4.1.2

Цель проекта: Android 4.3, API 18

Mainfest содержит

 <uses-feature android:glEsVersion="0x00020000" android:required="true" /> 

Шейдер создан:

 shaderProgram = new ShaderProgram( Gdx.files.internal( "shaders/sphere.vert" ), Gdx.files.internal( "shaders/sphere.frag" ) ); if ( !shaderProgram.isCompiled() ) { Gdx.app.error( TAG, shaderProgram.getLog() ); } 

Сфера – это StillModel:

создание:

 final ModelLoaderHints hint = new ModelLoaderHints( true ); model = ModelLoaderRegistry.loadStillModel( Gdx.files.internal( "data/sphere.obj" ), hint ); texture = new Texture( Gdx.files.internal( "data/sphere_tex.png" ), Format.RGB888, false ); material = new Material( "mat", new TextureAttribute( texture, 0, "u_texture" ) ); 

рендеринг:

 shaderProgram.begin(); texture.bind( 0 ); shaderProgram.setUniformMatrix( C.U_PROJECTION_MATRIX, cam.projection ); // light values shaderProgram.setUniformi( C.U_LIGHTS_ACTIVE, lightsActive ); shaderProgram.setUniform3fv( C.U_LIGHT_AMBIENT, lightAmbient, 0, 3 ); shaderProgram.setUniform3fv( C.U_LIGHT_POSITION, lightPosition, 0, 3 * lightsActive ); shaderProgram.setUniform3fv( C.U_LIGHT_DIFFUSE, lightDiffuse, 0, 3 * lightsActive ); shaderProgram.setUniform3fv( C.U_LIGHT_ATT_COEFFS, lightAttCoeffs, 0, 3 * lightsActive ); modelMatrix.setToTranslation( positionWrap ); modelMatrix.rotate( rotationAxis, rotation ); modelMatrix.scale( scaleX, scaleY, scaleZ ); modelViewMatrix.set( cam.view ).mul( modelMatrix ); normalMatrix.set( modelViewMatrix ).inv().tra(); shaderProgram.setUniformMatrix( C.U_NORMAL_MATRIX, normalMatrix3x3.set( normalMatrix ) ); shaderProgram.setUniformMatrix( C.U_MODEL_VIEW_MATRIX, modelViewMatrix ); stillModel.render( shaderProgram ); shaderProgram.end(); 

Надеюсь, это вся необходимая информация.

Заранее спасибо!

Преобразование моего комментария в предположение в ответ:

Спецификация GLSL требует только поддержки очень простых циклов (очень «постоянных» границ цикла и т. Д.). См. Мой ответ for-loop в шейдерном коде, работающем с жестко запрограммированным номером, но не с однородной переменной

В вашем случае вы, вероятно, можете исправить это, всегда перебирая MAX_LIGHTS и просто увеличивая воздействие неактивного света на 0 (или убедитесь, что настройки неактивных огней равны нулю или все 1.0 или что-то другое делает их неэффективными).

Обратите внимание, что добавление ветки внутри цикла для «пропустить» ненужную работу может быть медленнее из-за того, как выполняются пиксельные шейдеры (в параллельном исполнении SIMD). Попробуйте, чтобы все пиксели всегда выполняли ту же последовательность инструкций.