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

카테고리

전체목록 (676)
참고사이트 (8)
Goal (4)
Travel (10)
My Life (110)
Game (35)
Game Review (7)
Game Plan (0)
Books (5)
English (1)
Optimizing (12)
Study (219)
유용한 것들_etc (45)
유용한 것들_func (20)
Unity (48)
Unreal (87)
작업장 (54)
RenderMonkey (6)
정리요망 (3)
따라잡기 시리즈 (0)
링크용 (0)
Total373,518
Today0
Yesterday154

'정리요망'에 해당되는 글 3건

  1. 2020.01.29 ddx와 ddy
  2. 2019.12.06 Texture LOD calculation (useful for atlasing)
  3. 2013.12.24 wrapped diffuse

ddx와 ddy

정리요망 / 2020. 1. 29. 13:00

ddx에 대한 msdn 설명

화면공간 x 좌표에 대한 지정도니 값의 부분 도함수를 반환한다.


ddy도 대략 비슷한 설명이고 무슨말인지 모르곘다.ㅡㅡ;

그래서 내가 이해한것들을 풀어서 정리한다.


ddx와 ddy가 하는일은 무었인가?

ddx와 ddy는 그냥 화면 공간 좌표에 대해 값의 변화를 계산하는데 사용된다.

GPU는 한번에 많은 픽셀을 처리하기 위해 2x2 픽셀 블럭을 구성한다.

이때 ddx는 2x2 블럭에서 가로 픽셀의 오른쪽과 왼쪽의 차이를 반환한다.


원본 이미지 출처 : http://www.aclockworkberry.com/shader-derivative-functions/


ddx와 ddy가 왜 필요한가?

ddx와 ddy는 결국 좀 쉽고 대충 말하면 픽셀값 차이 반환하는 함수라고 이해할 수 있다.

그런데 이게 왜 필요할까?

대표적인 예로 나는 밉맵 구현을 들 수 있다.

예제는 이곳을 참고하면 된다.

간단하게 설명하자면 텍스쳐는 여러개의 밉으로 만들어지며 렌더링시

어느 밉을 선택할지 gpu에서 선택해야 하는데 이 때 해당 텍스쳐가 매핑된 물체가

화면상에서 어느정도의 크기를 가지는지를 판별하여 밉을 선택한다.

(텍스쳐의 캐시 일관성, 텍셀과 픽셀의 1대1비율 등의 내용이 있지만 적당히 적당히.)

해당 물체가 화면에서 크기가 작다면 작은 밉을 선택하게 되고 반대의 경우 큰 밉을 선택한다.

이로 인해 에일리어싱을 줄일 수 있다.


또한 미분은 픽셀 셰이더에서 현재 삼각형의 face normal(면 법선)을 계산하는 데 사용할 수 있다.

현재 픽셀의 월드 위치의 수평 및 수직 미분은 삼각형의 표면에 놓인 두개의 벡터다.

이들의 외적은 표면에 직교하는 벡터가 되며 이것은 삼각형의 법선벡터이다. 

normalize(cross(ddx(Input.PosN), ddy(Input.PosN)))

test ddx_1.rfx


그렇다면 미분이 아니라 분기를 사용하면 되지 않을까?

미분과 분기의 차이는 뭘까?

미분 계산은 여러 셰이더 인스턴스의 GPU 하드웨어에서 병렬실행을 기반으로 한다.

스칼라 연산은 2x2 픽셀의 블록을 4개의값으로 구성된 벡터를 가지는 레지스터에서 SIMD 아키텍처로 실행된다.

즉, 모든 실행 단계에서, 각 2x2블록에 속하는 셰이더 인스턴스가 동기화 되어 미분 계산을 하드웨어에서

빠르고 쉽게 구현할 수 있으므로 동일한 레지스터에 포함 된 값을 간단히 뺼 수 있다.

조건부 분기는 어떤가?

코어의 모든 스레드가 동일한 분기를 사용하지 않으면 코드 실행에 차이가 있다.

아래 이미지에서 8개의 셰이더 인스턴스가 있는 GPU코어에서 조건부 분기 실행인 분기를 예를 보여준다.

3개의 인스턴스가 첫번째 분기(노란색)을 사용하는데 다른 5개의 분기는 비활성 상태다.

노란색 분기 후에 실행마스크가 반전되고 나머지 5개의 인스턴스가 파란색 분기를 실행한다.

원본 이미지 출처 : http://www.aclockworkberry.com/shader-derivative-functions/

분기의 효율 및 성능손실 외에도 분기는 미분연산을 정의하지 않도록 하는 블럭에서 픽셀간의 동기화를차단한다.

이는 밉맵레벨 선택, 이방성 필터링 등의 미분연산을 필요로 하는 텍스쳐 샘플링에 대한 문제다.

이러한 문제에 직면 할 때 셰이더 컴파일러는 분기를 [flatten]을 사용하여 피하거나, 

텍스쳐를 읽는 코드를 분기 바깥으로 옮겨서 수행한다.

이 문제는 텍스쳐를 샘플링 할 때 명시적으로 미분이라 밉맵 레벨을 사용하면 피할 수 있다.


분기안에 미분이 있다면 어떻게 될까?

아래의 의사코드가 gpu에서 실행된다고 생각해 보자.

float tmp = 10000;

float color;

[branch]

if(xpos > side)

{

tmp = xpos * xpos;

float dx = ddx(tmp);

color = float3(dx,0,0);

}

else

{

tmp = xpos*xpos;

float dx = ddx(tmp)

color = float3(0,dx,0);

}

return color * 100;

2x2블럭의 픽셀에서 내부 픽셀이 첫번째 분기문으로 들어갈 때 

두번째 분기 실행을 기다리는 비활성 픽셀의 tmp값은 여전히 10000이어야 한다.

하지만 해당 코드는 오류를 발생시키는데 오류의 내용은 분기문 내에 미분 연산을 

가질수 없다는 내용이며 [branch]속성을 제거하면 컴파일이 되지만 분기가 평평해진다.(flat)


셰이더 미분의 내부블럭 정렬을 보여주는 간단한 실험을 해 보자.

ddx 테스트.

화면의 절반을 0, 나머지 절반을 1이라 했을때(step)이 값을 ddx로 테스트 해 보자.

미분 계산은 2x2픽셀 블럭에 대해 수행되므로 단계전환이 발생하는 위치에 따라 두가지 다른 결과가 예상된다.

1. 단계 전환이 2x2픽셀 블럭의 중간에 빠지면 2픽셀 두께의 수직선이 표시된다.

2. 단계 전환이 2개의 인접한 2x2픽셀 블럭 사이에 속한다.

   이 경우 두 블럭 모두 0과 같은 도함수를 계산하기 때문에 세로선이 표시 되지 않는다.


img1. 982 위치에서 변경됨.


img2. 983 위치에서 변경됨. (odd_step 값 1)


img3. 981과 983 위치에서 바뀜. (show derivative 값 1)

test_ssp.rfx


위 렌더몽키 파일에 hlsl 버전과 opengl 버전 이렇게 두개의 버전을 만들어 두었다.

코드 내용은 같은데 이상하게 odd 값이 틀리다.

dx에서는 짝수에서, gl에서는 홀수에서 미분선이 표시된다.

이 차이는 뭘까? (누가 답변해주면 참 좋을 텐데....)




https://www.opengl.org/pipeline/article/vol003_6/

http://www.iquilezles.org/www/articles/checkerfiltering/checkerfiltering.htm

https://developer.nvidia.com/gpugems/gpugems2/part-iii-high-quality-rendering/chapter-28-mipmap-level-measurement

https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/shading-normals

https://www.enkisoftware.com/devlogpost-20150131-1-Normal-generation-in-the-pixel-shader

Reference Link

- 미분 도함수 개념 원리 활용 증명 철저하게 이해하기

- 적분 구분 구적법 dx dy 개념과 원리 이해하기

An introduction to shader derivative functions

- What Is Ddx And Ddy

- 밉맵 텍스쳐링

- Texture LOD calculation

- Derivatives

- shader에서 if와 ler의 성능은?

- HLSL Flow Control

'정리요망' 카테고리의 다른 글

ddx와 ddy  (0) 2020.01.29
Texture LOD calculation (useful for atlasing)  (0) 2019.12.06
wrapped diffuse  (0) 2013.12.24
Posted by 붕대마음
TAG ddx, ddy, mipmap, 밉맵

댓글을 달아 주세요

최근에 본 코드중에 재미있는게 있어서 정리함. 

원문 : 

Texture LOD calculation (useful for atlasing)


텍스쳐 아틀라스에서 가장자리 필터 문제가 없는 셰이더를 작성중이며 이를 공유한다.

(텍스쳐 배열을 지원하지 않는 하드웨어에서 텍스쳐 배열 에뮬레이팅)



#define SUB_TEXTURE_SIZE 512.0 #define SUB_TEXTURE_MIPCOUNT 10 float MipLevel( float2 uv ) { float2 dx = ddx( uv * SUB_TEXTURE_SIZE ); float2 dy = ddy( uv * SUB_TEXTURE_SIZE ); float d = max( dot( dx, dx ), dot( dy, dy ) ); // Clamp the value to the max mip level counts const float rangeClamp = pow(2, (SUB_TEXTURE_MIPCOUNT - 1) * 2); d = clamp(d, 1.0, rangeClamp); float mipLevel = 0.5 * log2(d); mipLevel = floor(mipLevel); return mipLevel; }

ㅇㅇ


Reference Link

https://cgl.ethz.ch/teaching/former/vc_master_06/Downloads/Mipmaps_1.pdf

  (mipmap 원리, 필터링 기본 방식 설명)

https://developer.nvidia.com/gpugems/gpugems2/part-iii-high-quality-rendering/chapter-28-mipmap-level-measurement

https://studfile.net/preview/5125756/page:70/

https://usermanual.wiki/Document/GPU20Pro2036020Guide20to20Rendering.927333407/help

https://gamedev.stackexchange.com/questions/130888/what-are-screen-space-derivatives-and-when-would-i-use-them

https://aras-p.info/blog/2011/05/03/a-way-to-visualize-mip-levels/

https://community.khronos.org/t/texture-lod-calculation-useful-for-atlasing/61475

http://www.aclockworkberry.com/shader-derivative-functions/

http://webcache.googleusercontent.com/search?q=cache:http://www.jiajianhudong.com/question/575425.html

https://stackoverflow.com/questions/24568918/why-are-dfdx-ddx-and-dfdy-ddy-2-dimension-variables-when-quering-a-2d-texture

https://forum.unity.com/threads/calculate-used-mipmap-level-ddx-ddy.255237/

https://kblog.popekim.com/2011/04/tex2dlod.html

https://3dmpengines.tistory.com/1484

Reference Link

What Is Ddx And Ddy

https://www.sysnet.pe.kr/2/0/11613

https://lifeisforu.tistory.com/388

'정리요망' 카테고리의 다른 글

ddx와 ddy  (0) 2020.01.29
Texture LOD calculation (useful for atlasing)  (0) 2019.12.06
wrapped diffuse  (0) 2013.12.24
Posted by 붕대마음

댓글을 달아 주세요

wrapped diffuse

정리요망 / 2013. 12. 24. 17:33


Wrap이란 무었인가?
무었인가를 감싼다는 말인데 부드러운 반사를 표현하기 위해 빛이 비치는
반대 영역을 감싸주는 것을 말한다. (...ㅡㅡ;....맞나?) 

자세한 설명은 아래들 있다.
wrapped Diffuse
http://www.gamedevforever.com/150 
  http://cagetu.egloos.com/5621806

사실 욘석은 피부를 표현하고자 할 때 자주 사용하는데
http://blog.naver.com/PostView.nhn?blogId=edgerider&logNo=110148724540
이곳에 보면 피부(SSS)를 위해 wrapped lighting을 사용하는 예가 있다.

sss 만들기
http://chulin28ho.egloos.com/5591833



lighting만 테스트 하기 위해 specular은 빼고 테스트 해보자!!


// 1. default lambert

Output.mDiffuse = dot(-lightDir, worldNormal);

 


// 2. half lambert  

Output.mDiffuse = pow(dot(-lightDir, worldNormal) * 0.5 + 0.5, 4);

 

// 3. wrapped diffuse

// if magicNumber is 0, it same with lambert function 

float magicNmuber = 0.5; 

Output.mDiffuse = (dot(-lightDir, worldNormal) + magicNmuber) / (magicNmuber+1);



// 4. energy conserving wrapped diffuse

float magicV = 0.5;  

float NdotL = dot(-lightDir,worldNormal);

Output.mDiffuse = saturate( (NdotL+magicV ) / ((magicV +1)*(magicV +1))  ); 

 
 // 5. fake sss 1

float3 LightColor = float3(0.3, 0.0, 0.0);

float LightIntensity = 1.0;

float LambertLight = dot(-lightDir, worldNormal);

Output.mDiffuse = (pow(1.0 - LambertLight,2.0) * LightIntensity) * LightColor;    

Output.mDiffuse += LambertLight;

 

// 6. fake sss 2

float3 LightColor = float3(0.3, 0.0, 0.0);

float LightIntensity = 1.0;

float NdotL = dot(-lightDir, worldNormal);

Output.mDiffuse = (pow(dot(-lightDir, viewDir),4.0) * LightIntensity) * LightColor;    

Output.mDiffuse += NdotL;

 

// 7. fake sss 3

float3 LightColor = float3(0.3, 0.0, 0.0);

float3 DiffuseColor = float3(1.0,1.0,1.0);

float LightIntensity = 1.0;

float NdotL = dot(-lightDir, worldNormal);

Output.mDiffuse = (pow(dot(-lightDir, viewDir),4.0) * LightIntensity) * LightColor + LightColor; 
Output.mDiffuse = lerp(NdotL, Output.mDiffuse, Output.mDiffuse) * DiffuseColor;

 

// 8. fake sss4

float3 LightColor = float3(0.3, 0.0, 0.0);    

float NdotL = dot(-lightDir, worldNormal);

float TransmissionMask = 0.7;

float3 DiffuseColor = lerp(float3(NdotL,NdotL,NdotL), TransmissionMask, TransmissionMask);

Output.mDiffuse = LightColor * DiffuseColor + NdotL;

 
 

   
그냥 쭉 나열해 놓긴 했는데 뭘 쓰든 그냥 걍 맘에 드는걸로, 프로젝트에 맞는걸로,
입맞에 맞게 대충 고쳐쓰면 된다.
기본적인 내용은 다 똑같다.





참고자료
wrapped Diffuse
http://www.gamedevforever.com/150 
  http://cagetu.egloos.com/5621806
Energy-Conserving Wrapped Diffuse 
http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
 
 wrap Shading
  http://www.iro.umontreal.ca/~derek/publication8.html 
Energy Conservation In Game
http://www.rorydriscoll.com/2009/01/25/energy-conservation-in-games/
Diffuse Warping을 이용한 고급 셀 셰이딩
http://www.gamedevforever.com/272


Cinematic Character Lighting In Star
http://www.gdcvault.com/play/1014362/Cinematic-Character-Lighting-in-STAR
TERA에 사용된 렌더링 테크닉
-  http://www.slideshare.net/valhashi/2011-03-gametechtadptforpdf
구세대 엔진 신데렐라 만들기
http://www.slideshare.net/kokyoungseok/2-20009459
유니티 라이팅이 안이뻐요
http://ozlael.egloos.com/3999813
Oren-Nayar Reflectance Lighting Model
http://www.gamedevforever.com/93
SkinShader in Unity
http://wiki.unity3d.com/index.php?title=SkinShader

http://www.gamasutra.com/view/feature/2817/hemisphere_lighting_with_radiosity_.php

http://digitalerr0r.wordpress.com/2009/05/09/xna-shader-programming-tutorial-19-hemispheric-ambient-light/


http://www.slideshare.net/ozlael/deferred-rendering-case-study


http://http.developer.nvidia.com/GPUGems/gpugems_ch22.html

http://docs.unity3d.com/Documentation/Components/script-ColorCorrectionEffect.html

http://blog.naver.com/PostView.nhn?blogId=sorkelf&logNo=40146367692&redirect=Dlog&widgetTypeCall=true&topReferer=http%3A%2F%2Fblog.naver.com%2FPostView.nhn%3FblogId%3Dagebreak%26logNo%3D60149081175%26redirect%3DDlog%26widgetTypeCall%3Dtrue%26top

http://wiki.unity3d.com/index.php?title=SkinShader

http://http.developer.nvidia.com/GPUGems/gpugems_ch16.html

https://www.youtube.com/watch?v=XBTB17hcbio&feature=related

'정리요망' 카테고리의 다른 글

ddx와 ddy  (0) 2020.01.29
Texture LOD calculation (useful for atlasing)  (0) 2019.12.06
wrapped diffuse  (0) 2013.12.24
Posted by 붕대마음

댓글을 달아 주세요

최근에 달린 댓글

최근에 받은 트랙백

글 보관함