2013-04-28 2 views
0

Mon terrain utilise un shader qui utilise lui-même quatre textures différentes. Il fonctionne bien sur les machines Windows et Linux, mais sur Android il obtient seulement ~ 25FPS sur les deux galaxies. J'ai pensé, que les textures sont le problème, mais non, car il semble que le problème est avec la partie où je divise les coordonnées de texture et utilise frac pour obtenir des coordonnées en mosaïque. Sans cela, je reçois 60FPS.Opération fracture très lente sur Galaxy SII et SIII

// Material data. 
//uniform vec3 uAmbient; 
//uniform vec3 uDiffuse; 

//uniform vec3 uLightPos[8]; 
//uniform vec3 uEyePos; 
//uniform vec3 uFogColor; 
uniform sampler2D terrain_blend; 
uniform sampler2D grass; 
uniform sampler2D rock; 
uniform sampler2D dirt; 

varying vec2 varTexCoords; 
//varying vec3 varEyeNormal; 
//varying float varFogWeight; 

//------------------------------------------------------------------ 
// Name: fog 
// Desc: applies calculated fog weight to fog color and mixes with 
// specified color. 
//------------------------------------------------------------------ 
//vec4 fog(vec4 color) { 
// return mix(color, vec4(uFogColor, 1.0), varFogWeight); 
//} 

void main(void) 
{ 
    /*vec3 N = normalize(varEyeNormal); 
    vec3 L = normalize(uLightPos[0]); 
    vec3 H = normalize(L + normalize(uEyePos)); 

    float df = max(0.0, dot(N, L)); 
    vec3 col = uAmbient + uDiffuse * df;*/ 

    // Take color information from textures and tile them. 
    vec2 tiledCoords = varTexCoords; 
    //vec2 tiledCoords = fract(varTexCoords/0.05); // <========= HERE!!!!!!!!! 
    //vec4 colGrass = texture2D(grass, tiledCoords); 
    vec4 colGrass = texture2D(grass, tiledCoords); 
    //vec4 colDirt = texture2D(dirt, tiledCoords); 
    vec4 colDirt = texture2D(dirt, tiledCoords); 
    //vec4 colRock = texture2D(rock, tiledCoords); 
    vec4 colRock = texture2D(rock, tiledCoords); 
    // Take color information from not tiled blend map. 
    vec4 colBlend = texture2D(terrain_blend, varTexCoords); 
    // Find the inverse of all the blend weights. 
    float inverse = 1.0/(colBlend.r + colBlend.g + colBlend.b); 
    // Scale colors by its corresponding weight. 
    colGrass *= colBlend.r * inverse; 
    colDirt *= colBlend.g * inverse; 
    colRock *= colBlend.b * inverse; 

    vec4 final = colGrass + colDirt + colRock; 

    //final = fog(final); 
    gl_FragColor = final; 
} 

Remarque: il y a un peu plus de code pour le calcul de la lumière et le brouillard, mais il n'est pas utilisé. J'ai indiqué la ligne qui, lorsqu'elle n'est pas commentée, provoque un décalage important. J'ai essayé d'utiliser le plancher et de calculer la partie fractionnelle manuellement, mais le décalage est le même. Quel pourrait être le problème?

EDIT: Maintenant, voici ce que je ne comprends pas.

Ce:

vec2 tiledCoords = fract(varTexCoords * 2.0); 

runs great.

Ce:

vec2 tiledCoords = fract(varTexCoords * 10.0); 

Runs moyen sur SIII.

Ce:

vec2 tiledCoords = fract(varTexCoords * 20.0); 

... sur les LAG

Ce:

vec2 tiledCoords = fract(varTexCoords * 100.0); 

bien 5fps est encore mieux que prévu ...

Alors qu'est-ce qui se passe? Pourquoi cela arrive-t-il? À ma connaissance, cela ne devrait faire aucune différence. Mais ça le fait. Et un énorme.

+0

Avez-vous essayé de supprimer la partie '' varTexCoords/0.05'' et de la remplacer par '' varTexCoords'' uniquement? De plus, vous pouvez le remplacer par '' varTexCoords * 20.0'' à la place. – harism

+0

Ce fut la première chose que j'ai essayé, changer la division à la multiplication n'a rien changé. – SMart

+1

Ce que je devine c'est que ce n'est pas l'appel '' fract'' mais les recherches de texture qui causent le décalage. Vous utilisez quatre recherches de texture après tout avec quatre textures différentes. Maintenant, si cela se produit de sorte que '' texture2D'' parvienne à mieux tamponner la texture avec '' varTexCoords * 2.0'' que '' varTexCoords * 10.0'', cela aurait beaucoup plus de sens (pour moi) que de blâmer un simple '' fract'' appel. Mais bien sûr, je devine. – harism

Répondre

0

Je voudrais exécuter votre code sur un profileur (vérifier Mali-400), mais par l'apparence de celui-ci, vous tuez le cache de texture. Pour le premier pixel calculé, toutes ces 4 recherches de texture sont récupérées, mais les données contiguës sont également récupérées dans le cache de texture. Pour le prochain pixel, vous n'accédez pas aux données dans le cache mais regardez assez loin (10, 20..etc) ce qui défie complètement le but d'un tel cache.

Ceci, bien sûr, sans profilage adéquat est difficile à dire.

EDIT: @harism vous a également indiqué cette direction.