Water 만들기.
위의 사진은 Ogre의 Ocean 샘플이다.
가장 첫 시작은 이 샘플을 나도 구현해 보자로 시작되었다.
구현은 OpenglES 2.0을 기준으로 한다.
아래 파일은 Ogre에 들어있는 OpenglES용 셰이더 파일이다.
아래 링크는 Ogre의 Ocean 데모를 CG로 분석한 아티클 이다.
http://starlike.cafe24.com/moniwiki/wiki.php/OgreOceanDemoAnalysis?action=show
아래 링크는 Ogre의 Ocean 데모를 hlsl로 분석한 아티클 이다.
http://rosagigantea.tistory.com/334
지금 내가 하려는 것은 unreal 엔진에 OpenglES 버전으로 셰이더를 만들어 넣는것이다.
좌표계를 잘 알아야 한다. 이것땜에 몇일동안 삽질했다.
왼쪽이 왼손좌표계인 D3D좌표계, 오른쪽이 오른손좌표계인 OpenGL좌표계.
그리고 Unreal에서 사용하는 좌표계는 아래와 같다.
D3D의 왼손좌표를 Z가 up이 되도록 세운 모습이다.
즉, Unreal은 왼손 좌표계를 사용한다.
http://wiki.beyondunreal.com/Rotator
Start by facing in the direction of the positive X axis, with "up" corresponding to the positive Z axis. The Unreal Engine uses a left-handed Cartesian coordinate system, so by definition the positive Y axis is on the right side. ("left-hand rule": if the index finger of your left hand points forward, the thumb upwards, then the middle finger must point to the right)
OpenGL 좌표계
Opengl은 일반적으로 수학에서 사용하는 행벡터방식을 사용한다.
행렬 (메모리 배열 순서)
| m0 m4 m8 m12 |
| m1 m5 m9 m13 |
| m2 m6 m10 m14 |
| m3 m7 m11 m15 |
|Xx Yx Zx Tx | | x |
|Xy Yy Zy Ty | x | y |
|Xz Yz Zz Tz | | z |
|0 0 0 1 | | 1 |
DirectX 좌표계
DirectX는 컴퓨터 그래픽쪽에서 좋아하는 열벡터 방식을 사용한다.
행렬 (메모리 배열 순서)
| m0 m1 m2 m3 |
| m4 m5 m6 m7 |
| m8 m9 m10 m11 |
| m12 m13 m14 m15 |
|Xx Yx Zx Tx |
| x y z 1 | x |Xy Yy Zy Ty |
|Xz Yz Zz Tz |
|0 0 0 1 |
참고한 링크 : http://blog.naver.com/louiset26/110117456690
물을 구현하고자 할 때 신경쓰는 부분은 크게 두가지 이다.
"얼마나 물처럼 움직이는가?"(물리)와 "얼마나 물처럼 보이는가?"(비쥬얼)이다.
이 두가지가 물에 대한 리얼리즘을 표현한다.
// 물의 주파수와 진폭(물의 출렁임을 표현한다)
float waveFreq = 0.058;
float waveAmp = 1.0;
// wave
#define NWAVES 2
Wave wave[NWAVES];
wave[0] = Wave( waveFreq, waveAmp, 0.5, vec2(-1, 0) );
wave[1] = Wave( 3.0 * waveFreq, 0.33 * waveAmp, 1.7, vec2(-0.7, 0.7) );
// vertex position.
vec4 P = Position;
// sum waves
float ddx = 0.0, ddy = 0.0;
float deriv;
float angle;
float time = Update/50.0;
float WaveScale = 0.2;
// 물의 움직임의 합성은 두개의 서로 다른 주파수와 위상변위를 사용하는 두개의 사인 곡선을 사용한다.
for(int i = 0; i<NWAVES; ++i)
{
angle = dot(wave[i].dir, P.xz) * wave[i].freq + time * wave[i].phase;
P.y += wave[i].amp * sin( angle );
// calculate derivate of wave function
deriv = wave[i].freq * wave[i].amp * cos(angle);
ddx -= deriv * wave[i].dir.x;
ddy -= deriv * wave[i].dir.y;
}
그런데 여기에서 좀 고려해야 할 부분이 있다.
opengl의 좌표축과 unreal의 좌표축은 y값과 z값이 반대로 되어 있다.
즉, opengl의 y가 up이면 unreal에서는 z가 up이다.
그래서 위의 빨간색 부분을 아래와 같이 바꿔줘야 위아래로 출렁이는 물을 만들 수 있다.
'Study > ES' 카테고리의 다른 글
inverse 함수 (0) | 2012.09.19 |
---|---|
OPENGL ES 문법 (0) | 2012.08.25 |
GLSL에서 사용하는 수식자, 식별자 (0) | 2012.08.13 |