LUT를 사용하여 모바일 장치의 삼각 헤비 쉐이더 속도 향상


10

이 쉐이더 를 실제로 오래된 iDevice와 결국 Android에서 실행 하려고합니다 .

조각 당 코드를 2 개의 사인 함수로 줄이더라도 셰이더는 약 20fps로 실행됩니다.

나는 오래된 쉐이딩 기술에 대한 책에서 잎을 가져 와서 미리 정의 된 많은 삼각 값을 보유하고 어쨌든 쉐이더를 근사화하는 데 사용하는 배열을 만드는 것을 고려했습니다.

위에 링크 된 셰이더에서 나는 삼각 함수에 전송 된 값을 반올림하여 마우스 왼쪽으로 더 내려간 상태에서 셰이더의 품질이 떨어지는 것을 이미 시뮬레이션하고 있습니다. 실제로 왼쪽에 가깝기 때문에 실제로는 매우 시원합니다. 완전히 다른 멋진 셰이더처럼 보입니다.

어쨌든 나는 두 가지 딜레마가 있습니다.

  1. GLSL 셰이더에서 상수 또는 균일 한 360 값의 배열을 갖는 가장 효율적인 방법은 무엇입니까?
  2. 0에서 360 사이의 각도를 원한다면 보통 같은 범위에 숫자를 넣는 방법을 알 수 없습니다 (예 GPU는 라디안을 사용한다는 것을 알고 있습니다).

    func range(float angle)
    {
       float temp = angle
       while (temp > 360) {temp -= 360;}
       while (temp < 0)   {temp += 360;}
       return temp;
    }
    

    그러나 GLSL은 while 루프 나 재귀 함수를 허용하지 않습니다.


나는 이것을 구현하는 것이 실용적 일지 모르지만, 사전 계산 된 사인 값이 불균일하게 간격을두고 사인 곡선의 기울기가 가장 가파른 곳에서 더 가깝게 클러스터링 된 값과 수평을 이루는 값이 더 적을 때 도움이 될 것입니다. 많이 변하지 않습니까? 이것은 많은 수의 값을 저장할 필요없이 필요한 곳에 더 높은 정확도를 허용합니까?
trichoplax

5
# 2와 관련하여 내장 mod기능 이 원하는 것입니다. 당신은 쓸 것 mod(angle, 360.0)입니다.
Nathan Reed

1
@ trichoplax 훌륭한 아이디어이지만 테이블에서 값을 찾는 방법을 모르겠습니다. 우리는 그것들을 더 집중된 배열로 넣었다고 가정 해 봅시다. 올바른 인덱스를 어떻게 찾을 수 있습니까?
J.Doe

6
3 채널 1D 텍스처에 값을 넣는 것은 어떻습니까? 이렇게하면 단일 텍스처 검색의 가격으로 죄, 사악함 및 황갈색을 얻을 수 있습니다. 0-2pi 각도를 0-1 UV로 매핑하고 반복 텍스처 모드를 사용하면 모드 호출이 필요하지 않으며 자동으로 '랩핑'되며 저장된 값 사이에서 선형 값으로 근사값을 얻을 수도 있습니다 가장 가까운 곳에 스냅.
russ

3
각도를 사용하지 않고 sin / cos 쌍으로 시작 및 종료하고 반각 등에 삼각 ID를 사용하여 형상에 사용될 때 삼각 함수를 제거 할 수있는 시간이 많이 있습니다.
ratchet freak

답변:


8

[0,360)[0,2π)

  • [0,360][0,1]
  • 루프와 같은 간격 조정을 수행 할 필요가 없다는 추가적인 이점이 있습니다 (하지만 루프가 필요하지 않고 모듈러스 연산 만 사용할 수 있음). GL_REPEAT텍스처의 줄 바꿈 모드로 사용 하면 인수> 1 (및 음수 인수와 마찬가지로)로 액세스 할 때 처음부터 다시 자동으로 시작됩니다 .
  • 또한 텍스처 필터 로 사용하여 기본적으로 무료로 (또는 거의 무료라고) 배열의 두 값 사이선형 보간 하는 이점을 얻습니다. 이렇게하면 GL_LINEAR저장하지 않은 값을 얻습니다. 보간 선형 물론 삼각 함수에 대한 100 % 정확한 것은 아니지만보다 확실히 낫다 없는 보간.
  • RGBA 텍스처 (또는 필요한 많은 구성 요소)를 사용하여 텍스처둘 이상의 값을 저장할 수 있습니다 . 이런 식으로 단일 텍스처 검색으로 죄와 죄를 얻을 수 있습니다.
  • [1,1][0,1]float sin = 2.0 * (texValue.r + texValue.g / 256.0) - 1.0;(또는 더 미세한 입자를위한 더 많은 구성 요소). 이를 통해 다중 구성 요소 텍스처를 다시 활용할 수 있습니다.

물론 이것이 더 나은 솔루션인지는 여전히 평가되어야합니다. 텍스처 액세스는 텍스처 크기와 형식의 최상의 조합뿐만 아니라 텍스처 액세스도 완전히 자유롭지 않기 때문입니다.

텍스처를 데이터로 채우고 주석 중 하나를 처리하는 것과 관련하여 텍스처 필터링은 텍셀 중심 에서 정확한 값 , 즉 텍셀 크기의 절반만큼 텍스처 좌표를 반환한다는 점을 고려해야합니다 . 따라서 texels 에서 값을 생성.5 해야합니다 . 예를 들어 응용 프로그램 코드에서 다음과 같습니다.

float texels[256];
for(unsigned int i = 0; i < 256; ++i)
    texels[i] = sin((i + .5f) / 256.f) * TWO_PI);
glTexImage1D(GL_TEXTURE_1D, 0, ..., 256, 0, GL_RED, GL_FLOAT, texels);

uniform float sinTable[361]glUniform1fv[0,360)mod

angle = mod(angle, 360.0);
float value = sinTable[int(((angle < 0.0) ? (angle + 360.0) : angle) + 0.5)];

1
룩업 테이블을 텍스처에 저장하는 흥미로운 확장 기능이 있습니다. (ab) N-linear texture interpolation을 사용하여 데이터 포인트, 표면, 볼륨 및 hypervolume의 높은 차수 보간 (일명 선형보다 우수)을 얻습니다. blog.demofox.org/2016/02/22/…
Alan Wolfe
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.