블로그 이미지
자신의 단점을 메꾸는 것을 단(鍛)이라 하고 자신의 강점을 갈고 닦는 것을 련(鍊)이라 하여, 두가지를 합친 것을 단련이라고 부른다. 붕대마음

카테고리

전체목록 (667)
참고사이트 (8)
Goal (4)
Travel (10)
My Life (105)
Game (35)
Game Review (7)
Game Plan (0)
Books (5)
English (1)
Optimizing (12)
Study (218)
유용한 것들_etc (44)
유용한 것들_func (20)
Unity (48)
Unreal (87)
작업장 (54)
RenderMonkey (6)
정리요망 (1)
따라잡기 시리즈 (0)
링크용 (0)
Total344,974
Today26
Yesterday53

'Study'에 해당되는 글 218건

  1. 2019.08.16 Specular Showdown in the Wild West
  2. 2019.06.15 Clipmaps
  3. 2018.10.12 shader에서 if 와 lerp의 성능은?
  4. 2018.08.29 early z
  5. 2018.07.20 hlod
  6. 2018.03.10 What is Texture
  7. 2018.02.21 texture format
  8. 2018.02.13 shader에서 채널값이 모자를 때...
  9. 2018.02.10 2018-02-10
  10. 2018.02.04 2018-02-03

원문 : https://blog.selfshadow.com/2011/07/22/specular-showdown/

개인 공부를 위해 번역하였으며 원문을 읽길 적극 추천합니다.


요즘 엘리어싱 문제로 고민이 많다.

기존 사용하던 fxaa 대신  smaa로 바꿔서 사용하고 있긴 한데 그럼에도 불구하고 specular에 의한 반짝임은

도저히 고칠수가 없었다.

몇가지 아이디어를 테스트 해보기도 했다.

specular의 power, intensity를 거리 또는 pixel의 depth를 기반으로 한 감쇠정도가 그나마 괜찮았다.

그리고 구글링중 괜찮은 내용이 있어 번역했다.

번역은 적당히 했으니 원문을 추천.!!


// 이 색상은 개인적으로 추가한 내용.


말에 안장을 얹자!

이 글에서는 잘 동작하는 specular lighting을 위해 기존 방법들을 검토할 거다.

그리고 추가적으로, 현재 게임 라이팅 접근과 콘솔 메모리 제약의

간단한 변형에 대해서도 다룰 것이다.


잘 동작한다는 건 어떤 의미일까?

울퉁불퉁한 표면에 반짝이는 specular 하이라이트를 피하는 것 뿐만 아니라

먼 거리에서 올바른 외관을 얻는것에 대해 이야기 한다.

개별적인 주름과 불규칙성들은 너무 작아서 이러한 울퉁불퉁한 효과를 나타내기 어렵다.

주어진 예산으로 이러한 모든 것들을 처리 할 수 있을까?

이것들을 알아내기 위해 여행을 떠나보자!


좋음, 나쁨, 그리고 이상함.

어떤 날은 비디오게임 렌더링에 속해있는 우리들이 카우보이 무리처럼 느껴질 때가 있다.

우리는 화면에 제시간에 맞게 물체들을 올리기 위해 법칙에 맞게 빠르고 느리게 플레이 하며

우리와 아티스트가 원하는 모양을 만들기 위해 픽셀과 다툰다.


최근에 우리는 선형 라이팅(linear lighting)과 물리 기반음영모델(physically basedshading models)을 채택하여 

몇가지 잘못된 것들을 바로잡고 있었다.

이 부분은 더 발달해 있는 영화계에서조차 최근에서야 전환하고 있는 추세이다.

이러한 것들이 다 좋기는 하지만, 앞서나가거나 거친 서부시대가 끝났다고 믿기 전에, 

잘 대처해야 하는 중요한 영역이 있다 : 엘리어싱


Dan Baker가 당당히 주장했던 것 처럼, 엘리어싱은 실시간을 다루는 사람들과 오프라인을 다루는 사람들을

사이를 구별하는 중요한 요소다.

문제부분에 좀 더 많은 샘플을 할 여유는 있겠지만, 무거운 슈퍼샘플링은 우리한테는 너무 느리다.

(실제로 나는 링크4의 내용을 구현해 보지는 않았지만, 현재 콘솔에서 잘 동작하지 않을 것이라 생각한다)

MSAA 또한 외곽 엘리어싱만 처리하니 효과적이지 않고, 음영의 샘플링 내부에서 아티펙트가  생긴다.

specular 반짝임이 대표적인 예다.

후처리 AA(현재 많은 잠재적인 옵션이 있음, 링크5 참고)는 카메라나 물체가 움직일 때 

생기거나 사라지는 선명한 하이라이트를 해결하지 못하기 때문에 실제로 도움이 되지 않는다.

마지막으로, temporal AA가 해결책이 될지도 모른다고 생각하겠지만, 이는 시간적 일관성에 대한

의존도가 높아짐에 따라 프레임 전반에 걸친 저렴한 수퍼 샘플링일 뿐이다.


요약하자면, 우리가 게임에서 사용하는 기본적인 AA기술은 반짝이는 것을 막는것에, 

특히 높은 specular power일 경우에서는 그다지 쓸모있지 못하며 우리가 원하는 

거리를 기반으로 우리가 원하는 결과를 만들어 내지 못한다.

성능부분은 제외하고, 커스텀 텍스쳐 필터링과 함께 난해한 수의 샘플을 사용하지 않는다면 

수퍼샘플링조차도 부족하다고 의심되며, 그렇지 않다면 bump정보는 평균화되어 사라진다.

(전체적으로는 아니지만 나중에 자세히 설명)


다른 선택지가 있을까?

예전 컨퍼런스에서, Dan은 일반적으로 개발자들이 사용하는 두가지 해결방법에 대해 다루었는데,

거리에 따라 울퉁불퉁함(bumpiness)이나 광택(glossiness)를 줄이는 것이다.

첫번째 방법인 bump를 줄이는건 우리가 원하는 것과 반대의 개념이기 때문에 실제로 잘못되었고,

카메라에서 멀어질 때 울퉁불퉁한 표면이 흐릿해 보이게 하는 것 보다는

법선맵을 평평하게 하는 것이 보다 더 광택이 생긴다.

대신에, specular power를 (첫번째 근사치) 줄이는 것은 옳은 방법이다.

비록 경우에 따라 조정(tweak)해야 하고 울퉁불퉁지역과 평평한 지역 모두에서 normal map이

정확하게 동작하지는 않지만, 단순한 엘리어싱을 사용하거나 높은 power를 피하는 것 보다는 낮다.

텍스쳐 공간 라이팅에 대해서 이야기 하고 싶지만, 이는 자체적으로 문제가 있는 

또 다른 중대한 대안이므로 여기서는 더이상 논의하지 않겠다.


모두들, 제대로 동작하지 않는 스펙큘러와 못생긴 반짝임을 그냥 체념해 버려야 할까?

만약 마을에 보안관이 새로 온다면 아닐지도 모르지....


거리 청소

LEAN Mapping은 각계각층의(확대율에 예외가 있을수 있는데 이 부분에 대해선 나중에 좀 더 이야기 함)

specular 하이라이트를 강력하게 필터링 하기 위한 최신 접근 방식이다.


이 기술은 거리에 따라 표면의 거친정도의 거시적 효과를 잘 나타낼 뿐 아니라, 

-심지어 능선이 있는 법선맵 (ridged normal map)으로부터 이방성 하이라이트를 생성-

런타임에 동적 범프 레이어 결합을 지원한다. (부하는 좀 더 들지만 더 자연스러워진다.)


실제로 어떻게 동작하는지 자세히 알아볼 여유는 없지만, -자세히 보고자 한다면 아래 링크를 참조-

수많은 이전 기술들에 비교해 글의 말미에 있는 해결책이 좀 더 현실적이라는건 명확하다.

어쨌든 Civilization V(문명 5)에 적용되었고, 내가 경험해 보기로는 어느정도 인상적인 결과였다.


그렇긴 하지만, 바로 광범위하게 적용하기에 몇가지 문제점이있다.

- 많은 저장공간이 필요.

- 이방성, 접선공간 Beckmann 공식


우선 저장공간에 대한 요구사항은 지금당장 많은 개발자에게 제한요소가 될 것이다.

Lean매핑은 표준 normal map대신 두개의 텍스처가 더 필요하며(그리고 아마 레이어를 결합하기 위해 더 필요할지도..),

Variance Shadow Maps과 비슷한 이유인 성가신 정밀도 조건에 의해 오버헤드가 발생한다.

Firaxis는 경우에 따라 채널당 8비트 저장공간으로 압축 작업을 수행했지만, 논문에서는 아래와 같이 조언했다.

"일반적으로, 8비트 텍스쳐는 속도나 공간에 절대적으로 필요한 경우에만 의미가 있다."


당연하게도, 이 기술은 현재 콘솔에서 normal map을 위한 가장 일반적인 크로스 플랫폼 형식 중 하나 인

DXT1 또는 DXT5에서 사용할 수 없다.

이에 비해, 저장공간 비용은 최소 8배가 될 수 있다.( 핵심 LEAN 조건에서 normal이 복구되고 

다른 데이터가 그 자리에 포함 된 경우)


지연(deffered) 렌더링을 쓸 경우 더욱 거칠어지는데,

G버퍼의 공간은 일반적으로 부족하며 설상가상으로 조명 공식은 더욱 복잡해 진다

모든것을 공통 공간(예를 들자면 월드 공간같은)으로 옮길 수 있다고 가정하더라도,

여전히 추가 접선 벡터를 저장해야 한다.

또한 LEAN 매핑과 관련된 수학적인 내용이 더 있으며 이는 환경에 라이트를 드리우기 위해 

어떤 선택을 할지와 별개로 고려해야할 또 다른 중요한 사항이다.


그래서 전반적으로 보자면, 대체품이 처음 나타나는 것은 아니다.

다행스럽게도 보안관은, 더 빠른 draw가 가능한 대리자가 있다.

올해 GDC에서 Dan은 저렴한 버전인 Clean(저렴한 LEAN) Mapping을 발표했다.

낮은 저장 공간(대략 절반정도)과 약간 더 높은 퍼포먼스를 위해 이방성을 희생한다.

이는 중요한 개선이며 이방성을 잃으면 효율적으로 두번째 문제를 해결하지만,

DXT에 대한 영역은 여전히 내 취향에 맞지 않는다.


내가 정말 좋아하는 것은 예술품들을 심각하게 "재평가"할 필요 없이 자유롭게 적용하는 것이다.

(그리고 물론, 다른 부분에서 삭감하는 것을 의미한다.)

내 말을 오해하지 마라, LEAN 매핑은 실제로 흥미로운 진보라고 생각한다.

나느 현 세대의 콘솔에서 와일드 한 것을 포기하는 현 상태로 사용하는 것을 기대하지는 않는다.

그러나 문명5의 물의 경우 처럼 특정한 상황에서 적절히 사용하면 훌륭한 옵션이다.


더 저렴한 방법이 필요하다.

투자대비 더 높은 효율을 얻을 방법이 있을까?

실제로 2004년에 Michael Toksvig가 LEAN 매핑과 비슷하게 밉매핑의 이점과 하드웨어 텍스쳐 필터링을 활용하지만

이미 존재하는 normal map에서 저장되어 있는 normal 벡터의 평균 길이로부터 직접 범프 편차를 측정하는

매우 간단한 기법을 제시했다.

일반적으로 명명된 이름이 아직 없기에 그냥 Toksvig AA라고 부르겠다.


문서에서, 기존 블린 퐁 공식은 아래와 같다.



Na는 텍스쳐에서 읽은 평균법선값이며, 이로부터 Toksvig Factor라고 부를 ft값을 얻는다.

그리고나서 스펙큘러 지수(specular exponent)인 s를 조절하는데 사용하고, 이 값(s)은 분산에 따른

전체강도를 조절한다.(거친정도)


여기 위 식을 간단하게 트윅한 코드버전이 있다.

float len = length(Na);

float ft = len/lerp(s, 1, len);  // 텍스쳐의 평균값(Na)이 1에 가깝다는 말은 각 텍셀에 저장된 벡터의 방향이 비슷하다는 뜻.

float scale = (1 + ft * s) / (1 + s);

float spec = scale * pow(saturate(dot(Na,H))/len, ft*s);

// 결국 스펙큘러 지수를 평균법선값을 기반으로 조절하겠다는 뜻.


원래 버전에서는 이 모든것들이 dot(Na, H)와 dot(Na, Na)로 인덱스화된 2D LUT에 저장되는데,

이 경우 Clamp 텍스쳐 주소 모드는 saturate()를 처리해 준다.

LUT는 픽셀 셰이더 2.0 이하 버전을 쓰던 옛날에는 의미가 있었지만, 현재 우리는 셰이더에서

그냥 바로 판별 할 수 있기 때문에 스펙큘러 지수당 LUT는 필요 없고, 그럼 으로 인해 

잠재적인 캐시 와 정밀도 문제를 피할 수 있다.


방정식의 첫번째 부분인  또한 한 방향으로만 에너지 보존을 처리하기 때문에 

약간 가짜의 느낌이 나며, 1은 실제로 2가 되어야 한다고 확신한다.

내가 정말 원하는건 블린 퐁을 정규분포함수(NDF)로 취급하는 것이다.



이미 에너지 보존 블린 퐁을 사용하는 사람이라면 이 공식은 익숙하고 우아하게 보일 것이다.

스펙큘러 지수를 조정하면 모든것이 잘 동작할 것이다.


이는 명확해 보이긴 하지만 디퍼드 렌더링의 경우 초기 화면 패스에서 이 작업을 수행해야 한다.

그러므로 모든 라이팅 대신에  G버퍼에 지수를 팩킹하기 전에 한번만 스케일링 해야 한다.

이는 또한 뷰 공간에서 BFN(best fit texture인듯) 또는 두개의 구성요소 같이

법선의 영리한 G버퍼 인코딩을 자유롭게 사용할 수 있다는 것을 의미한다.


불행히도, 이는 Toksvig AA의 중대 문제점을 발생한다.

3Dc 및 (일반적으로)DXT5와 같은 두개의 입력성분을 사용하는 법선에서는 사용할 수 없다.

이 기술의 전체 기조는 지역 거칠기(분기하는 법선)는 필터링된 법선의 길이에 의해 대략적으로 포착되므로 

단위벡터를 재 구성하는 인코딩으로는 이를 수행하는 것이 좋지 않다.

또한 DXT1을 노멀맵에만 독점적으로 사용하더라도, 압축은 여전히 벡터 길이와 혼동된다.

(DXT의 압축방식이 벡터길이에 영향을 끼쳐 Toksvig AA의 결과에 영향을 끼친다는 말이듯..)

재 정규화 후 조명에 대해 허용되는 결과가 종종 나오기 때문에 이 사실을

잊어버리기는 쉽지만 실제로 Toksvig AA에서는 혼란스러울 수 있다.

(어차피 ~1로 정규화 하고 그 결과는 결국 라이팅에서 허용하는 결과값이기때문에 이상함을 못느낄수 있다는 말인듯..)

이 모든것을 감안해 보면 개발자가 이 기술을 채택하지 않은게 놀라운 사실은 아니다.


이는 또 다른 막다른 골목이었을까?

실제적으로 전혀 아니다. 해결책에 좀 더 가까워졌다.


야생적 직감

사실 간단한 아이디어가 하나 있다.

Toksvig과 LEAN 매핑은 텍스쳐 필터링을 사용하니까 이를 오프라인으로 만드는 것이다.

그림1의 법선맵에서 각 밉 레벨의 가우시안 필터링된 버전으로부터 Toksvig Factor을 

미리 계산해서 가져올 수 있다면 어떨까?

그림 1 : 법선 맵


결과는 그림 2에 나와있으며 무처 직관적이다.

원본 법선맵에서 평평한 부분은 흰색(광택), 지글거리고 울퉁불퉁할 수록 어두워진다.

그림 2 : Toksvig map


올바른 커널 사이즈를 가진 이 Toksvig map은 실시간 Toksvig 메소드와 실제로 잘 어울리며

이를 구현한 실제 데모는 글의 마지막에서 볼 수 있다.


그림 3a : Toksvig AA 확대 관찰

그림 3b : Toksvig map 확대 관찰


우리가 실제로 가지고 있는 것은 자동 생성된 안티 엘리어싱 gloss 맵이며 LEAN 용어와 달리 실제로 잘 압축된다.

또한 이 맵이 아트 임포트 파이프라인의 일부로 생성되면 선택한 압축 방법을 사용하기 전에

고 정밀도 3성분 법선을 무료로 사용할 수 있다.


이 맵을 사용하는 것은 다른 gloss map을 사용하는 것과 마찬가지로 어렵지 않다.


1
2
3
4
float ft = tex2D(gloss_map, uv).x;
float p = ft*s;
float scale = (p + 2)/8;
float spec = scale*pow(saturate(dot(N, H)), p);


하지만 이 글을 주의깊게 읽은 독자라면 Toksvig Map이 특별한 스펙큘러 파워를 염두에 두고 생성되었음을 알 수 있다. 

다행히도 100정도의 값으로 잘 동작하는 것처럼 보이는 적당한 콘트라스트를 제공하는 고정된 power로 

텍스쳐를 만들 수 있고, 유연성이 필요한 경우 나중에 다시 변환 할 수 있다.(예를 들자면 텍스쳐 재사용이나 재질 속성 변경)


ft /= lerp(s/fixed_s, 1, ft);

다른 방법은 적절한 power인  를 Naty Hoffman에 의해 제안된 최대 스펙큘러 지수(범위 0~1)로서 저장하는 것이다.

이 로그 공간 광택 용어는 아티스트가 보다 직관적으로 작업할 수 있으며,

지수에 대한 별도의 머티리얼 속성이 필요하지 않고, 게다가 또한 직접 G버퍼 저장을 위한 편리한 포멧이다.

세번째 방법은 분산 또는 법선의 길이를 대신 저장하고 나머지 계산은 실시간으로 수행하는 것이다.


데이터 자체는 스펙큘러 마스크와 함께 팩 되거나 기존 gloss맵을 조정하는데 사용된다.

심지어 아티스트가 그림을 그리는 시작점으로 직접 사용가능한지도 생각해 봤지만, 이럴경우

엘리어싱이 다시 나타나는 것을 방지하기 위해 주의가 필요하다.


물리 기반 셰이딩 측면에서 gloss 맵이 스펙큘러 마스크보다 더 중요하지만, 아티스트들은

일반적으로 후자에 더 편하다.

게다가, 에너지 보존 스펙큘러로 가능한 높은 강도의 범위에서 안티 엘리어싱은 보다 더 치명적이다.


이러한 이유로 인해 자동 생성되는 텍스쳐에 대한 아이디어는 아직 결과물에 대해 모두 

테스트 해보지는 않았지만 실제로 매력적인 아이디어라고 생각한다.


나는 작업의 80~90프로를 자동으로 해주는 아트 툴을 무척이나 좋아하지만,

여전히 직접 들어가서 결과물을 트윅(조정)할 수 있는 방법을 제공한다.

결과적으로 머리카락을 덜 당기고 폴리싱에 더 시간을 할애 할 수 있다.

이것이 내가 원하는 방식이다.


OK목장의 결투

Toksvig Mapping은 Lean Mapping과 무었이 다른가?

글쎄, 이방성(anisotropy) 부분이 부족한 만큼 확실히 좋지는 않으며,

어떤 경우에는 스펙큘러 하이라이트가 과도하게 넓어지고, 또 어떤 경우에는 엘리어싱 얼룩들을 남긴다.

하지만 Clean Mapping을 대신 미리 저장하는 것이 가능하며, 보수적으로 감쇠하는 경향이 있기 때문에

약간의 하이라이트 블룸이 발생하는 비용으로 나머지 반짝이는 것들을 줄인다.


우리가 이것을 할 수 있는 이유는 Toksvig와 Clean을 행하는 데 있어 서로를 분리해 주는

가장 중요한 것이 분산의 측정이기 때문이다.


Toksvig Maps과 관련해서 앞서 언급한 모든것(베이킹, 평가, power 간 변환 등)도 마찬가지로 여기에 적용된다.

LEAN을 베이킹하는데 성공했지만 다른 이야기를 하겠다.


LEAN 매핑은 기본 사실에 더 가깝지만 미리 구운 Toksvig/CLEAN 매핑은 여전히 바로 지금 

대부분의 사람들이 하는것 처럼 아무것도 하지 않는 것보다는 훨씬 낫다.


어서 가요, 카우보이!

여기에 표준 블린 퐁(기본)과 Toksvig AA및 Toksvig Map 를 전환할 수 있는 간단한 WebGL 데모가 있다.

셰이더 코드도 바로 편집할 수 있다.


데모 업데이트 : Toksvig Map 옵션과 NVIDIA GPU와 관련된 시각적 문제에 대한 보고가 있었다.

Mip맵이 없는 것처럼 보이면 최신 드라이브로 업데이트 하면 문제가 해결된다.


블린 퐁으로 반짝거리는 것 외에도 마우스 휠로 줌 아웃 할 때 울퉁불퉁한게 사라지는 것 처럼 주전자가

어떻게 반짝이는지 확인해라.

대조적으로, 머티리얼은 Toksvig의 외관을 유지한다.


필터링 프로세스를 보여주는 또 다른 작은 예제도 만들었다.







아래 내용은 렌더몽키로 테스트 해 본 내용.

기존 블린 퐁 방법


Tobsk 방법


Tobsk.rfx


nvidia거 : 

ToksvigFactorComparison.zip


Reference Link

중요한 링크들은 원문에 대부분 다 포함되어 있고 아래 링크들은 추가로 달아둔 링크.

원문의 링크도 꼭 한번 다 읽어보길 추천.

1. energy conserving Blinn-Phong

2. best fit normal map generator + source code

3. Selective supersampling

'Study > Graphics' 카테고리의 다른 글

Specular Showdown in the Wild West  (0) 2019.08.16
Clipmaps  (0) 2019.06.15
early z  (0) 2018.08.29
hlod  (0) 2018.07.20
What is Texture  (0) 2018.03.10
texture format  (0) 2018.02.21
Posted by 붕대마음

댓글을 달아 주세요

Clipmaps

Study/Graphics / 2019. 6. 15. 14:55

원문 : Clipmaps

원문을 보시길 적극 추천.



요약

클립맵은 지형에 매우 높은 해상도의 텍스쳐를 매핑할수 있게 하는 SGI 워크스테이션에서 처음 구현된 기능이다.

원본 SGI 구현은 매우 전문적인 맞춤형 하드웨어가 필요했다.

NVIDIA GeForce 8800의 고급기능은 현재  소비자의 하드웨어를 사용하여 같은 알고리즘을 허용한다.

비록 현재 API들과 GeForce 8800가 8192 크기의 텍스쳐를 직접적으로 지원할 지라도, 

이 크기가 비행 시뮬레이션같은 넓은 경치를 말할때는 충분하지 않을지도 모른다.

전체 경치에 하나의 텍스쳐를 사용하는 이 아이디어는 전체 경관 텍스쳐를 한번에 디자일 할 수 있을 뿐 아니라

파라미터화 시키는 것도 간단하다.

큰 텍스쳐는 몇개의 텍스쳐를 사용하여 블렌딩 하는 기존 방식에 비해 큰 이점을 가진다.

이는 텍스쳐를 원하는 만큼 복잡하게 디자인 할 수 있다는 것이다.

디자이너가 하나의 전체 맵을 만들었으므로 그걸 그대로 사용할 수 있다.


클립맵은 원근투영이기 때문에 텍스쳐 밉맵 피라미드 내의 상대적으로 작은 영역만

모든 프레임에서 엑세스 한다는 사실을 이용한다.

따라서 우리는 뷰어를 여기저기 이동할 때 이러한 "hot"영역을 관리하고 

비디오 메모리에서 업데이트 해야 한다.

DX10 해결책은 이러한 영역들을 텍스쳐 배열에 저장하는 것이다.

픽셀셰이더에서 인덱싱 할 수 있다면 DX10에서 클립맵 알고리즘을 간단히 구현할 수 있다.


클립맵은 작동 방식

클립맵은 모든 단일 프레임에서 텍스쳐링에 필요한 모든 정보를 가지고 있는

밉맵피라미드의 부분 표현이라고 정의할 수 있다. 

소스텍스쳐로부터 어떤 데이터가 사용될것인지 어떻게 결정할까?

답은 밉맵 샘플 선택 전략에 있다.

텍스쳐링을 하는 동안 픽셀의 영역에 텍셀을 1대1 매핑하여 사용할 수 있게 하는 것이 가장 이상적인 방법이다.

이것이 현재 화면 해상도를 기반으로 밉맵레벨에서 클립 사이즈를 정의하는 방법이다.

밉맵 피라미드의 가장 낮은 레벨은 항상 비디오 메모리에 적재되고 고정적으로 사용된다.

다른 모든 밉레벨은 모든 프레임에서 실제 데이터를 저장하기 위해 동적으로 업데이트 되는 클립맵 스택을 형성한다.

가장 일반적인 경우 스택의 내용은 스택의 크기와 뷰어의 위치에 따라 정의할 수 있다.


그림설명 : 

  위 그림은 클립맵을 그림으로 표시한 것이다.

  파란색 밉 레벨들은 전체 월드에 매핑되는 데이터를 표시한다.

  녹색 지역은 동적으로 로드되는 하위(sub)지역이다.


기본 아이디어는 하나의 2D 텍스쳐 배열에 클립맵 스택을 저장하는 것이다.

텍스쳐 배열은 DX10에서 추가된 기능이다.

밉맵 피라미드의 나머지 부분은 밉과 함께 기존방식의 2D텍스쳐로 구현된다.

하위 리소스 메소드 복사/업데이트를 사용하여 동적으로 스택을 갱신할 수 있다.

때로는 시스템 메모리에서 필요한 모든 데이터를 가지고 있을수 없는 경우도 있다.

그러므로 디스크에서 필요한 모든 데이터를 효율적으로 스트리밍 하기 위한 추가 메커니즘이 필요하다.


데이터 표현

클립맵 스택은 2D텍스쳐 배열에 저장된다.

이 배열은 클립맵의 동적인 부분을 이루고, 각 프레임에서 모든 밉레벨의 실제데이터를 포함해야 한다.

원본 밉 레벨마다 별도의 레이어가 있으므로, 밉이 없는 텍스쳐를 만들어야 한다.

나머지 이미지 부분은 기존의 일반적인 2D 텍스쳐로 저장할 수 있다.


DX10 API를 사용하여, 아래와 같이 리소스를 만든다.

(Clipmap 스택 텍스쳐의 경우 ArraySize 요소를 사용해 레이어 수를 지정해줘야 한다.)


D3D10_TEXTURE2D_DESC texDesc;

ZeroMemory( &texDesc, sizeof(texDesc) );


texDesc.ArraySize = 1;

texDesc.Usage = D3D10_USAGE_DEFAULT;

texDesc.BindFlags = D3D10_BIND_SHADER_RESOURCE;

texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;

texDesc.Width = g_PyramidTextureWidth;

texDesc.Height = g_PyramidTextureHeight;

texDesc.MipLevels = g_SourceImageMipsNum - g_StackDepth;

texDesc.SampleDesc.Count = 1;


pd3dDevice->CreateTexture2D(&texDesc, NULL, &g_pPyramidTexture);


texDesc.ArraySize = g_StackDepth;

texDesc.Width = g_ClipmapStackSize;

texDesc.Height = g_ClipmapStackSize;

texDesc.MipLevels = 1;


pd3dDevice->CreateTexture2D(&texDesc, NULL, &g_pStackTexture); 

각주 : 피라미드용 텍스쳐하나와 스택용 텍스쳐 하나필요.

피라미드용 텍스쳐에는 원본 이미지의 밉레벨에서 동적으로 사용될 스택을 뺀 만큼의 밉이 필요.



정보 갱신 전략

지형을 이리저리 이동하면서, 새로운 클립 중심 위치에 맞게 스택의 정보를 갱신해줄 필요가 있다.

대부분의 경우에는 클립맵 스택(동적으로 바뀌는 부분)의 각 레이어에 있는 비교적 작은 부분의 데이터를 바꿔줘야 한다.

스택안에서 큰 데이터 교체가 일어나는 것을 방지하기 위해, toroidal addressing라고 알려진 특정 기술을 사용한다.

Toroidal addressing은 이미지의 위쪽 새 데이터가 아래에 로드되고, 오른쪾의 새 데이터가 왼쪽에 로드된다.

이 개념의 접근방식은 중첩된 영역에 대한 변경을 필요로 하지 않기 때문에 아래의 경우 무척 효율적이다.


그림 2. 스택의 단일레이어에 대한 두가지 업데이트 단계


대부분의 어플리케이션에서는 가로와 세로 부분을 개별적으로 업데이트 하여

L자 모양 대신 간단한 직사각형 영역을 만들 수 있으므로 이 프로세스가 더 간단해 질 수 있다.


클립맵 텍스쳐 주소

모든 작업은 픽셀 셰이더에서 처리한다.

우선 가져올(fetch) 밉레벨을 결정할 필요가 있다.

이를 위해 ddx와 ddy명령어를 사용하여 화면공간에서의 쿼드 크기를 찾는다.

float2 dx = ddx(input.texCoord * textureSize.x);

float2 dy = ddy(input.texCoord * textureSize.y);

float d = max(sqrt(dot(dx.x, dx.x) + dot(dx.y, dx.y)), sqrt(dot(dy.x, dy.x) + dot(dy.y, dy.y));


이제 쉽게 접합한 밉레벨을 계산할 수 있다.

float mipLevel = log2(d);

밉레벨을 부동소수점(float)으로 계산하고 소수부분을 사용하여 삼선형(trilinear) 필터링을 수행한다.

클립맵 텍스쳐 어드레싱은 간단하다.

필요한건 밉레벨을 기반으로 입력 텍스쳐 좌표를 스케일하는 것이다.

원본 이미지 크기를 클립맵 스택 크기로 나눠서 배율 인수를 계산한다.

float2 clipTexCoord = (input.texCoord) / pow(2, iMipLevel);

clipTexCoord.x *= scaleFactor.x + 0.5f;

clipTexCoord.y *= scaleFactor.y + 0.5f;

float4 color = StackTexture.Sample(stackSampler, float3(clipTexCoord, iMipLevel));

스택 샘플러의 경우 toroidal 어드레싱을 구현하기 위해 어드레싱모드를 "wrap"모드로 지정해야한다.



Reference Link

- D3D10_TEXTURE2D_DESC msdn

- Clip Mapping

'Study > Graphics' 카테고리의 다른 글

Specular Showdown in the Wild West  (0) 2019.08.16
Clipmaps  (0) 2019.06.15
early z  (0) 2018.08.29
hlod  (0) 2018.07.20
What is Texture  (0) 2018.03.10
texture format  (0) 2018.02.21
Posted by 붕대마음

댓글을 달아 주세요

나의 궁금증은 아래와 같다.


1. shader 코드에서 동적분기로 return 시키는 것은 최적화에 도움이 되는가?

- 정적분기라면 굳. 확실히 최적화에 도움이 될듯. 컴파일에서 부터 정해지니까.

- 동적분기라면 비교값이 상수가 아닌 변수이므로 런타임에 정해진다.

- 마소 문서를 보면 if문에도 [branch]와 [flatten] 가 있으며 branch의 경우 if문의 부울이 먼저 평가 되므로

  맞는 부분만 실행되고, flatten은 if의 양쪽 다 계산하고 맞는 부분을 결과값으로 선택하는 방식이다.

  다만 branch는 tex2d 와 같은 그라디언트 함수를 쓰면 작동하지 않는다.

  이는 주변 프래그먼트에 종속적이므로 실행되어야 하며, 각 프래그먼트를 건너뛰지 않아야 하기 때문이다.

  

2. if문 자체가 주는 부하를 감소시키기 위해 lerp, 삼항연산자 등을 쓰는게 도움이 되는가?

- 예를들어 아래와 같은 if문 형식이 있다면..

  if(compare < 1)

  { 연산 a }

  else

   { 연산 b}

  이를 lerp(연산a, 연산b, step(compare, 1)) 로 바꾸거나 compare < 1 : (연산 a) ? (연산 b) 로 바꾸는게

  더 좋은 방법인걸까?

3. if문이 정말 신경써야할 만한 부하를 야기하는가?

- https://answers.unity.com/questions/442688/shader-if-else-performance.html

- https://code.i-harness.com/ko-kr/q/2413290

- https://stonzeteam.github.io/Shader_Tutorial-6/




"The COMPLETE Effect And HLSL Guide" 내용 대략 번역..... 녹색글은 그냥 붙인 각주.

-------------------------------------------------------------------------------------------------

버텍스 셰이더 1.1 아키텍쳐에서는 동적 분기를 지원하지 않기 때문에 if문을 사용하면

if의 양쪽 셰이더 코드를 다 구현하도록 어셈블리 코드가 동작할 것이다.

코드는 선형적으로 실행되지만, if문의 한 부분의 결과만 결과로 사용된다.

vs1.1에서 컴파일 되는 예제코드를 살펴보자.

if(Value > 0)

  Position = Value1;

else

  Position = Value2;


위 식을 어셈으로 변형하면 아래와 같다.

// r0.w에 선형보간(lerp)값을 계산한다.

mov r1.w, c2.x   // r1.w에 비교값 0을 넣는다.

slt r0.w, c3.x, r1.w // c3.x가 r1.w보다 작으면 r0.w는 1, 그렇지 않으면 0으로 설정


// 비교 결과값을 기반으로 value1과 value2 사이 값을 lerp한다.

mov r7, -c1  // -Value1의 값

add r2, r7, c0 // Value2 - Value1

mad oPos, r0.w, r2, c1 // r0.w * r2 + c1, 즉, 비교값*(Value2-Value1) + Value

결국 if문은 lerp의 계산과 값은 형식을 취한다는 것을 알 수 있다.

실제로 lerp의 계산이 x + s(y-x)로 되어있다.


위의 코드를 통해 if 구문의 두 표현식이 버텍스 셰이더 1.1모델에서 보간법으로 계산되어

올바른 결과를 결정하게 되는 것을 볼 수 있다.

실제 동적 흐름 제어에서, 이 표현식은 단지 두개의 명령문만 필요로 하지만, 이 경우에는 5개의 명령어가 필요하다.


게다가 if 구문은, 몇몇 하드웨어에서는 정적 또는 동적 반복을 허용하지만, 대부분은 선형 실행이 필요하다.


비록 HLSL이 1.x 픽셀셰이더를 제외한 모든  셰이더 모델에 대한 흐름제어 명령을 지원하지만,

진정한 흐름제어는 18개의 흐름제어 어셈블리 명령어 집합을 통해 3.0 버텍스 및 픽셀

셰이더가 있는 하드웨어에서만 지원된다.

이는 3.0이 아닌 셰이더모델이 흐름제어를 코드로 변환하여 조건문과 펼쳐진 루프의 양쪽을 다 실행한다는 것을 의미한다. 

하드웨어 흐름제어가 그래픽스 하드웨어 내에서 아직 초기 단계이기 때문에, 그 성능은 여전히 한계가 있다.

적절한 실행을 위해 주의를 기울여야 한다.

7장에서 더 광범위하게 분기하는 것에 대한 성능 고려 사항을 논의 할 것이다.


대부분의 흐름 제어는 정적 또는 동적 타입이다.

정적 흐름제어에서, 명령문에 사용된 표현식은 실제로 불변(constant)하며 사전에 결정되어질 수 있다.

예를들면, 정적 분기는 boolean 셰이더 상수에 따라 코드 블록을 켜거나 끌 수 있다.

이 방식은, 현재 렌더링 되고 있는 오브젝트의 타입을 기반으로 코드 패스를 유효 또는 무효로 

할 수 있는 편리한 방식이다.

렌더링 호출 사이에서 현재 셰이더에서 지원하길 원하는 기능을 결정 한 후에 그 동작을

얻기 위해 boolean 플래그를 설정할 수 있다.


반면에, 동적 분기는 대부분의 개발자들이 잘 알고 있고 있다.

동적 분기의 비교 조건은 변수에 있으므로, 런타임시에 비교가 수행된다.

성능 비용은  분기 비용 + 분기에서 가져오는 추가적인 명령어의 비용이다.

동적 분기는 동적 흐름 제어를 지원하는 특정 하드웨어의 버텍스 셰이더에서 사용할 수 있다.

-------------------------------------------------------------------------------------------------


DX8 : pixel shader 1.1

DX8.1 : pixel shader 1.3 & 1.4

DX9 : pixel shader 2

DX9.0c : pixel shader 3

DX10 : pixel shader 4

DX10.1 : pixel shader 4.1

DX11 : pixel shader 5

DX12 : pixel shader 5.x ( dx12가 오버헤드 절감에 초점을 맞춰 개발해서 새로운 shader model 버전은 미정)



Reference Link

- DirectX9 High Level Shading Language

The COMPLETE Effect And HLSL Guide

- GPU Flow Control Idioms

- microsoft doc, if statement

- shader if else performance

- Modern gpu optimize

'Study > Shader' 카테고리의 다른 글

shader에서 if 와 lerp의 성능은?  (0) 2018.10.12
Posted by 붕대마음

댓글을 달아 주세요

early z

Study/Graphics / 2018. 8. 29. 16:27

Early Z : 

- Z Test(Depth Test, 깊이 판정)를 미리 해서 비싼 Pixel연산을 피하자

- 일종의 픽셀단위 Culling 기법.


Z Test :

- 깊이 판정은 픽셀의 깊이 값을 깊이 버퍼의 깊이 값과 비교해서 픽셀의 가시성을 판단한다.

- 현재 픽셀이 다른 픽셀의 뒤에 있는지를 판단하여 뒤에 있다면 픽셀을 폐기하고,

  앞에 있다면 그 픽셀을 다음 단계로 넘겨 값을 z버퍼에 기록한다.


그렇다면 기존 Z Test의 순서는?

- 간단하게 말하자면 pixel shader(fragment shader) 다음.

   자세하게 말하자면 파이프 라인 참고.

- 왜 깊이판정을 ps 이후로 했을까?

- ps 연산에 따라 depth가 변경될 수 있기 때문에 ps 앞에서 하지 않음.


Early Z를 위해서는?

- 기존 하드웨어 동작방식이 바뀌는 거기 때문에 하드웨어에서 지원해 줘야 한다.

- Coarse-grained Z Culling vs Fine-grained Z Culling

- Depth Stencil buffer를 사용

- Early Z 비활성화 (Z buffer Optimization, 10page)

  - 그래서 ps에서 depth 값을 write(갱신)한다면 비활성화 된다. 

    (ps에서는 원하는 depth을 저장해야 하니)

  - ps에서 discard 하면 비활성화 된다.

    (ps에서는 버리려는데 write 할 수 있으니)

  - alpha-test을 쓸 경우 비활성화 된다.

    (discard와 마찬가지)

- 결국 ps에서 depth는 왠만하면 건들지 마라.


Early Z의 구현은?

- 하드웨어적으로 지원하고 적용될 수 있는 상황이라면 하드웨어에서

  내부적으로 사용되며 다른 멀티패스 기술(z pass 후 color pass)과 관련이 없다.

- OpenGL 이나 D3D 어디에서도 early z 작업을 지정하지 않는다.

  이 모든 작업은 하드웨어 관련 작업이며 사용 또는 미사용 설정은 할 필요 없이 

  하드웨어에서 자동으로 처리된다.

  즉, early z 는 실행가능한 조건충족하면 하드웨어가 알아서 지원한다.

- Depth/ Stencil buffer 사용

- Early Z를 하드웨어가 실행하는 조건을 충족시켜 주기 위해 사용하는 Early-Z Pass

- 1st pass에서 depth rendering, 2st pass에서 depth write 비활성화 하고 rendering.



Reference Link

- early-z를 이용한 pixel shader 최적화

- everything about early-z

- 3dmp - early z

- early z visibility test (early-z)

- early z and discard

- why discard pixel take a noticeable performance hit?

- 픽셀 셰이더의 기초

- wiki, HyperZ

- Applications of Explicit Early-Z culling, pdf

- Hierarchical Z-Buffer Visiblility

- microsoft early-z

- Triple Depth Culling

- Saving the Z-Cull Optimization

- Early Fragment Tests, Hi Z, Depth, Stencil and other benchmarks

- Early Fragment Test

- You Can Never Have a Custom Z Buffer Distribution and Early Z at the Same Time

- Early-Z

'Study > Graphics' 카테고리의 다른 글

Specular Showdown in the Wild West  (0) 2019.08.16
Clipmaps  (0) 2019.06.15
early z  (0) 2018.08.29
hlod  (0) 2018.07.20
What is Texture  (0) 2018.03.10
texture format  (0) 2018.02.21
Posted by 붕대마음

댓글을 달아 주세요

hlod

Study/Graphics / 2018. 7. 20. 11:59

원문 : http://www.cs.unc.edu/~walk/hlod/

원문의 내용을 필요부분 번역하였습니다.

원문을 보길 강력추천합니다.


그림 1. Double Eagle 대형선박. 이 모델은 126,630개 오브젝트, 그리고 82,361,612 삼각형으로 구성되어 있다.


전통적인 LOD 방식으로는 한번에 하나의 객체만 단순화 할 수 있다.

그래서 여러 객체를 포함하는 화면이 주어지면 이 방식은 장면 전체가 아닌

개별 객체에 대해서만 에러를 최소화 할 수 있다.

HLOD(Hierarchical Level Detail, 계층적 lod)는 전통적인 방식의 LOD를 오브젝트의 

계층적 집합체로 일반화 하는 것이다.

장면의 개별 부분을 같이 단순화 하는 HLOD를 생성하여, 특히 적극적인 단순화를 위해

좀 더 괜찮은 전역 근사값을 생성한다.

원하는 목표 폴리곤 갯수에 따라, LOD는 화면에서 모든 오브젝트들을 렌더하지 못할 수도 있어 균열을 만들수 있다. 

그림 2. Double Eagle의 LOD. 7,887개, 1,922의 페이스로 구성.


HLOD는 보다 견고한 근사값을 제공한다. (그림 3 참고)

그림 3. Double Eagle의 LOD. 7,710개, 1,914의 페이스로 구성.

동적 장면에서, 가능하다면 동적으로 HLOD를 비동기로 계산하여 병렬 하드웨어의 이점을 얻는다.


중요 

충실도 : 오브젝트를 그룹화하여 HLOD를 만들므로 시각적 품질이 좀 더 많이 근사치만큼 올라간다.

자동 생성 : 사용자 개입없이 장면 그래프(scene graph)의 HLOD를 계산한다.

보편성 : 위상 정보나 표현에 대해 아무런 가정을 하지 않는다.

효율성 : LOD는 정적이므로 디스플레이 목록을 사용하여 렌더링 할 수 있다.

유연성 : HLOD 장면 그래프 구조는 일정한 프레임 속도 모드이미지 품질 모드로 렌더링 할 수 있게 해 준다.


HLOD 만들기

기존 방식의 LOD는 환경에서 단일 노드의 지오메트리를 나타내지만, HLOD는 장면 그래프의 전체 분기 또는,

다중 노드의 지오메트리를 나타낸다.

장면그래프를 사용해서 환경을 표현하고 먼저 각 노드에 대한기준 LOD를 계산한다.

그리고 나서 각 노드에서 해당 LOD를 기반으로 상향식으로 HLOD를 계산한다.

- 단말 노드(leaf node, 맨 마지막 끝 노드)의 HLOD는 그 노드의 LOD와 같다.

- 장면 그래프에 있는 내부 노드의 HLOD는 노드 자체에 속한 모든 LOD를 하위 노드의 HLOD와 

  결합하여 계산된다.


HLOD 렌더링

기존 LOD 렌더링 시스템에서는, 출력 알고리즘이 장면그래프의 모든 오브젝트나 노드에 대해

적절한 LOD를 렌더링 한다.

노드의 HLOD는 해당 노드의 지오메트리 뿐만 아니라 하위 노드까지의 근사치 이기 때문에,

장면그래프를 순회하면서 HLOD를 렌더하면 굳이 하위노드는 순회 할 필요가 없다. (그림 4 참고)

이렇게 하면 적절한 시점에 단지 HLOD를 렌더링함으로써, 장면의 전체 부분을 적극적으로 제거할 수 있다.

이미지 품질 모드에서, HLOD와 연관된 오차범위가 화면공간에 투영된 오류제약조건을 만족시킬 때 까지

장면 그래프를 순회하여 렌더링 한다.

목표 프레임 속도 모드에서, 시간적 제약보다 더 많은 폴리곤을 렌더링 할 때 까지 

최대한의 투영 오차를 가지는 가장 조잡한 HLOD를 만든다.

그림 4. 얼굴 모양을 만들기 위해 LOD와 HLOD를 사용하여 렌더링. 

얼굴에서 시작하여 장면그래프를 순회하는 알고리즘이다.

시야가 멀기 때문에, HLOD 0을 사용하여 얼굴모양을 그린다.

이 HLOD는 전체 장면그래프를 나타내므로 시스템은 순회를 멈춘다.




Reference Link

- Unity AutoLOD

- Unreal HLOD

- 번역 원문

- 3D Engine Design for Virtual Globes, page 371

'Study > Graphics' 카테고리의 다른 글

Clipmaps  (0) 2019.06.15
early z  (0) 2018.08.29
hlod  (0) 2018.07.20
What is Texture  (0) 2018.03.10
texture format  (0) 2018.02.21
shader에서 채널값이 모자를 때...  (0) 2018.02.13
Posted by 붕대마음

댓글을 달아 주세요

What is Texture

Study/Graphics / 2018. 3. 10. 15:14

What is Texture란 글을 쓰게 된 이유는 요즘 게임을 개발하다 보니,

Texture을 정말 다양한 용도로, 그리고 다양한 방법으로 쓰게되서

Texture에 대해 여러가지로 정리하는 시작점을 가지고 싶었기 때문이다.


Texture란 무었인가?

이 질문에 나름 모범적인 대답은 아래와 같다.

3d 그래픽에서 폴리곤에 다양한 색상이나 질감을 표현하기 위해 사용되어지는 2D 이미지

게임에서 사용되는 텍스쳐는 내가 생각에는 데이터를 저장하는 storage 라고 생각한다.

Texture에는 폴리곤에 색상이나 질감을 표현하기 위해 많이 사용하기도 하지만, 다른 용도로도 쓸 수 있기 때문이다.

화면톤을 위해 사용할 수도 있고, 계산하기 복잡한 특정 수치값들을 미리 저장해서 쓸수도 있다.


그래서 텍스쳐란 무었인가? 와 무었을 위한 텍스쳐인가? ,를 고민해 봐야 한다.

아래 Texture types 을 참고하면 여러가지 텍스쳐의 쓰임을 알 수 있다.


Reference Link

- Texture types

- Unity Texture compression and optimization

- UV Texture Coordinates and Texture Mapping - OpenGL / DirectX

- tangent space, 접선공간

- DXT 압축

- Texture Format


- 모바일 게임 최적화의 정석 - 텍스처 압축 편

- Surface Texture Mapping

-


'Study > Graphics' 카테고리의 다른 글

early z  (0) 2018.08.29
hlod  (0) 2018.07.20
What is Texture  (0) 2018.03.10
texture format  (0) 2018.02.21
shader에서 채널값이 모자를 때...  (0) 2018.02.13
depth-precision-visualized  (0) 2018.01.31
Posted by 붕대마음

댓글을 달아 주세요

texture format

Study/Graphics / 2018. 2. 21. 17:48

texture에는 file format 이 있고 pixel format이 있다.

파일 포멧이야 파일의 확장자를 보면 알수 있고 이 파일들 마다 독특한 성질을 가지고 있다.

몇가지 예를 들어 보면 tga, bmp, jpeg, png, dds, psd, gif, etc... 가 있다.

각각 데이터의 압축, 압축시 손실유무, 특정 픽셀포멧 지원여부 등의 기능을 따진다.

픽셀포맷은 사용되는 형식에 따라 채널과 비트수, 부호, 부동소수점 등으로 사용된다.

아래 링크에서 각 텍스쳐 포멧에 대한 추가적인 내용을 알 수 있다.


Reference Link

- Difference between floating point render target and normal render target

- Floating point texture가 왜 필요한가

- 텍스쳐 포맷과 기초

- Display color와 Digital texture format의 이해

- Direct3D Surface Format

- Khronos Group, Image Format

-

'Study > Graphics' 카테고리의 다른 글

hlod  (0) 2018.07.20
What is Texture  (0) 2018.03.10
texture format  (0) 2018.02.21
shader에서 채널값이 모자를 때...  (0) 2018.02.13
depth-precision-visualized  (0) 2018.01.31
디더링 (Dithering)  (0) 2018.01.26
Posted by 붕대마음

댓글을 달아 주세요

텍스쳐마다 채널이, R/ RG/ RGB/ RGBA 등이 있는데 가끔 채널 하나가 더 필요할 때가 있다.

예를들어 R채널에는 Diffuse Mask, G채널에는 Rim Mask, B채널에는 Specular Mask, A채널에는 depth를 

넣는데 추가로 offset값을 저장해 줘야 할 때가 있다. 

그럴때 가끔 fmod를 사용해서 하나에 두개의 값을 넣게 하는 방법을 쓴 적이 있다.

z값(B채널)이 0.0f ~ 1.0f 사이이고 offset 값이 1.0f에서 10.0f 사이라면 

z값에 기존값 * 0.01f하고 offset 값을 *0.1f 해서 더한 후 다음 패스에서 이 값을 fmod로 z값을 구한 후

기존값에서 빼면 z값만 구할수 있긴 하다. 다만 offset 값이 1.0f~10.0f 조건에 추가로

단차가 0.1f 단위여야 한다는 조건이 붙는다.

1.1f는 가능하지만 1.01f는 기존값고 정밀도를 더 나눠써야 한다.

가끔 이런방식으로 작업을 해서 쓰긴 하는데 fmod자체가 그렇게 단순 연산만큼 가볍지는 않지만

텍스쳐 한장 더 써서 한번 더 찍어야 하는 상황에서는 나름 괜찮았던것 같다.


float2 fmod(float2 a, float2 b)

{

  float2 c = frac(abs(a/b))*abs(b);

  return (a < 0) ? -c : c;   /* if ( a < 0 ) c = 0-c */

}


Reference Link

- fmod

-

'Study > Graphics' 카테고리의 다른 글

What is Texture  (0) 2018.03.10
texture format  (0) 2018.02.21
shader에서 채널값이 모자를 때...  (0) 2018.02.13
depth-precision-visualized  (0) 2018.01.31
디더링 (Dithering)  (0) 2018.01.26
Texture types  (0) 2017.02.05
Posted by 붕대마음

댓글을 달아 주세요

벡터, 행렬, 렌더링 파이프라인 간단하게.

벡터 : http://mgun.tistory.com/1143

행렬 : http://mgun.tistory.com/1363


기존거 복습 : diffuse, specular

http://mgun.tistory.com/2121


brdf 관련 

http://mgun.tistory.com/1304


'Study > M's Lecture daily record' 카테고리의 다른 글

2018-02-10  (0) 2018.02.10
2018-02-03  (0) 2018.02.04
Posted by 붕대마음

댓글을 달아 주세요

1. Texture 관련 

what is texture?

2. 기본 Lighting 에 대한 이해.

http://mgun.tistory.com/854

3. 조명모델 

http://mgun.tistory.com/1336

http://mgun.tistory.com/1337


우선은 언렬의 비쥬얼 노드의 사용법을 익히는걸 목표로 하고

따라하기 "쉬운 언리얼 쉐이더 활용 테크닉" 책으로 연습을.

굳이 책 내용을 이해할 필요는 없음. 그냥 비쥬얼 노드의 사용만 익숙해지면 끝.

이론보다는 예제 우선으로 툴에 익숙해지고 그 다음에 이건 왜 이럴까로 유도하는게...


다음 강의는 뭘로 할까?

사람 : 눈동자, 피부, 머리카락

물체 : 금, 판금, 가죽, 벨벳, etc..

자연 : 지형, 물, 하늘, 태양, etc..

렌더링 방식 : npr 관련

흐음...최대한 쉽고....2시간 정도 떄울만한걸로....




'Study > M's Lecture daily record' 카테고리의 다른 글

2018-02-10  (0) 2018.02.10
2018-02-03  (0) 2018.02.04
Posted by 붕대마음

댓글을 달아 주세요

최근에 달린 댓글

최근에 받은 트랙백

글 보관함