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;

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.

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.