'대학생 졸업하기 전 레벨/DirectX'에 해당되는 글 18건


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

.... 어라... 짐 맵툴을 만드는건지 게임을 만드는건지.. 분간이 안가는군요.. 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

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


맵툴 작업현황

그냥.. 비 효과를 포기했습니다.

음... 생각해 보니 갖고 있는 예제가... 무지개 생성 예제이고...
비도 DX10 이 아닌 이상 원하는 결과 갖기 힘들꺼 같고..

그냥 눈 파티클 생성해서 저 동그란 눈송이 그림만 나중에 바꿔서 좀 수정하면 비가 될꺼 같아서....

@_@

음... 그런겁니다.. orz
저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

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


음.. 오늘은 걍 눈 효과를 넣어 봤습니다..
눈 효과

어려운건 없고.. 그냥 용책에 있는걸 배꼇기 때문에...
설정 맞추는게 햇갈렸지만, 그방 ok
음..... 그런데 좀 언벨런스한 느낌이 드네요
석양에..... 눈이라... 음...

참고로 현재 이 프로그램의 목적은
Eco 게임맵같은거 찍어내는 맵툴 프로그램입니다...
음.. 이제 보니 바다효과는 너무 오버해서 만든 느낌이 드네요.. >_<)
에밀크로니클 온라인 게임중
(에밀크로니클 온라인의 눈효과와 바다 효과)

처음 snowball 크기는 0.25f 라.. 눈 2000개 뿌려야 보일듯 말듯..
당연히 프레임은 2,3 을 왔다갔다 해서..

눈을 200개로 줄이고, 크기를 5.0f 로 늘렸습니다..

결과적으로 FPS 도 잡고, 눈효과도 주고...

내일은 비를 한번 도전 한뒤...
(이것도 만만할꺼 같진 않고.. 뭐 현재 파티클 소스 조금 고치면 되지만 그럼 재미 없기에..
쉐이더를 써볼까 합니다만... ... 걍 파티클로 갈까... 고민중입니다.)

그리고 본격 타일 뜯어고치기..
속성이나 Object 처리야.. 이전 2D 맵툴작업때 한거 수정하면서 옮겨오면 되니...
상관없을꺼 같구요..

음... 4월 13일 오사카 일어 학교 수업시작인데 그 이전에 완성 되려나...
저작자 표시 비영리 변경 금지
신고
블로그 이미지

프로그래머 지향자 RosaGigantea

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

티스토리 툴바