정점셰이더

struct VS_INPUT //입력을 받는 곳
{
   float4 mPosition : POSITION; //버텍스에서 위치 정보를 받기 위한 시맨틱(DirectX의 버텍스
   로부터 위치 정보를 구하는 기능)
   
   float3 mNormal : NORMAL; // 법선(노멀) 시맨틱
   
};

struct VS_OUTPUT // 정점셰이더가 위치변환 결과를 래스터라이저 하는 과정(이다음에 픽셀
//셰이더로 넘어간다.) 출력하는곳이다.

{
   float4 mPosition : POSITION; //정점 좌표를 위한 시맨틱
   float2 mUV : TEXCOORD0; // (TEXCOORD0) UV좌표 위한 시맨틱
   float2 mDiffuse : TEXCOORD1; 
   float3 mViewDir: TEXCOORD2; // 
   float3 mReflection: TEXCOORD3;  //정반사를 받기 위한 표면 시맨틱
   
};

float4x4 gWorldMatrix; // 월드 공간
float4x4 gViewMatrix;  // 뷰공간(월드공간안에 카메라로 찍힌 공간)
float4x4 gProjectionMatrix; // 투영공간(카메라에 찍힌 물체의 거리가 인지되는것을 
화면으로 그려지는 이미지?)

float4 gWorldLightPositon; //라이트 위치
float4 gWorldCameraPositon; // 카메라 위치(정반사를 구하기위함)


VS_OUTPUT vs_main( VS_INPUT Input ) // VS_OUTPUT로 보내기전에 함수를 작성하는 곳
{
   VS_OUTPUT Output; //반환할 구조체 선언

   Output.mPosition = mul( Input.mPosition, gWorldMatrix ); //mPosition을 공간으로 변환
   
   float3 lightDir = Output.mPosition.xyz - gWorldLightPositon.xyz; //노멀의 위치값을 구한다.
   //정점위치에서 빛위치을 빼주면 정점이 빛에서 어떤 위치에 있는지 알수 있다.
   //난반사를 구하는 값이다.
   lightDir = normalize(lightDir); // 벡터(vector)를 1로 만드는 과정.
   
   float3 viewDir = normalize(Output.mPosition.xyz - gWorldCameraPositon.xyz);
   //정점에서 카메라위치를 빼주면 마찬가지로 정점이 카메라에서 어떤 위치인지 알수 있다.
   //정반사를 구하는 값이다.
   Output.mViewDir = viewDir;
   
   
   Output.mPosition = mul( Output.mPosition, gViewMatrix ); //mPosition을 뷰공간화
   Output.mPosition = mul( Output.mPosition, gProjectionMatrix ); //mPosition을 투영공간화
   
   float3 worldNormal = mul(Input.mNormal, (float3x3)gWorldMatrix); //법선(노멀)을 월드공간으로 변환
   worldNormal = normalize(worldNormal); //난반사
   
   Output.mDiffuse = dot(-lightDir, worldNormal); // 법선을 구할 내적(코사인을 간략한것)
   Output.mReflection = reflect(lightDir, worldNormal); //정반사
   
   Output.mUV = Input.mUV; //텍스쳐UV

    
   return Output;
   
}

픽셀셰이더

struct PS_INPUT //화면에 출력될 픽셀정보에 필요로 하는 것을 넣는다.
//버텍스의 정보가 변화되는 내용이 없기 때문이다. mPosition만 없다.
{
   float2 mUV : TEXCOORD0;
   float3 mDiffuse : TEXCOORD1;
   float3 mViewDir: TEXCOORD2;
   float3 mReflection: TEXCOORD3;
   
};
   

float4 ps_main(PS_INPUT Input) : COLOR //ps_main함수
{   
   
   float4 albedo = tex2D(DiffuseSampler, Input.mUV); //텍스쳐
   
   //float3 diffuse = saturate(Input.mDiffuse); //난반사
    float3 diffuse = gLightColor * albedo.rgb * saturate(Input.mDiffuse);//난반사에 텍스쳐를 추가
    
   float3 reflection = normalize(Input.mReflection);
   float3 ViewDir = normalize(Input.mViewDir);
   
   float3 specular = 0;   
   if(diffuse.x >0) //정반사 (빛이 닿지않는 부분은 필요없기때문에 0이상으로 설정)
   {
      specular = saturate(dot(reflection, -ViewDir)); 
      specular = pow(specular, 20.0f); // 난반사보다 강해야 하므로,
      //빛을 강하게 받아야하니 강제로 값을 올려준다.
   
   }
   
   float3 ambient = float3(0.1f, 0.1f, 0.1f); //물체의 어두운부분이 너무 어둡지 않게
   //임의로 밝게 처리(환경광효과처럼 넣는다.) 
   //즉, 실제 반사가 되서 밝아진것이 아니라 강제로 밝게 한것이다.

   
   
   return float4(ambient + diffuse + specular, 1);
   
}

 

 

 

참고서적: 셰이더 프로그래밍입문의 RenderMonkey기반

'Unity > Code base Shader' 카테고리의 다른 글

Fake Shine  (0) 2021.02.13
Microsoft HLSL  (0) 2021.02.09
인위적 유리 셰이더  (0) 2021.02.09
Z-Buffer, Render Queue, Tag, Blending  (0) 2021.01.01
Unity Shader에 대한 이해  (0) 2021.01.01