Adicionar um mix simples () destrói a taxa de quadros

7

Eu tenho um shader muito simples e adicionei nevoeiro linear via mix como este:

finalColor = mix(finalColor, vec3(0.5, 0.8, 0.95), vUVoutAndViewZ.z);

Observe que a distância Z da vista está na variável que também contém as coordenadas UV, portanto o nevoeiro nem adicionou um novo interpolador.

Ainda assim, essa linha inócua trouxe a taxa de quadros no OG Droid com o chipset Power SGX de 33fps para 22fps. Até o HTC Evo com a GPU Adreno 200 fica abaixo de 30fps. (O Adreno 205 está a 60fps constantes, mas isso é uma besta).

O próprio shader de fragmento é primitivo (todos os valores são codificados permanentemente, pois é um shader de teste):

precision mediump float;
varying mediump vec3 vUVoutAndViewZ;
varying lowp vec3 vNormalOut;

uniform lowp sampler2D diffuse;


void main() {
    lowp vec3 normal = vNormalOut;

    // Lighting
    lowp vec3 lightDir = vec3(0.5, 0.3, 0.5);
    lowp vec3 light = vec3(dot(normal, lightDir));

    lowp vec3 diffuse = texture2D(diffuse, vUVoutAndViewZ.xy).rgb;

    lowp vec3 finalColor = diffuse * light;

    // Fog
    finalColor = mix(finalColor, vec3(0.5, 0.8, 0.95), vUVoutAndViewZ.z);

    gl_FragColor = vec4(finalColor.xyz, 1.0);
}

Eu adicionei as declarações lowp / mediump mais tarde (que adicionaram cerca de 2fps), funciona tão ruim sem elas.

Recuso-me a acreditar que o chipset PowerVR é tão fraco que não consegue lidar com um shader simples como esse. Deve haver algo estúpido nesse sombreador (como algo implicitamente mexendo em um registro lowp) que apenas atrapalha completamente a unidade.

RESPOSTA e EDIÇÃO:

Ellis tem algumas informações fantásticas na resposta e nos comentários subsequentes. Nesse caso em particular, parece que mix () é totalmente quebrado. Ele trouxe o sombreador para 12 ciclos (de 4) e 4 GPRs (de 2). Voltei a 29fps usando este código:

lowp vec3 fogDiff = vec3(0.5, 0.8, 0.95) - finalColor;
fogDiff *= vUVoutAndViewZ.z;
finalColor += fogDiff;
EboMike
fonte
Você sabia que o nevoeiro não é linear com a profundidade? Se você não tem medo de adicionar a função pow ao shader, eu acho que você deveria tentar torná-lo mais realista;)
Notabene
@notabene: Estou ciente disso, mas como este post é sobre como um simples mix()matou a taxa de quadros, eu não estava muito inclinado a fazer um powpara acabar com isso.
EboMike

Respostas:

5

Resposta do EboMike calculada com o PVRUniSCo Editor: mix () leva o sombreador de 4 a 12 ciclos (PowerVR).

O PowerVR 530/535 é muito lento. O Andreno 200 e o PowerVR 530/535 são a primeira geração de GPU (OpenGL ES 2.x) para resolução hdpi. Você não pode redesenhar uma tela cheia a 60FPS com uma textura simples.

Eu escrevi o GPUBench para testar o desempenho dos shaders e é muito ruim nessas GPU. A segunda geração (Andreno 205, Powervr 540) é muito melhor.

Hoje, tento minimizar o fragmento shader com uma ou duas operações. Você pode tentar otimizar seu shader porque os compiladores GLSL são ruins (na plataforma móvel).

Nota: para powervr gpu, leia este documento . O PVRUniSCo Editor pode calcular ciclos usados ​​em shaders.

Meus durões:

  • A GPU Droid é mais lenta que o Andreno 200 por causa da taxa de preenchimento
  • 30 FPS para o Andreno 200 é bom
  • 20 FPS para Droid é bom
  • Você pode renderizar sua cena em um FBO menor e desenhá-lo em uma tela (mas o switch FBO é caro)
  • Os shaders de fragmentos devem ser muito curtos.
Ellis
fonte
Voce esta partindo meu coracao! E o HTC Evo? O Adreno 200 não seria capaz de lidar com isso? Mesmo para uma GPU fraca, isso parece irracionalmente patético.
EboMike
Meu objetivo é de 30fps pelo menos para o Droid e o EVO. Lembro-me vagamente de jogos como o Backbreaker que PARECERAM muito bonitos (já faz um tempo desde que o vi, posso estar errado). Qual é o segredo aqui? Não tenho overdraw, mal uso alfa blending e esse shader é primitivo. Você tem alguma ideia? (Btw, vai aceitar a resposta em poucas horas, não se preocupe :))
EboMike
30 FPS para Droid ou EVO é muito difícil. Essas GPU têm taxa de preenchimento muito baixa.
21411 Ellis
Não sei nada sobre chipsets gráficos para dispositivos móveis, mas não posso deixar de notar que você não explicou a parte mais interessante. Por que uma única linha diminui o desempenho de maneira tão dramática? É realmente uma operação de mistura lenta?
quer
2
Eu não tentei, mas você pode procurar no "PVRUniSCo Editor" os ciclos de instruções GLSL.
Ellis