2016-08-09 4 views
1

iOS 앱의 프래그먼트 셰이더에서 몇 가지 기본 최적화를 수행하고 있습니다. gl_FragColor에 몇 가지 색상 중 하나를 지정하고 싶습니다. 첫 번째 시도는 삼항 연산자를 사용했습니다. 이 시뮬레이터와 아이폰 5C 모두에서 제대로 일을 표시iOS에서의 조각 셰이더 동작

lowp float maxC = max(color.r, max(color.g, color.b); 
lowp float minC = min(color.r, min(color.g, color.b); 
gl_FragColor.rgb = (maxC > 1.0 ? result0 : (minC < 0.0 ? result1 : result2)); 

은 내가 덜 분기와 논리 위를 복제 할 수 있는지 확인하기 위해 mixstep의 조합으로 삼항 연산자를 대체하기 위해 노력했다. 불행하게도,이 시뮬레이터에서가 아니라 iOS 장비에서 작동 :

lowp float step0 = step(0.0, minC); 
    lowp float step1 = step(1.001, maxC); 
    lowp vec3 mix0 = mix(result1, result2, step0); 
    gl_FragColor.rgb = mix(mix0, result0, step1); 

는 특히, 시뮬레이터에서 제대로 그려 화면의 일부 흰색 영역이 장치에 검은 색 영역으로 잘못 그려집니다. 다른 모든 것은 괜찮아 보입니다.

위의 stepmix의 조합이 3 진수 연산자를 사용하는 접근법과 동일한 결과를 재현하지 못하는 이유는 무엇입니까?

답변

2

OpenGL 쉐이더에서 부동 소수점 연산의 정확한 내용을 이해하기 어려울 수 있습니다. 무슨 일이 벌어 질지에 관해서는, 삼항 연산자가 GLSL 컴파일러에 의해 제로 연산에 최적화되어 있다는 것입니다. 접는 조건을 곱하기 또는 다른 간단한 연산으로 변환하는 방법에 대한 정보는 avoiding-shader-conditionals을보십시오. 가장 유용한 유틸리티 함수는 다음 사용

float when_eq(float x, float y) { 
    return 1.0 - abs(sign(x - y)); 
} 

예가 될 것이다 : 위의 코드 VTEST의 현재 값에 의존하는 하나 V1 또는 V2 샘플 콘텐츠를 설정한다

float comp = 0.0; 
comp += when_eq(vTest, 0.0) * v1; 
comp += when_eq(vTest, 1.0) * v2; 

. 이 명시 적 구현을 ​​테스트하고 컴파일러에서 생성 된 3 진 impl을 테스트하여 어느 것이 더 빠르는지 확인하십시오.