[完]MMORPG_Server,Client[2010-2-5].zip

MapTool_3D Water, fog, snow 완료.zip


음...
DirectX 는 2009, 10월 버젼 이었던거 같네요.
VS 2008 작업입니다.

사실 지금 보면 보잘것 없는 소스이긴 한데, 공부하시는데 도움이 되길 바라는 마음으로 공개합니다..

저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소


음.. 결국 이전에 소스 갈아 엎기 전의 부분까지 완성했습니다..
이제 남은건, 스카이박스 좀 씌워주고
오브젝트정도 띄우고, 에니메이션 돌려주고...
뭐 그 정도만 하면...

.... 어라... 짐 맵툴을 만드는건지 게임을 만드는건지.. 분간이 안가는군요.. orz
저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

수면을 하고, 그다음 쉬운 안개 쉐이더를 할려고 하다가
Shadre X2 책의 쉐이더를 적용 하려고 하는데..
의외로 코드를 그대로 copy 하니 텍스쳐가 날아가 버리더군요..
뭐가 문제인가 하다가 .... 결국 .. lerp 여기 값을 수정하니까 제대로 나오는것에
맥이 빠져 버렸습니다. orz

어쨋든 한것에 대한 스샷 입니다.


그리고 이건 그 HLSL 코드 입니다.
// It use the layer fog value
float4x4 matWorldViewProj;
float4x4 matWorldView;
float4x4 matWorld;
float4 fFog;
float4 vCamera;
float4 colorFog;
struct VS_INPUT
{
 float4 Position     : POSITION;
 float3 Diffuse   : COLOR0;
 float2 Tex0         : TEXCOORD0;
};
struct VS_OUTPUT
{
 float4 Position     : POSITION;
 float3 Diffuse   : COLOR;
 float3 FogVal   : COLOR1;
 float2 Tex0     : TEXCOORD0;
 float  Fog         : FOG;
};
struct PS_OUTPUT
{
 float4 Color: COLOR;
};
uniform sampler2D baseTexture;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// exp2 fog program
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void exp2_main_vs(in const VS_INPUT Input, out VS_OUTPUT Out)
{
 float4  clpPos, worldPos;
 // Init output
 Out = (VS_OUTPUT) 0;
 // Calculate the clip space position
 clpPos   = mul(Input.Position, matWorldViewProj);
 Out.Position = clpPos;
 // Simply pass on the texture coords and the vertex color
  Out.Tex0.xy  = Input.Tex0.xy;
 Out.Diffuse  = Input.Diffuse;
 // Extract the fog parameters
 float fDensity = fFog.x;
 float fFogEnd = fFog.y;
 // Calculate the vertex position in world space
 worldPos  = mul(Input.Position, matWorld);
 // Calculate the distance to the viewer in world space
 float fDistance = distance(worldPos, vCamera);
 // The distance is scaled to have a value of 4 at distance: FogEnd
 float fDist  = fDistance/fFogEnd*4;
 // Exp squared calculation
 float f = exp(-(fDist*fDensity)*(fDist*fDensity));
 // Set the fog value
 Out.FogVal.x = f; // Passed to PixelShader using color register
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// It use the layer fog shader program
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void layer_main_vs(in const VS_INPUT Input, out VS_OUTPUT Out)
{
 float4 clpPos, camPos, worldPos;
 float  fDistance;
 // Init output
 Out = (VS_OUTPUT)0;
 // Calculate the clip space position
 clpPos   = mul(Input.Position, matWorldViewProj);
 Out.Position = clpPos;
 // Simply pass on the texture coords and the vertex color
 Out.Tex0.xy  = Input.Tex0.xy;
 Out.Diffuse  = Input.Diffuse;
 
 // Get fog parameter
 float fFogTop = fFog.x;
 float fFogEnd = fFog.y;
 float fFogRange = fFog.z;
 // Calculate the world position
 worldPos  = mul(Input.Position, matWorld);
 // Calculate the distance to the viewer
 fDistance = distance(worldPos, vCamera);

 // Project both points into the x-z plane
 float4 vCameraProj, vWorldProj;
 vCameraProj  = vCamera;
 vCameraProj.y  = 0;
 vWorldProj  = worldPos;
 vWorldProj.y  = 0;
 // Scaled distance calculation in x-z plane
 float fDeltaD   = distance(vCameraProj, vWorldProj)/fFogEnd*2.0f;
 // Height based calculations
 float fDeltaY, fDensityIntegral;
 if(vCamera.y > fFogTop)
 {
  if (worldPos.y < fFogTop)
  {
   fDeltaY = (fFogTop - worldPos.y)/fFogRange*2;
   fDensityIntegral = (fDeltaY * fDeltaY * 0.5f);
  }
  else
  {
   fDeltaY = 0.0f;
   fDensityIntegral = 0.0f;
  }
 }
 else
 {
  if (worldPos.y < fFogTop)
  {
   float fDeltaA = (fFogTop - vCamera.y)/fFogRange*2;
   float fDeltaB = (fFogTop - worldPos.y)/fFogRange*2;
   fDeltaY =abs(fDeltaA -fDeltaB);
   fDensityIntegral = abs((fDeltaA * fDeltaA * 0.5f) - (fDeltaB * fDeltaB * 0.5f));
  }
  else
  {
   fDeltaY = abs(fFogTop - vCamera.y)/fFogRange*2;
   fDensityIntegral = abs(fDeltaY * fDeltaY * 0.5f);
  }
 }
 float fDensity;
 if (fDeltaY != 0.0f)
 {
  fDensity = (sqrt(1.0f + ((fDeltaD / fDeltaY) * (fDeltaD / fDeltaY)))) * fDensityIntegral;
 }
 else
  fDensity = 0.0f;
 float f= exp(-fDensity);
 // Set the fog value
 Out.FogVal.x = f;   // Passed to PixelShader using color register
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main_fs(in const VS_OUTPUT Input, out PS_OUTPUT Out)
{
 // Init output
 Out = (PS_OUTPUT) 0;
 // Retrieve base texture
 float4 colorBase = tex2D(baseTexture, Input.Tex0);
 
 // Fog blending
 float f = Input.FogVal.x;
 Out.Color = lerp(colorFog, colorBase , f);
}

int Color;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// technique
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
technique FOG
{
 
      // use a linear fog
 pass P0
 {
         //
     // Set Misc render states.
     pixelshader       = null;
     vertexshader      = null;
     fvf              = XYZ | Normal;
     Lighting          = true;
     NormalizeNormals = true;
     SpecularEnable    = false;
     //
     // Fog States
     FogVertexMode  = LINEAR; // linear fog function
     FogStart            = float(fFog.x);  // fog starts 50 units away from viewpoint
     FogEnd         = float(fFog.y); // fog ends 300 units away from viewpoint
     FogColor       = int(Color); // gray
     FogEnable      = true;       // enable
 }
 // use a exp log fog
 pass P1
 {
  vertexshader = compile vs_1_1 exp2_main_vs();
  pixelshader = compile ps_2_0 main_fs();
 }
 // use a layer shader fog
 pass P2
 {
  vertexshader = compile vs_1_1 layer_main_vs();
  pixelshader = compile ps_2_0 main_fs();
 }
}

패스에 여러 안개 효과를 줬는데요..
패스 0 이 용책의 소스 그대로 copy... 음... 
패스 1은 exp2 의 안개 효과이구요
패스 2는 레이어 안개 입니다.

저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

최근, 게임회사에 들어가기 위해 여러 작업을 하고 있습니다만...
제가 해온건 거의 Network 관련이라 (이쪽이 은근히 재미 있습니다..) Network 관련 프로그램을 짜거나 했었는데..

막상 이력서 쓸려고 보니, 게임회사에서 한눈에 볼 수 있는 작품이 없더군요...
(Network 경우 DB 셋팅이니, 서버, 클라이언트 소스 동시에 검토 하니... 의외로 잘 안먹히는 느낌입니다..)

역시 시대는 3D... 3D로 최소한의 능력을 보여주자 해서 (라기 보단 뭔가 네트워크랑 2D(MFC)로 작품내니 무시당하는 느낌이....)이전에 만들었던 맵툴 소스를 열어서 디버깅 했습니다만...

그땐, 셀러논 시스템이었고, 지금은 AMD 시스템... 윈도우도 비스타 -> 7...
그리고 CG 컴파일러 문제....  여튼 지금 보니 프로그램이 엄청 꼬여있더군요...

그래서 기분을 가볍게 하고, 처음부터 갈아 엎어서 만들고 있는 도중....

맵툴의 맵 시스템은, 친구에게 받아서 대략 구조 검토하고 개조한 뒤, 위에 좀 괜찮은 효과를 씌울까 하다가
역시 믿을 만한건 화면 효과라.... 이전의 수면효과를 CG (NVidia 의)를 해볼려 하다가..
기초 부터 하는게 좋을꺼 같아 HLSL 로 하기로 했습니다.

그런데.. 이거 의외로 소스가 없더군요.(특히 우리나라..)
이거 받은 친구에게 물어봤는데.. 수면 쉐이더가 그렇게 고급기술은 아니라고 들었습니다만...

어떻게 구현하는지 소스 좀 구경하려고 하니 죄다 스샷 찍어놓고, "나 이거 했어요" 느낌이더군요.....

음.......
결국, 이전에 오우거 엔진 공부할때 네이버 오우거 카페의 주바리님의 바다 쉐이더 분석을 가지고 공부 한적이 있어서, 그걸 이용하기로 했습니다.
하지만, 오우거 엔진의 경우 CG를 사용하기에 HLSL코드가 아니라 살짝 요령을 가지고 바꿔 봤습니다.

제 글은 그냥 HLSL소스를 필요로 하는.... (제가 봤을때 이건 대학생 레벨 정도 일꺼 같은..)
분들꼐 많은 도움이 되시길 바라면서...
제 글에 이해가 잘 안가시는 분은
http://starlike.cafe24.com/moniwiki/wiki.php/OgreOceanDemoAnalysis?action=show
이쪽의 주바리님이 분석한걸 봐주시기 바랍니다.


처음 소스 입니다.
파란 화면 평면을 띄어 봅시다..

float4x4 WorldViewProj;
struct a2v {
    float4 Position : POSITION;   // in object space
    float2 TexCoord : TEXCOORD0;
};
struct v2f {
    float4 Position  : POSITION;  // in clip space
};
v2f main_vs( a2v IN)
{
    v2f OUT;
    float4 P = IN.Position;
   
    OUT.Position = mul(P, WorldViewProj);
   
    return OUT;
}
/******************************************************************************/
float4 main_fs(v2f IN) : COLOR
{
    return float4(0, 0, 1, 1);
}


이건 삼각형 2개로 이루워진... 말 그래도 그냥 평면입니다.


파랗게 변했군요..
픽셀 출력이 float(0,0,1,1) 이니까 어쩔 수 없겠지만요 ...
주바리님 소스에 의하면 버텍스 쉐이더의 mul 부분의 연산 순서가 바껴있는데요..
이건 CG와 HLSL의 컴파일 차이인지... 음...

다음 차례 입니다.

float4x4 WorldViewProj : WORLDVIEWPROJ; //our world view projection matrix
float4 eyePosition;
float time;
float2 textureScale = float2(25, 25);
texture texture0;
texture texture1;
 
sampler2D texSampler : TEXUNIT0 = sampler_state
{
 Texture   = (texture0);
    MIPFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
};
//application to vertex structure
struct a2v {
    float4 Position : POSITION;   // in object space
    float2 TexCoord : TEXCOORD0;
};
//vertex to pixel shader structure
struct v2f {
    float4 Position  : POSITION;  // in clip space
     
    float2 bumpCoord0 : TEXCOORD3;
};
//pixel shader to screen
struct p2f
{
    float4 color    : COLOR0;
};
void main_vs(in a2v IN, out v2f OUT)
{
    float4 P = IN.Position;
   
    OUT.Position = mul(P, WorldViewProj);
    OUT.bumpCoord0.xy = IN.TexCoord * textureScale;
}
/******************************************************************************/
uniform sampler2D NormalMap;
void main_fs(in v2f IN, out p2f OUT)
{
    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
 
    float3 N = normalize(t0.xyz);
    float3x3 m; // tangent to world matrix
    m[0] = float3(1, 0, 0);
    m[1] = float3(0, 0, 1);
    m[2] = float3(0, 1, 0);
   
    N = normalize( mul( N, m ) );
   
    float amplitude = saturate(dot(N, float3(0, 1, 0)));
   
    OUT.color = float4(0, 0, amplitude, 1);
}
technique water
{
    pass p0
    {
        vertexshader = compile vs_1_1 main_vs();
        pixelshader = compile ps_2_0 main_fs();
    }
}


텍스쳐를 씌었습니다.... 멀리 떨어져서 그냥 다 검은색으로 보이네요.

평면에 웨이브를 줘 보겠습니다.
float4x4 WorldViewProj : WORLDVIEWPROJ; //our world view projection matrix
float4 eyePosition;
float time;
float2 textureScale = float2(25, 26);
float waveFreq = 0.028;
float waveAmp = 1.8;

texture texture0;
texture texture1;
 
/******************************************************************************/
sampler2D texSampler : TEXUNIT0 = sampler_state
{
 Texture   = (texture0);
    MIPFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
};
struct Wave {
  float freq;  // 2*PI / wavelength
  float amp;   // amplitude
  float phase; // speed * 2*PI / wavelength
  float2 dir;
};
/******************************************************************************/
//application to vertex structure
struct a2v {
    float4 Position : POSITION;   // in object space
    float2 TexCoord : TEXCOORD0;
};
//vertex to pixel shader structure
struct v2f {
    float4 Position  : POSITION;  // in clip space
     
    float2 bumpCoord0 : TEXCOORD3;
};
//pixel shader to screen
struct p2f
{
    float4 color    : COLOR0;
};
/******************************************************************************/
void main_vs(in a2v IN, out v2f OUT)
{
    #define NWAVES 2
    Wave wave[NWAVES] = {
        { 1.0, 1.0, 0.5, float2(-1, 0) },
        { 2.0, 0.5, 1.7, float2(-0.7, 0.7) }
    };
    wave[0].freq = waveFreq;
    wave[0].amp = waveAmp;
    wave[1].freq = waveFreq * 3.0;
    wave[1].amp = waveAmp * 0.33;
    float4 P = IN.Position;
   
    int i = 0;
    float angle = dot(wave[i].dir, P.xz) * wave[i].freq + time * wave[i].phase;
    P.y += wave[i].amp * sin( angle );
    OUT.Position = mul(P, WorldViewProj);
    OUT.bumpCoord0.xy = IN.TexCoord * textureScale;
}
/******************************************************************************/
uniform sampler2D NormalMap;
void main_fs(in v2f IN, out p2f OUT)
{
    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
 
    float3 N = normalize(t0.xyz);
    float3x3 m; // tangent to world matrix
    m[0] = float3(1, 0, 0);
    m[1] = float3(0, 0, 1);
    m[2] = float3(0, 1, 0);
   
    N = normalize( mul( N, m ) );
   
    float amplitude = saturate(dot(N, float3(0, 1, 0)));
   
    OUT.color = float4(0, 0, amplitude, 1);
}
technique water
{
    pass p0
    {
        vertexshader = compile vs_1_1 main_vs();
        pixelshader = compile ps_2_0 main_fs();
    }
}




음.. 이렇게 확대해 봐도 잘 모르겠습니다..
뭔가 미묘하게 움직이는게 보이기는 하는데요
너무 어두워서... >_<


위의 소스를 좀더 개량해 봅니다.
float4x4 WorldViewProj : WORLDVIEWPROJ; //our world view projection matrix
float4 eyePosition;
float time;
float2 textureScale = float2(25, 26);
float waveFreq = 0.028;
float waveAmp = 1.8;
texture texture0;
texture texture1;
 
/******************************************************************************/
sampler2D texSampler : TEXUNIT0 = sampler_state
{
 Texture   = (texture0);
    MIPFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
};
struct Wave {
  float freq;  // 2*PI / wavelength
  float amp;   // amplitude
  float phase; // speed * 2*PI / wavelength
  float2 dir;
};
/******************************************************************************/
//application to vertex structure
struct a2v {
    float4 Position : POSITION;   // in object space
    float2 TexCoord : TEXCOORD0;
};
//vertex to pixel shader structure
struct v2f {
    float4 Position  : POSITION;  // in clip space
     
    float2 bumpCoord0 : TEXCOORD3;
};
//pixel shader to screen
struct p2f
{
    float4 color    : COLOR0;
};
/******************************************************************************/
void main_vs(in a2v IN, out v2f OUT)
{
    #define NWAVES 2
    Wave wave[NWAVES] = {
        { 1.0, 1.0, 0.5, float2(-1, 0) },
        { 2.0, 0.5, 1.7, float2(-0.7, 0.7) }
    };
    wave[0].freq = waveFreq;
    wave[0].amp = waveAmp;
    wave[1].freq = waveFreq * 3.0;
    wave[1].amp = waveAmp * 0.33;
    float4 P = IN.Position;
   
    float angle;
    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 );
    }
    OUT.Position = mul(P, WorldViewProj);
    OUT.bumpCoord0.xy = IN.TexCoord * textureScale;
}
/******************************************************************************/
uniform sampler2D NormalMap;
void main_fs(in v2f IN, out p2f OUT)
{
    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
 
    float3 N = normalize(t0.xyz);
    float3x3 m; // tangent to world matrix
    m[0] = float3(1, 0, 0);
    m[1] = float3(0, 0, 1);
    m[2] = float3(0, 1, 0);
   
    N = normalize( mul( N, m ) );
   
    float amplitude = saturate(dot(N, float3(0, 1, 0)));
   
    OUT.color = float4(0, 0, amplitude, 1);
}
technique water
{
    pass p0
    {
        vertexshader = compile vs_1_1 main_vs();
        pixelshader = compile ps_2_0 main_fs();
    }
}


음... 뭔가 더 미묘하게 움직이는 느낌이 드는군요.. ㅋㅋ

float4x4 WorldViewProj : WORLDVIEWPROJ; //our world view projection matrix
float4 eyePosition;
float time;
float2 textureScale = float2(25, 26);
float waveFreq = 0.028;
float waveAmp = 1.8;
float BumpScale = 1;
texture texture0;
texture texture1;
 
/******************************************************************************/
sampler2D texSampler : TEXUNIT0 = sampler_state
{
 Texture   = (texture0);
    MIPFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
};
struct Wave {
  float freq;  // 2*PI / wavelength
  float amp;   // amplitude
  float phase; // speed * 2*PI / wavelength
  float2 dir;
};
/******************************************************************************/
//application to vertex structure
struct a2v {
    float4 Position : POSITION;   // in object space
    float2 TexCoord : TEXCOORD0;
};
//vertex to pixel shader structure
struct v2f {
    float4 Position  : POSITION;  // in clip space
   
// tangent to obj space transform
    float3 rotMatrix1 : TEXCOORD0; // first row of the 3x3 transform
    float3 rotMatrix2 : TEXCOORD1; // second row of the 3x3 transform
    float3 rotMatrix3 : TEXCOORD2; // third row of the 3x3 transform
    float2 bumpCoord0 : TEXCOORD3;
};
//pixel shader to screen
struct p2f
{
    float4 color    : COLOR0;
};
/******************************************************************************/
void main_vs(in a2v IN, out v2f OUT)
{
    #define NWAVES 2
    Wave wave[NWAVES] = {
        { 1.0, 1.0, 0.5, float2(-1, 0) },
        { 2.0, 0.5, 1.7, float2(-0.7, 0.7) }
    };
    wave[0].freq = waveFreq;
    wave[0].amp = waveAmp;
    wave[1].freq = waveFreq * 3.0;
    wave[1].amp = waveAmp * 0.33;
    float4 P = IN.Position;
   
     // sum waves
    float ddx = 0.0, ddy = 0.0;
    float deriv;
    float angle;
   
    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 );
        deriv = wave[i].freq * wave[i].amp * cos(angle);
        ddx -= deriv * wave[i].dir.x;
        ddy -= deriv * wave[i].dir.y;
    }
   
    // compute the 3x3 tranform from tangent space to object space
    // first rows are the tangent and binormal scaled by the bump scale
    OUT.rotMatrix1.xyz = BumpScale * normalize(float3(1, ddy, 0)); // Binormal
    OUT.rotMatrix2.xyz = BumpScale * normalize(float3(0, ddx, 1)); // Tangent
    OUT.rotMatrix3.xyz = normalize(float3(ddx, 1, ddy)); // Normal
    OUT.Position = mul(P, WorldViewProj);
    OUT.bumpCoord0.xy = IN.TexCoord * textureScale;
}
/******************************************************************************/
uniform sampler2D NormalMap;
void main_fs(in v2f IN, out p2f OUT)
{
    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
 
    float3 N = normalize(t0.xyz);
    float3x3 m; // tangent to world matrix
    m[0] = float3(1, 0, 0);
    m[1] = float3(0, 0, 1);
    m[2] = float3(0, 1, 0);
   
    N = normalize( mul( N, m ) );
   
    float amplitude = saturate(dot(N, float3(0, 1, 0)));
   
    OUT.color = float4(0, 0, amplitude, 1);
}
technique water
{
    pass p0
    {
        vertexshader = compile vs_1_1 main_vs();
        pixelshader = compile ps_2_0 main_fs();
    }
}


노멀 맵핑을 교정한 소스의 결과 입니다.....
이렇게 봐도... 음.... 역시 그냥 검은 평면에 뭔가 파란 점이 떠다니는 정도로 밖에 안보이네요..


여기에 주변광을 넣을 준비 하는 소스입니다.
float4x4 WorldViewProj : WORLDVIEWPROJ; //our world view projection matrix
float time;
float2 textureScale = float2(25, 26);
float waveFreq = 0.028;
float waveAmp = 1.8;
float BumpScale = 1;
float4 eyePosition;
float4 deepColor = float4(0, 0.3, 0.5, 1.0);
float4 shallowColor = float4(0, 1, 1, 1.0);
float waterAmount = 0.3;
texture texture0;
texture texture1;
 
/******************************************************************************/
sampler2D NormalMap: TEXUNIT0 = sampler_state
{
 Texture   = (texture0);
    MIPFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
};
struct Wave {
  float freq;  // 2*PI / wavelength
  float amp;   // amplitude
  float phase; // speed * 2*PI / wavelength
  float2 dir;
};
/******************************************************************************/
//application to vertex structure
struct a2v {
    float4 Position : POSITION;   // in object space
    float2 TexCoord : TEXCOORD0;
};
//vertex to pixel shader structure
struct v2f {
    float4 Position  : POSITION;  // in clip space
   
// tangent to obj space transform
    float3 rotMatrix1 : TEXCOORD0; // first row of the 3x3 transform
    float3 rotMatrix2 : TEXCOORD1; // second row of the 3x3 transform
    float3 rotMatrix3 : TEXCOORD2; // third row of the 3x3 transform
    float2 bumpCoord0 : TEXCOORD3;
    float2 bumpCoord1 : TEXCOORD4;
    float2 bumpCoord2 : TEXCOORD5;
 
   float3 eyeVector : TEXCOORD7;
};
//pixel shader to screen
struct p2f
{
    float4 color    : COLOR0;
};
/******************************************************************************/
void main_vs(in a2v IN, out v2f OUT)
{
    #define NWAVES 2
    Wave wave[NWAVES] = {
        { 1.0, 1.0, 0.5, float2(-1, 0) },
        { 2.0, 0.5, 1.7, float2(-0.7, 0.7) }
    };
    wave[0].freq = waveFreq;
    wave[0].amp = waveAmp;
    wave[1].freq = waveFreq * 3.0;
    wave[1].amp = waveAmp * 0.33;
    float4 P = IN.Position;
   
     // sum waves
    float ddx = 0.0, ddy = 0.0;
    float deriv;
    float angle;
   
    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 );
        deriv = wave[i].freq * wave[i].amp * cos(angle);
        ddx -= deriv * wave[i].dir.x;
        ddy -= deriv * wave[i].dir.y;
    }
   
    // compute the 3x3 tranform from tangent space to object space
    // first rows are the tangent and binormal scaled by the bump scale
    OUT.rotMatrix1.xyz = BumpScale * normalize(float3(1, ddy, 0)); // Binormal
    OUT.rotMatrix2.xyz = BumpScale * normalize(float3(0, ddx, 1)); // Tangent
    OUT.rotMatrix3.xyz = normalize(float3(ddx, 1, ddy)); // Normal
    OUT.Position = mul(P, WorldViewProj);
   
    // calculate texture coordinates for normal map lookup
    OUT.bumpCoord0.xy = IN.TexCoord * textureScale;
    OUT.bumpCoord1.xy = IN.TexCoord * textureScale * 2.0;
    OUT.bumpCoord2.xy = IN.TexCoord * textureScale * 4.0;
 
    OUT.eyeVector = P.xyz - eyePosition; // eye position in vertex space
}
/******************************************************************************/
void main_fs(in v2f IN, out p2f OUT)
{
    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
    float4 t1 = tex2D(NormalMap, IN.bumpCoord1) * 2.0 - 1.0;
    float4 t2 = tex2D(NormalMap, IN.bumpCoord2) * 2.0 - 1.0;
    float3 N = t0.xyz + t1.xyz + t2.xyz;
   
    float3x3 m; // tangent to world matrix
    m[0] = IN.rotMatrix1;
    m[1] = IN.rotMatrix2;
    m[2] = IN.rotMatrix3;
   
    N = normalize( mul( m, N ) );
   
    float3 E = normalize(IN.eyeVector);
   
    float facing = 1.0 - max(dot(-E, N), 0);
    float4 waterColor = lerp(shallowColor, deepColor, facing) * waterAmount;
   
    OUT.color = waterColor;
}
technique water
{
    pass p0
    {
        vertexshader = compile vs_1_1 main_vs();
        pixelshader = compile ps_2_0 main_fs();
    }
}


음... 역시 아직도 검은 평면.. orz
포기하지 않고 소스를 좀더 수정해 봅니다.

float4x4 WorldViewProj : WORLDVIEWPROJ; //our world view projection matrix
float time;
float2 textureScale = float2(25, 26);
float waveFreq = 0.028;
float waveAmp = 1.8;
float BumpScale = 1;
float2 bumpSpeed = float2(0.015, 0.005);
float4 eyePosition;
float4 deepColor = float4(0, 0.3, 0.5, 1.0);
float4 shallowColor = float4(0, 1, 1, 1.0);
float waterAmount = 0.3;
texture texture0;
texture texture1;
 
/******************************************************************************/
sampler2D NormalMap: TEXUNIT0 = sampler_state
{
 Texture   = (texture0);
    MIPFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
};
struct Wave {
  float freq;  // 2*PI / wavelength
  float amp;   // amplitude
  float phase; // speed * 2*PI / wavelength
  float2 dir;
};
/******************************************************************************/
//application to vertex structure
struct a2v {
    float4 Position : POSITION;   // in object space
    float2 TexCoord : TEXCOORD0;
};
//vertex to pixel shader structure
struct v2f {
    float4 Position  : POSITION;  // in clip space
   
// tangent to obj space transform
    float3 rotMatrix1 : TEXCOORD0; // first row of the 3x3 transform
    float3 rotMatrix2 : TEXCOORD1; // second row of the 3x3 transform
    float3 rotMatrix3 : TEXCOORD2; // third row of the 3x3 transform
    float2 bumpCoord0 : TEXCOORD3;
    float2 bumpCoord1 : TEXCOORD4;
    float2 bumpCoord2 : TEXCOORD5;
    float3 eyeVector : TEXCOORD7;
};
//pixel shader to screen
struct p2f
{
    float4 color    : COLOR0;
};
/******************************************************************************/
void main_vs(in a2v IN, out v2f OUT)
{
    #define NWAVES 2
    Wave wave[NWAVES] = {
        { 1.0, 1.0, 0.5, float2(-1, 0) },
        { 2.0, 0.5, 1.7, float2(-0.7, 0.7) }
    };
    wave[0].freq = waveFreq;
    wave[0].amp = waveAmp;
    wave[1].freq = waveFreq * 3.0;
    wave[1].amp = waveAmp * 0.33;
    float4 P = IN.Position;
   
     // sum waves
    float ddx = 0.0, ddy = 0.0;
    float deriv;
    float angle;
   
    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 );
        deriv = wave[i].freq * wave[i].amp * cos(angle);
        ddx -= deriv * wave[i].dir.x;
        ddy -= deriv * wave[i].dir.y;
    }
   
    // compute the 3x3 tranform from tangent space to object space
    // first rows are the tangent and binormal scaled by the bump scale
    OUT.rotMatrix1.xyz = BumpScale * normalize(float3(1, ddy, 0)); // Binormal
    OUT.rotMatrix2.xyz = BumpScale * normalize(float3(0, ddx, 1)); // Tangent
    OUT.rotMatrix3.xyz = normalize(float3(ddx, 1, ddy)); // Normal
    OUT.Position = mul(P, WorldViewProj);
   
    // calculate texture coordinates for normal map lookup
    OUT.bumpCoord0.xy = IN.TexCoord * textureScale + time * bumpSpeed;
    OUT.bumpCoord1.xy = IN.TexCoord * textureScale * 2.0 + time * bumpSpeed * 4.0;
    OUT.bumpCoord2.xy = IN.TexCoord * textureScale * 4.0 + time * bumpSpeed * 8.0;
 
    OUT.eyeVector = P.xyz - eyePosition; // eye position in vertex space
}
/******************************************************************************/
void main_fs(in v2f IN, out p2f OUT)
{
    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
    float4 t1 = tex2D(NormalMap, IN.bumpCoord1) * 2.0 - 1.0;
    float4 t2 = tex2D(NormalMap, IN.bumpCoord2) * 2.0 - 1.0;
    float3 N = t0.xyz + t1.xyz + t2.xyz;
   
    float3x3 m; // tangent to world matrix
    m[0] = IN.rotMatrix1;
    m[1] = IN.rotMatrix2;
    m[2] = IN.rotMatrix3;
   
    N = normalize( mul( N, m ) );
   
    float3 E = normalize(IN.eyeVector);
   
    float facing = 1.0 - max(dot(-E, N), 0);
    float4 waterColor = lerp(shallowColor, deepColor, facing) * waterAmount;
   
    OUT.color = waterColor;
}
technique water
{
    pass p0
    {
        vertexshader = compile vs_1_1 main_vs();
        pixelshader = compile ps_2_0 main_fs();
    }
}




여기까지 하니까 이제 뭔가 보이기 시작하네요.
평면이 꿈툴거리는것도 뭔가 그럴듯 합니다.

이제 여기에 SkyCube, 하늘 Texture 를 씌여 줍니다.
오우거 소스의 이 소스는 원래 기반이 SkyCube 이므로 SkyCube 로 텍스쳐를 불러오는게
좀더 자연스러운 수면효과를 만들 수 있습니다.

float4x4 WorldViewProj : WORLDVIEWPROJ; //our world view projection matrix
float time;
float2 textureScale = float2(25, 26);
float waveFreq = 0.028;
float waveAmp = 1.8;
float BumpScale = 0.2;
float2 bumpSpeed = float2(0.015, 0.005);
float4 eyePosition;
float4 deepColor = float4(0, 0.3, 0.5, 1.0);
float4 shallowColor = float4(0, 1, 1, 1.0);
float waterAmount = 0.3;
float4 reflectionColor = float4(0.95, 1, 1, 1.0);
float reflectionAmount = 1.0;
float reflectionBlur = 0.0;
    
float fresnelPower = 5.0;
float fresnelBias = 0.328;
float hdrMultiplier = 0.471;

texture texture0;
texture texture1;
 
/******************************************************************************/
sampler2D NormalMap: TEXUNIT0 = sampler_state
{
 Texture   = (texture0);
    MIPFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
};
sampler2D EnvironmentMap: TEXUNIT0 = sampler_state
{
 Texture   = (texture1);
    MIPFILTER = LINEAR;
    MAGFILTER = LINEAR;
    MINFILTER = LINEAR;
};
struct Wave {
  float freq;  // 2*PI / wavelength
  float amp;   // amplitude
  float phase; // speed * 2*PI / wavelength
  float2 dir;
};
/******************************************************************************/
//application to vertex structure
struct a2v {
    float4 Position : POSITION;   // in object space
    float2 TexCoord : TEXCOORD0;
};
//vertex to pixel shader structure
struct v2f {
    float4 Position  : POSITION;  // in clip space
   
// tangent to obj space transform
    float3 rotMatrix1 : TEXCOORD0; // first row of the 3x3 transform
    float3 rotMatrix2 : TEXCOORD1; // second row of the 3x3 transform
    float3 rotMatrix3 : TEXCOORD2; // third row of the 3x3 transform
    float2 bumpCoord0 : TEXCOORD3;
    float2 bumpCoord1 : TEXCOORD4;
    float2 bumpCoord2 : TEXCOORD5;
    float3 eyeVector : TEXCOORD7;
};
//pixel shader to screen
struct p2f
{
    float4 color    : COLOR0;
};
/******************************************************************************/
void main_vs(in a2v IN, out v2f OUT)
{
    #define NWAVES 2
    Wave wave[NWAVES] = {
        { 1.0, 1.0, 0.5, float2(-1, 0) },
        { 2.0, 0.5, 1.7, float2(-0.7, 0.7) }
    };
    wave[0].freq = waveFreq;
    wave[0].amp = waveAmp;
    wave[1].freq = waveFreq * 3.0;
    wave[1].amp = waveAmp * 0.33;
    float4 P = IN.Position;
   
     // sum waves
    float ddx = 0.0, ddy = 0.0;
    float deriv;
    float angle;
   
    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 );
        deriv = wave[i].freq * wave[i].amp * cos(angle);
        ddx -= deriv * wave[i].dir.x;
        ddy -= deriv * wave[i].dir.y;
    }
   
    // compute the 3x3 tranform from tangent space to object space
    // first rows are the tangent and binormal scaled by the bump scale
    OUT.rotMatrix1.xyz = BumpScale * normalize(float3(1, ddy, 0)); // Binormal
    OUT.rotMatrix2.xyz = BumpScale * normalize(float3(0, ddx, 1)); // Tangent
    OUT.rotMatrix3.xyz = normalize(float3(ddx, 1, ddy)); // Normal
    OUT.Position = mul(P, WorldViewProj);
   
    // calculate texture coordinates for normal map lookup
    OUT.bumpCoord0.xy = IN.TexCoord * textureScale + time * bumpSpeed;
    OUT.bumpCoord1.xy = IN.TexCoord * textureScale * 2.0 + time * bumpSpeed * 4.0;
    OUT.bumpCoord2.xy = IN.TexCoord * textureScale * 4.0 + time * bumpSpeed * 8.0;
 
    OUT.eyeVector = P.xyz - eyePosition; // eye position in vertex space
}
/******************************************************************************/
void main_fs(in v2f IN, out p2f OUT)
{
    float4 t0 = tex2D(NormalMap, IN.bumpCoord0) * 2.0 - 1.0;
    float4 t1 = tex2D(NormalMap, IN.bumpCoord1) * 2.0 - 1.0;
    float4 t2 = tex2D(NormalMap, IN.bumpCoord2) * 2.0 - 1.0;
    float3 N = t0.xyz + t1.xyz + t2.xyz;
   
    float3x3 m; // tangent to world matrix
    m[0] = IN.rotMatrix1;
    m[1] = IN.rotMatrix2;
    m[2] = IN.rotMatrix3;
   
    N = normalize( mul( N, m ) );
   
    // reflection
    float3 E = normalize(IN.eyeVector);
    float4 R;
    R.xyz = reflect(E, N);
  
    // Ogre conversion for cube map lookup
    R.z = -R.z;
    R.w = reflectionBlur;
    float4 reflection = tex2Dbias(EnvironmentMap, R);
    // cheap hdr effect
    reflection.rgb *= (reflection.r + reflection.g + reflection.b) * hdrMultiplier;
    // fresnel
    float facing = 1.0 - max(dot(-E, N), 0);
    float fresnel = saturate(fresnelBias + pow(facing, fresnelPower));
    float4 waterColor = lerp(shallowColor, deepColor, facing) * waterAmount;
    reflection = lerp(waterColor,  reflection * reflectionColor, fresnel) * reflectionAmount;
 
    OUT.color = waterColor + reflection;
}
technique water
{
    pass p0
    {
        vertexshader = compile vs_1_1 main_vs();
        pixelshader = compile ps_2_0 main_fs();
    }
}



음.... 꽤 그럴듯한 효과가 나왔습니다.

이것만으론 뭐가 뭔지 역시 모르겠습니다 하실 분도 계실꺼 같아서
소스도 같이 올립니다.






저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소


일본에 있으면서.. 슬슬 어학과정도 끝나고해서, 이전의 프로그래밍 감각을 살려볼까 하는 취지에
만들었습니다.

이전 학교에서 턴프로젝트로 만들었던 리눅스 epoll 소스를 사용해서 (덕분에 DB는 MySQL을 사용했습니다)
윈도우 IOCP 서버 구축에 1주일,
클라이언트 제작에 3일.. 서로 데이터 동기화에 3일
총 2주 걸렸네요 orz

일단 결과물 입니다..
<서버 화면>

별볼일 없는 콘솔 화면 입니다..
현재 서버 시간을 1초 마다 갱신하게 만들었습니다.
위의 /last 같은것은 명령어 입니다.


다음 클라이언트 화면 입니다.
3D를 하는것이 좋긴 하지만, 그런거 빠지다간 끝이 없기때문에,
간단하게 현재 서버가 잘 작동되는지 눈으로 확인 가능한 2D GUI 클라이언트 입니다.
DirectX 2D 조차 쓰지 않은 순전 MFC 입니다.. @_@
맵도 원래는 바둑판처럼 가이드선을 그을려고 했는데
재미 없을꺼 같아서 소프트맥스의 창세기 외전2 템페스트의 세계 지도를 가져와 멋대로 붙였습니다.

밑에 서버 IP, port 입력하고 (디폴트 127.0.0.1:9000) connect 하면 서버에 연결됩니다.

ID와 암호를 채팅창으로 입력하면
플레이어 (마리오), 주변의 적(쿠퍼) 들이 뜹니다.

월드의 전체 크기는 5000x3200 으로 적은 렌덤으로 1000개가 뿌려지게 했습니다.
그리고 내 주변의 적들의 위치(거리 약 400), 방향, 타입, 등등의 위치를 recv 받아서 근처에 뿌려줍니다.

물론 다른 플레이어(클라이언트)도 마리오 형상으로 띄어줍니다.
단, 마리오 머리 위에 해당 클라이언트의 ID를 띄어놓게 했습니다.

채팅서버가 기본이므로. 채팅이 제대로 되는지 확인하기 위해 3개의 클라이언트를 띄었습니다.
클라이언트의 채팅은, 자기 주변 (약 200)안의 것들만 통신이 되게 했습니다.

1번 클라이언트 Miss.Ninja의 화면


2번 클라이언트의  Miss.Kim의 화면


3번 클라이언트 Miss.Rin의 화면


채팅내용을 잘 살펴보시면
가운데 닌자 클라이언트는 Kim과 Rin의 이야기를 다 듣지만, 다른 클라이언트는 닌자 클라이언트만 통신이 됩니다.


저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소