2013-04-10 14 views
10

Próbuję utworzyć moduł cieniujący OpenGL ES 2.0, który generuje wiele gradientów zatrzymania wzdłuż jednej osi. Powinien interpolować wiele kolorów w punktach zdefiniowanych w procentach.Jak utworzyć wiele modułów cieniowania stopni gradientu stop?

mam to osiągnąć za pomocą if s shadera fragmentów, tak:

float y = gl_FragCoord.y; 
float step1 = resolution.y * 0.20; 
float step2 = resolution.y * 0.50; 

if (y < step1) { 
    color = white; 
} else if (y < step2) { 
    float x = smoothstep(step1, step2, y); 
    color = mix(white, red, x); 
} else { 
    float x = smoothstep(step2, resolution.y, y); 
    color = mix(red, green, x); 
} 

Mówią, że rozgałęzienia w fragment shader może zabić wydajność. Czy istnieje jakieś sprytne oszustwo, które może zostać użyte do interpolacji między wieloma wartościami bez używania if s? Czy rzeczywiście jest tego warte (jest to wysoce subiektywne, wiem, ale jako zasada)?

Aby zilustrować mój problem, pełne źródłowego (choć jeszcze krótkie) w ten link GLSL Sandbox: http://glsl.heroku.com/e#8035.0

+0

Jak rozumiem, wszystkie rdzenie procesora graficznego oczekują wykonania tej samej operacji w tym samym czasie. Jeśli masz gałęzie, istnieje ryzyko, że różne rdzenie będą musiały wykonywać różne operacje, a zatem niektóre rdzenie będą skutecznie blokowane. To właśnie zabija wydajność. Dobrą praktyką jest unikanie gałęzi w shaderów. –

Odpowiedz

6

Jeśli chcesz wyeliminować gałęzie można to zrobić następująco (zaczerpnięte z Heroku);

color = mix(white, red, smoothstep(step1, step2, y)); 
color = mix(color, blue, smoothstep(step2, step3, y)); 
color = mix(color, green, smoothstep(step3, resolution.y, y)); 

Ale nie jestem pewien, czy to jest szybsze niż czy/elses czy nie.

+0

Tego rodzaju odpowiedź właśnie szukałem! Jeśli mam problemy z wydajnością, przetestuję wydajność tych metod. – murgo

+1

Przykładowy przykład tego kodu: http://glslsandbox.com/e#39992.0 – neave

Powiązane problemy