WebGL에서 FPS 측정 코드를 설정하고 ( 이 SO answer 기반 ) 프래그먼트 셰이더의 성능과 약간의 차이점을 발견했습니다. 이 코드는 1024x1024 캔버스에 단일 쿼드 (또는 오히려 두 개의 삼각형)를 렌더링하므로 조각 매직에서 모든 마법이 발생합니다.
이 간단한 셰이더 (GLSL; 정점 셰이더는 단지 통과)를 고려하십시오.
// some definitions
void main() {
float seed = uSeed;
float x = vPos.x;
float y = vPos.y;
float value = 1.0;
// Nothing to see here...
gl_FragColor = vec4(value, value, value, 1.0);
}
따라서 이것은 흰색 캔버스를 렌더링합니다. 내 컴퓨터의 평균 약 30fps입니다.
이제 숫자 크 런칭을 늘리고 몇 옥타브의 위치 종속 노이즈를 기반으로 각 조각을 계산해 보겠습니다.
void main() {
float seed = uSeed;
float x = vPos.x;
float y = vPos.y;
float value = 1.0;
float noise;
for ( int j=0; j<10; ++j)
{
noise = 0.0;
for ( int i=4; i>0; i-- )
{
float oct = pow(2.0,float(i));
noise += snoise(vec2(mod(seed,13.0)+x*oct,mod(seed*seed,11.0)+y*oct))/oct*4.0;
}
}
value = noise/2.0+0.5;
gl_FragColor = vec4(value, value, value, 1.0);
}
위의 코드를 실행하려면 이 구현을snoise
사용 하고 있습니다.
이것은 fps를 7과 같은 것으로 만듭니다.
이제 이상한 부분은 다음과 같은 조건에서 노이즈 계산을 래핑하여 16 개 조각 중 하나만 노이즈로 계산하고 나머지는 흰색으로 남겨 둡니다.
if (int(mod(x*512.0,4.0)) == 0 && int(mod(y*512.0,4.0)) == 0)) {
// same noise computation
}
이 속도가 훨씬 빠를 것으로 예상되지만 여전히 7fps입니다.
한 번 더 테스트하려면 다음 조건부로 픽셀을 필터링하십시오.
if (x > 0.5 && y > 0.5) {
// same noise computation
}
이것은 이전과 정확히 같은 수의 노이즈 픽셀을 제공하지만 이제는 거의 30fps까지 백업됩니다.
무슨 일이야? 16 분의 1의 픽셀을 걸러내는 두 가지 방법이 정확히 같은 횟수의 사이클을 제공해서는 안됩니까? 그리고 왜 모든 픽셀을 노이즈 처럼 렌더링하는 것보다 느린 픽셀이 느린 가요?
보너스 질문 : 이것에 대해 어떻게해야합니까? 실제로 경우 끔찍한 성능 해결하려면 어떤 방법이 있나요 않는 몇 비싼 조각 내 캔버스 반점 싶어은?
(확실히 말해서, 실제 모듈로 계산은 흰색 대신 16 번째 픽셀을 검은 색으로 렌더링하여 프레임 속도에 전혀 영향을 미치지 않음을 확인했습니다.)