강좌를 보기 전에...
Cygwin 설치방법
REYES
Shader 강좌 1
Shader 강좌 2
Shader 강좌 3
Shader 강좌 4
Shader 강좌 5
Shader 강좌 6
Shader 강좌 7
Shader 강좌 8
안녕하세요. 김대현입니다.

오늘은 프로시주얼 텍스쳐를 만들기 위한 기초 준비를 해보겠습니다.

Makefile
------------------------------------------------------------------------------------------

RENDER=prman
SLCOMPILER=shader
SLEXT=slo
RIBNAME=test.rib

SHADERNAME=Test

${SHADERNAME}.tiff : ${SHADERNAME}.${SLEXT} ${RIBNAME}
    cat ${RIBNAME} | sed s/XXXX/${SHADERNAME}/g | ${RENDER} -progress

${SHADERNAME}.${SLEXT} : ${SHADERNAME}.sl
    ${SLCOMPILER} ${SHADERNAME}.sl

clean :
    rm -f ${SHADERNAME}.tiff ${SHADERNAME}.${SLEXT}


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



test.rib
------------------------------------------------------------------------------------------

Display "XXXX.tiff" "tiff" "rgb"
Format 320 240 1
Projection "perspective" "fov" [45]
LightSource "ambientlight" 1 "intensity" [0.2]
LightSource "distantlight" 2 "from" [-1 1 0 ] "to" [0 0 3] "intensity" [1]

Translate -0.5 -0.5 1.5
WorldBegin
    Color [1 0 0]
    Surface "XXXX"
    Patch "bilinear" "P" [ 0 0 0
                           1 0 0
                           0 1 0
                           1 1 0]
WorldEnd


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



Test.sl
------------------------------------------------------------------------------------------

surface Test ( float Ka = 1; float Kd = .8; )
{
    normal Nf = faceforward (normalize(N),I);
    color Ct;

    color Red = color "rgb" (1, 0, 0);
    color Blue = color "rgb" (0, 0, 1);

    Ct = mix(Red, Blue, s);

    Oi = Os;
    Ci = Oi * ( Ct * ( Ka*ambient() + Kd*diffuse(Nf) ) );
}


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



Pasted Graphic

1.
시간과 마찮가지로 test.rib 같은 것을 계속 사용하고, Makefile SHADERNAME 우리가 만드는 쉐이더 파일의 이름으로 변경하시면 되겠습니다.



2.
소스는 별다른 것은 없고, 시간에 만들었던 mix함수를 이용한 쉐이더입니다. 오늘은 소스에 계속 변경을 하면서 다양한 함수를 구경해 예정입니다.



3.
~ 첫번째로 함수는 step이라는 함수입니다. 우선 변경된 소스를 보시죠.

stepTest.sl
------------------------------------------------------------------------------------------

surface stepTest ( float Ka = 1; float Kd = .8; )
{
    normal Nf = faceforward (normalize(N),I);
    color Ct;

    color Red = color "rgb" (1, 0, 0);
    color Blue = color "rgb" (0, 0, 1);

    Ct = mix(Red, Blue, step(0.5, s));


    Oi = Os;
    Ci = Oi * ( Ct * ( Ka*ambient() + Kd*diffuse(Nf) ) );
}


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

위에서 말씀드렸듯이 Makefile SHADERNAME stepTest 바꾸시면 됩니다.

우리의 mix 함수에 step 함수를 넣어 봤습니다. 우선 결과를 보고 얘기하죠.


어떻습니까? 시간에 smoothstep이라는 함수를 사용하기 전에 if문으로 위치에 따라 색상을 선택하게 소스와 비슷하지 않습니까 ?

맞습니다~. 함수의 구조는 step(min, value)로서 value값이 min보다 작으면 0 값을 리턴하고, 그렇지 않으면 1 리턴합니다.

우리가 만든 예제에선 s값이 0.5 보다 작으면 0 리턴하므로, s값이 0.5보다 클때까지 빨간색이 쉐이딩되고, s값이 0.5이상이 되면 1 리턴하여 웨이트 값이 파란쪽으로 100% 적용되므로 파란색이 쉐이딩됩니다.

Pasted Graphic 1

현재는 색상이 갈라지는 부분이 위아래 직선이므로 지글거림이 없지만, 역시나 대각선이 되었을때는 aliasing 발생합니다.



4.
이전 시간에 했던 처럼 그냥 if문을 써서 해도 되는데 굳이 step문을 따로 만든 이유가 뭘까요 ?

mix
문에 사용된 step 보시면 뒤통수를 맞은듯한 느낌이 들지 않나요 ?

~~ 뒤통수를 어루 만지시고~!!

바로 다른 함수들과 연동해서 사용하기 위함입니다. , 소스의 가독성을 좋게 하고, 더더욱 중요한......

바로 바로 바로 ~~~~~ 레이어링을 하기 위한 기반이라고 있겠습니다.

레이어링이 별건 아니고요. 포토샵에 레이어를 생각하시면 쉬울듯 합니다. 포토샵의 레이어를 어떤 기능을 하나요 ?

그렇죠~ 바로 레이어를 합성하여 우리가 원하는 최종 이미지를 만들어 내는 역활을 하는 것입니다.

우리가 만若?쉐이더도 결국은 여러 연산을 통해 다양한 색상을 조합해서 하나의 이미지를 만들어 내는 것입니다.



5. slim
이란 툴이나, houdini Vex shader 보신 있으신가요 ?

툴은은 노드들을 연결해서 하나의 쉐이더를 생성해 냅니다. 고도로 추상화되어 있어서 거의 프로그래밍 지식이 없이도 어여쁜 쉐이더를 만들어 있죠.

우리는 쉐이더 프로그래밍을 해봤으니, 가볍게 코웃음을 지으며, "그게 별건가 ? 그냥 노드들이 색상을 계산해 주거나 조건을 만들어 주는 함수일 뿐이고, 노드(함수)들의 입력, 출력을 적절히 다른 노드(함수)들과 연결해서 최종 이미지를 만들어 내는 거잖아~~" 하고 말해 있을 겁니다.



6.
쉐이더 소스에 조금 장난을 쳐보고 다음으로 넘어갑시다.

stepTest2.sl
------------------------------------------------------------------------------------------

surface stepTest2 ( float Ka = 1; float Kd = .8; )
{
    normal Nf = faceforward (normalize(N),I);
    color Ct;

    color Red = color "rgb" (1, 0, 0);
    color Blue = color "rgb" (0, 0, 1);

    Ct = mix(Red, Blue, step(s, 0.5));


    Oi = Os;
    Ci = Oi * ( Ct * ( Ka*ambient() + Kd*diffuse(Nf) ) );
}


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

별다른 것은 아니고, step함수의 입력값을 살짜쿵 바꿔 봤습니다. 결과가 어떻게 될까 잠시 생각해 보시죠.

...Zzzz

...ZZzzzzzzzzz

~ 바로 보시면 아니되옵니다. ^^;

Pasted Graphic 2

s값은 왼쪽에서 오른쪽으로 0에서 1로 변화되어 가는 값입니다. 그렇다면, 초반에 0.5는 s보다 크므로 1이 나오겠죠 ?

그러다가 s가 0.5이상이 되면 value부분인 0,5가 s보다 작아지므로 0이 나올겁니다. 색상이 반전되었군요.

재미난 결과지 않습니까 ? 앞으로 많이 보시겠지만, 이런 이상 야릇한 소스들이 꽤 재미난 효과를 만들어 낸답니다.




7. 자~ 쫌 재밌는데, step 을 더 괴롭혀 보죠~

pulse.sl
------------------------------------------------------------------------------------------

surface pulse ( float Ka = 1; float Kd = .8; )
{
    normal Nf = faceforward (normalize(N),I);
    color Ct;

    color Red = color "rgb" (1, 0, 0);
    color Blue = color "rgb" (0, 0, 1);

    Ct = mix(Red, Blue, step(0.4, s)-step(0.6, s));


    Oi = Os;
    Ci = Oi * ( Ct * ( Ka*ambient() + Kd*diffuse(Nf) ) );
}


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



Pasted Graphic 3

결과를 보시면 아시겠지만, step 2개로 파란색 띠를 만들어 냈습니다.

s
첫번째 step 0,4보다 작을 동안은 0 리턴합니다. 당연히 두번째 step 0.6 0.4보다 값이기 때문에 0 리턴합니다. 0 - 0이기 때문에 s 0.4 되기 전까진 0으로 빨간 색이 쉐이딩됩니다.

s
0.4 되면, 첫번째 step 1 리턴하고, 두번째 step 아직 s 0.6보다 작으므로 0 리턴합니다.

그래서 1 - 0으로 1 값이 사용되어 파란색이 쉐이딩됩니다.

s
0.6 되면, 첫번째 step 당근 0.4보다 크니 1 리턴할 것이고, 두번째 step s 0.6 넘겼으니 1 리턴할 것입니다. 그럼 1-1 = 0 해서 결국은 0 값이 사용되어 빨간색이 쉐이딩됩니다.

~~ 무지 무지 신기합니다. 조금만 응용하면 체스판 만드는 쉐이더 정도는 껌씹으면서 만드실 있을 같지 않습니까 ?



8.
~ 다시 본론으로 돌아와서 clamp 관해 알아봅시다.

clamp.sl
------------------------------------------------------------------------------------------

surface clamp ( float Ka = 1; float Kd = .8; )
{
    normal Nf = faceforward (normalize(N),I);
    color Ct;

    color Red = color "rgb" (1, 0, 0);
    color Blue = color "rgb" (0, 0, 1);

    Ct = mix(Red, Blue, clamp(s, 0.3, 0.6));


    Oi = Os;
    Ci = Oi * ( Ct * ( Ka*ambient() + Kd*diffuse(Nf) ) );
}


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


Pasted Graphic 4

clamp(value, min, max) 형태를 가진 놈으로 value값이 min보다 작으면 min값을 리턴하고, max보다 크면 max값을 리턴하고, min max사이 값이면 선형 보간을 하는 함수입니다.

우리가 만든 예제에서 s 0.3보다 작을때는 0,3 리턴하므로 빨간색 70%, 파란색 30% 섞인 색상이 나오고, s 0.3~0.6사이 값이면, 선형 보간된 웨이트 값에 의해 색상이 그라데이션됩니다.

s
0.6보다 크면 0.6 리턴하므로 빨간색 40%, 파란색 60% 색상이 쉐이딩됩니다.

Pasted Graphic 5
위에 보시는 그래프가 바로 clamp 역활을 보여줍니다.




9.
그밖에도 abs, min, max등의 함수들이 있습니다. abs 절대값을 돌려주고 min 수중 작은 놈을 리턴해 주고, max 두수 놈을 리턴해 줍니다.



10.
지금까지 보신 함수들의 내용을 숙지해 두시기 바랍니다. 대부분의 패턴을 만들어 내는 쉐이더들은 함수들을 복잡하게 연결하여 결과값을 만들어 냅니다. 내용을 정확히 이해하고 있지 못하면, 미궁에 빠져 헤어나오지 못하게 됩니다.

가능하면 여러가지 테스트를 해보시고, 확실히 익혀 두시기 바랍니다.

~ 그럼 다음 시간에 뵙죠.



예제소스 : shader_7.zip