본문 바로가기

포트폴리오 /DirectX 11

[Eunbi's Farm - DirectX11] 흐르는 물 구현하기

[ 흐르는 물 구현하기 ]


DetailTexture의 UV만 바꿔주면 되기 때문에 쉐이더 기술중에 쉬운 편이다.


넘겨주어야 할 것은 일단 BaseTexture와 DetailTexture.


UV는 기본적으로 0.0~1.0 사이의 값을 가지고 있지만, 그 이상을 벗어나면 다시 0.0에 해당하는 값을 가지게 된다.


즉, 1.1은 0.1에 해당하는 텍스쳐를 가지는 것이다. 


다음 그림과 같이 하트모양의 텍스쳐 여러개가 이어져있는 형식이다. 



이것을 이용하면 0.0~1.0에 해당하는 UV를 BaseTexture에 적용을 해 주고, DetailLevel을 지정하여 input으로 들어온 UV에 곱해주면 0~ DetailLevel의 값을 가지게 되고 이는 연속된 텍스쳐로 이루어 져 있으므로, 자잘한 텍스쳐 여러개가 맵핑 될것이다.


그런 후, 이 두 텍스쳐를 saturate( )함수를 이용하여 50:50의 비율로 섞어주면 디테일텍스쳐가 입혀진 베이스 텍스쳐가 생겨난다. 


이를 이용하면 흐르는 물 제작도 쉽게 할 수 있다.


쉐이더에 상수버퍼로 deltaTime을 넘겨준다. 


이 때 주의해야 할 점은, 업데이트시에 count를 1 올려주거나 하는 방법을 이용하면 안된다. 그런 경우 Debug모드와 Release모드에 따라서 혹은, 컴퓨터의 성능에 따라서 다른 속도로 물이 흐를 것이기 때문이다. 


** 필자의 경우 QueryPerformanceCounter를 통한 방법으로 시간을 쟀다. 


이 델타 타임을 UV의 x나 y값에 더해주면 흐르는 물을 구현할 수 있다. 


<코드>


     float g_fDetailLevel = 30.f; // 디테일 값지정 

     float2 vDetailUV = (input.vUV * g_fDetailLevel); 


     vColor = saturate((vColor * 0.5f) + (cDetailTexColor * 0.5f)); // 혼합


     vDetailUV.y += g_fWaterTime;



UV의 샘플링을 하는 부분을 조금씩 이동해가면서 물이 흐르는 것을 구현할 수 있다.


영상에서 처음나오는 흐르는 물은 DetailLevel을 20.f로 주고, 타임값의 1/10만큼 UV를 이동해 준 모습이다.


두번 째 나오는 물은 DetailLevel 30에 타임값만큼 UV를 이동해 준 모습이다.


이처럼 자유롭게 흐르는 물의 값을 조정할 수 있다.



Blendstate는 이와 같이 설정해 주면 된다. 

쉐이더에서 알파값을 건들 필요 없이, 블렌드 상태객체의 설정을 다르게 하는것만으로 투명한 오브젝트를 만들 수 있다. 



ps. 우상단의 RenderTarget에 나오지 않는 이유는, 알파값이 있는 오브젝트이기 때문이다.