정점셰이더

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

docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics

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

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

 

Z는 공간에서 Z축 위치를 뜻하며,Buffer는 카메라와 물체의 거리를 저장하는 메모리 공간을 의미합니다.

 

처음엔 초록색을 그리고, 그다음엔 빨간색을 그리고, 그다음은 파란색순으로 색위를 덫칠한다고 생각해야합니다.

위 과정으로 화면에  컬러들이 표시된다고 상상하면 됩니다.

 

Unity는 Cull , Zwrite, Ztest의 세가지 옵션을 제공합니다.

 

ZTest는 7가지 값이 있습니다.

ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always

기본값은 LEqual  (이미 그려진 오브젝트와 거리가 같거나 더 가까운 경우에 그립니다. 그보다 먼 경우에는 오브젝트로 숨깁니다)입니다.

 

Ztest와 Cull 를 이용하면 재미있는 형태를 만들어 낼수 있다.

 


태그는 위와 같은 구문을 사용합니다. 위 Tag는 전체 셰이더에 영향을 주지만, pass 안에 있으면 선택한 pass에만 영향을 미칩니다.

 

장면에 물체를 그릴때 마다 객체 정보를 GPU에 전달하고 이 그리는 과정을 "Draw Call"이라고 합니다. 셰이더에 pass가 많을수록 드로우콜이 늘어납니다.(카메라는 가장 먼거리에서부터 가까운 물체를 그립니다.)

 

Unity에 처리 대기열을 Render Queue라고 합니다.

Render Queue를 수정하는 방법은 두가지 방법이 있습니다.

위처럼 material inspector의 숫자를 변경하여 순서를 정하거나, 

아래 셰이더 Tag를 이용하는 방법입니다.

 

 

Queue의 순서는 다음과 같습니다.

"Queue"= "배경" 범위는 0 ~ 1499입니다. 기본값은 1000입니다.
"Queue"= "지오메트리" 1500 ~ 2399 범위 기본값은 2000입니다.
"Queue"= "AlphaTest" 2400 ~ 2699 범위 기본값은 2450입니다.
"Queue"= "투명"  2700 ~ 3599 범위 기본값은 3000입니다.
"대기열"= "오버레이" 범위는 3600에서 5000까지입니다. 기본값은 4000입니다.


블랜딩 종류
각종 블랜딩 옵션 설정 방법

 SubShader
    {
        Tags 
        { 
            "RenderType"="Opaque"
            "Queue" = "Transparent"
        }
        
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha //전통적인 투명
            //Blend One OneMinusSrcAlpha // 미리 곱해진 투명
            //Blend One One //ADD
            //Blend OneMinusDstColor One // SOFT ADD
            //Blend DstColor Zero // MULTIPLY
            //Blend DstColor SrcColor // 2X MULTIPLY
            //Blend SrcColor One //OVERLAY
            //Blend OneMinusSrcColor One //SOFT LIGHT
            //Blend Zero OneMinusSrcColor //SUBTRACT


            BlendOp Add  //Default Value
            //BlendOP Sub
            //BlendOP Max
            //BlendOP Min
            //BlendOP RevSub

        Pass

코드는 위처럼 만들어지게 되고, 그 결과는 아래와 같은 순서로 됩니다.

Blend SrcAlpha OneMinusSrcAlpha
Blend One OneMinusSrcAlpha
Blend One One
Blend OneMinusDstColor One
Blend DstColor Zero
Blend DstColor SrcColor
Blend SrcColor One
Blend OneMinusSrcColor One
Blend Zero OneMinusSrcColor
Blend One OneMinusSrcAlpha + BlendOP Sub

유니티 도움말 참고: docs.unity3d.com/Manual/SL-Blend.html

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

Microsoft HLSL  (0) 2021.02.09
인위적 유리 셰이더  (0) 2021.02.09
Unity Shader에 대한 이해  (0) 2021.01.01
Specular 다 광원지원  (0) 2020.12.21
SpecularShader  (0) 2020.12.19

Unity Shaders con CG/HLSL y Shader Graph 강의를 대충듣고 작성된겁니다.

(원어가 스페인어이고 이를 번역한 영어를 또 해석한거라 오역이 있을수 있습니다.)

 

 

물체가 화면에 뿌려지는 과정은 위와 같은과정을 거친다.

 

unity 쉐이더는 CG 코드를 사용한다.

CG언어는 NVIDIA와 마이크로소프트의 협력하여 만든 언어이다.

그리고 이것은 HLSL가 비슷한 구문으로 사용된다.

 

GLSL- OpenGL Shading Language

HLSL- High Level Shader Language

HLSL과 CG는 동일한 언어이지만 다른 이름을 반영합니다.

 

셰이더가 CG 언어로 작동하는 이유 HLSL과 GLSL을 모두 컴파일 할 수 있기 때문입니다.

 

1. Shader의 이름을 정의합니다.

2. Shader 속성을 정의합니다.

3. Shader 시작과끝

4. 하나 이상의 pass를 설정합니다.

 

반투명과 투명픽셀의 블랜딩을 설정하여 투명단계를 설정합니다.

Shader의 모든 속성은 쉐이더랩 언어로 선언됩니다.

이 모든것은 CG언어가 GPU에서 실행됩니다.

 

Unity는 두가지를 선택할수 있는 언어 옵션을 제공합니다.

Surface shader는 빠르고 쉽게 접근이 가능하지만 갖혀진 틀에서 작업해야하며,

Vertex/Fragment Shader는 좀더 많은 범위에서 조작이 가능해집니다.

 

속성은 8가지로 작성될수 있습니다.

 

투명과 불투명을 설정합니다. (이외에 뭐라 설명하는데 이해를 못했네요.)

 

투명패스, 컬러패스, 그림자패스등 렌더 패스를 나타냅니다.

패스가 많을수록 드로우콜이 늘어나게 됩니다.

 

Fallback은 subshader가 실패할 경우 사용해야 하는 기본 셰이더 이름에 해당합니다.

(만든 셰이더가 제대로 작동하지 않는다면 다른 셰이더를 사용하라는 일종에 대비에 해당됩니다.)

 

구조체 사용변수

 

정점 셰이더는 3D 모델의 각 정점에서 실행되는 프로그램입니다.

객체의 정점 위치를 "클립공간" "투사공간"이라고 불리는 자표계로 변환할수 있습니다.

 

물체에 텍스쳐를 붙이고 싶다면 우리는 UV좌표를 갖을 필요가 있습니다.

Fragment Shader는 객체가 화면에 차지하는 각 픽셀에서 실행되는 프로그램입니다.

 

Fragment Shader는 최종적으로 화면에 뿌려지는 픽셀이라고 설명할수 있습니다.

 

그래서 우리는 원하는 결과를 화면에 물체를 뿌리기 위해서는  Vertex Shader와 Fragment Shader 둘다 필요합니다.

 

Unity에서 셰이더를 생성하기위한 표준 언어가 HLSL입니다.

Unity에는 모바일 장치에서 더 나은 작동을 허용하는 몇 가지 추가 데이터 유형이 위처럼 있습니다.

더 높은 정밀도로 데이터 유형으로 작업 할 때 GPU 계산이 높을수록 그러므로,모바일 장치가 더 뜨거워지고 배터리가 더 많이 소모됩니다.

Float는 고정밀 32 비트 데이터 유형입니다.
Half는 16 비트 중간 정밀도 데이터 유형입니다.
fixed는 낮은 정밀도의 11 비트 데이터 유형입니다.

 

벡터와 행열

 

텍스처의 데이터 유형의 예

 

3D 물체가  화면에 뿌려주는 과정

 

float4x4는 UNITY_MATRIX_MVP 행렬에 해당하는 세 개의 개별 행렬이 결합 된 형태입니다.

로컬, 월드, 뷰, 프로젝션 

 

Local space : 물체의 중심을 기준으로 정의됩니다.

POSITION 시맨틱은 꼭지점 값을 이야기 합니다.

float4 vertex : POSITION 의미는 "vertex"변수에 모델의 초기 정점 위치를 저장하여 셰이더에 할당합니다.

 

World space: 포인트의 위치는 그리드의 중심을 기준으로 정의됩니다.

 

View space: 공간에서 한 지점 사이의 거리 좌표에 해당 카메라 뷰의 포인트입니다. 카메라 시선이라고 생각하면됩니다.

 

 

Projection space: 클립스페이스이다.

카메라 렌즈의 중앙에있는 거리와 관련하여 클립 공간이라고도하는 투영 공간에서 좌표 변환 프로세스는 카메라 Frustum와 관련하여 수행됩니다.

Frustum: 근거리 클리핑 평면, 원거리 클리핑 평면 및 시야로 정의됩니다.

SV_POSITION 의미론은 픽셀의 위치에 해당합니다.

(유니티정의:두 클리핑 평면과 경계선에 의해 잘린 피라미드의 형상이 되며, 이것을 뷰 Frustum이라고 합니다.)

 

 

UnityObjectToClipPos ()는 오브젝트를 로드할 때 정점의 위치는 오브젝트 공간에 로드됩니다

물체를 로드하는 방식은 여러가지 이나, 가장 적절하고 간단한 방법은 포함 된 기능을 사용하는 것입니다.

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

인위적 유리 셰이더  (0) 2021.02.09
Z-Buffer, Render Queue, Tag, Blending  (0) 2021.01.01
Specular 다 광원지원  (0) 2020.12.21
SpecularShader  (0) 2020.12.19
diffuseShader  (0) 2020.12.15
Shader "ryoo/RyooSpecularShaderForwardAddooo" 

{ 

	Properties 
	{
	
		_DiffuseTex ("Texture", 2D) = "white" {} 
		_Color ("Color", Color) = (1,0,0,1) 
		_Ambient ("Ambient", Range (0, 1)) = 0.25 
		_SpecColor ("Specular Material Color", Color) = (1,1,1,1) // 스페큘러 컬러
		_Shininess ( "Shininess", Float) = 10 // 스페큘러 강도
	}


	SubShader
	{

		Tags { "LightMode" = "ForwardBase" } 
		LOD 100

		Pass
		{

			CGPROGRAM 
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc" 
			#pragma multi_compile_fwdbase
			#include "UnityLightingCommon.cginc" 

			struct appdata 
			{
				float4 vertex : POSITION; 
				float3 normal : NORMAL;
				float2 uv : TEXCOORD0; 
			}; 

			struct v2f // v2f struct(구조체)에 변수를 추가하고, v2f를 통해 프레그먼트 셰이더에 전달
			{
				float2 uv : TEXCOORD0; 
				float4 vertexClip : SV_POSITION; 
				float4 vertexWorld : TEXCOORD2; // 프레그먼트 셰이더에서 광원 방향 벡터 계산
				float3 worldNormal : TEXCOORD1; 
			}; 

			sampler2D _DiffuseTex; 
			float4 _DiffuseTex_ST; 
			float4 _Color; 
			float _Ambient; 
			float _Shininess; 
			
			v2f vert (appdata v) //정점 셰이더 부분
			{
				v2f o;
				o.vertexClip = UnityObjectToClipPos(v.vertex); 
				//o.vertexWorld = mul(unity_ObjectToWorld, v.vertex);
				o.vertexWorld = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _DiffuseTex); //텍스쳐 영역
				float3 worldNormal = UnityObjectToWorldNormal(v.normal); 
				o.worldNormal = worldNormal;
				return o; 
			} 

			float4 frag (v2f i) : SV_Target //프레그먼트 셰이더 부분
			{
				//정규화된 월드 공간의 노멀 벡터
				float3 normalDirection = normalize( i.worldNormal); 
				
				// 정규화된 뷰 방향 벡터
				float3 viewDirection = normalize(UnityWorldSpaceViewDir(i. vertexWorld)); 
				
				// 정규화된 광원 방향 벡터
				float3 lightDirection = normalize(UnityWorldSpaceLightDir(i. vertexWorld));
				//텍스쳐 영역
				float4 tex =tex2D(_DiffuseTex, i.uv); 
				
				// 디퓨즈(람버트) 구현
				float nl = max(_Ambient, dot(normalDirection, lightDirection));
				float4 diffuseTerm = nl * _Color * tex * _LightColor0; 
	
				//스페큘러(퐁) 구현
				float3 reflectionDirection = reflect(-lightDirection, normalDirection); 
				float3 specularDot = max(0.0, dot(viewDirection, reflectionDirection)); 
				float3 specular = pow(specularDot, _Shininess);
				float4 specularTerm = float4( specular, 1) * _SpecColor * _LightColor0; 
				
	
				float4 finalColor = diffuseTerm + specularTerm;
				return finalColor; 
			} 
			ENDCG
		}

		Pass // 추가 광원을 지원하기 위해서 같은걸 복사하고 몇가지만 수정
		{

			Tags { "LightMode" = "ForwardAdd" } // 추가 광원을 지원하기 위함.
			Blend One One
			CGPROGRAM 
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fwdadd 
			#include "UnityCG.cginc" 
			#include "UnityLightingCommon.cginc" 
			
			struct appdata 
			{
				float4 vertex : POSITION; 
				float3 normal : NORMAL;
				float2 uv : TEXCOORD0; 
			}; 

			struct v2f 
			{
			float2 uv : TEXCOORD0; 
			float4 vertexClip : SV_POSITION; 
			float4 vertexWorld : TEXCOORD2;
			float3 worldNormal : TEXCOORD1; 
			}; 
			
			sampler2D _DiffuseTex; 
			float4 _DiffuseTex_ST; 
			float4 _Color; 
			float _Ambient;
			float _Shininess; 
			
			v2f vert (appdata v) 
			{
				v2f o;
				o.vertexClip = UnityObjectToClipPos(v.vertex); 
				o.vertexWorld = mul(unity_ObjectToWorld, v.vertex); 
				o.uv = TRANSFORM_TEX(v.uv, _DiffuseTex); 
				
				float3 worldNormal = UnityObjectToWorldNormal(v.normal); 
				o.worldNormal = worldNormal;
				return o;
			} 
			
			float4 frag (v2f i) : SV_Target 
			{
			float3 normalDirection = normalize( i.worldNormal); 
			
			// 정규화된 뷰 방향 벡터
			float3 viewDirection = normalize( UnityWorldSpaceViewDir(i.vertexWorld)); 
			
			// 정규화된 광원 방향 벡터
			float3 lightDirection = normalize(UnityWorldSpaceLightDir(i.vertexWorld));
			
			//텍스쳐 영역
			float4 tex = tex2D(_DiffuseTex, i.uv); 
			
			// 디퓨즈(람버트) 구현
			float nl = max(0.0, dot(normalDirection, lightDirection)); // Ambient를 제외시킨다. 포함시키면 빛이 더해져서 너무 밝게 나오기 때문에 0으로 셋팅한다.
			float4 diffuseTerm = nl * _Color * tex * _LightColor0; 
			
			//스페큘러(퐁) 구현
			float3 reflectionDirection = reflect(-lightDirection, normalDirection); 
			float3 specularDot = max(0.0, dot(viewDirection, reflectionDirection)); 
			float3 specular = pow( specularDot, _Shininess); 
			//여기까지 퐁
			float4 specularTerm = float4( specular, 1) *_SpecColor * _LightColor0; 
			float4 finalColor = diffuseTerm + specularTerm;
			return finalColor; 
			}
			ENDCG
		}

	}

}

참고서적: 유니티 물리 기반 셰이더 개발 

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

Z-Buffer, Render Queue, Tag, Blending  (0) 2021.01.01
Unity Shader에 대한 이해  (0) 2021.01.01
SpecularShader  (0) 2020.12.19
diffuseShader  (0) 2020.12.15
좌표공간 변환  (0) 2020.12.12
Shader "ryoo/RyooSpecularzero" 

{ 

	Properties 
	{
	
		_DiffuseTex ("Texture", 2D) = "white" {} 
		_Color ("Color", Color) = (1,0,0,1) 
		_Ambient ("Ambient", Range (0, 1)) = 0.25 
		_SpecColor ("Specular Material Color", Color) = (1,1,1,1) // 스페큘러 컬러
		_Shininess ( "Shininess", Float) = 10 // 스페큘러 강도
	}

	SubShader
	{

		Tags { "LightMode" = "ForwardBase" } 
		LOD 100

		Pass
		{

			CGPROGRAM 
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc" 
			#include "UnityLightingCommon.cginc" 

			struct appdata 
			{
				float4 vertex : POSITION; 
				float3 normal : NORMAL;
				float2 uv : TEXCOORD0; 
			}; 

			struct v2f // v2f struct(구조체)에 변수를 추가하고, v2f를 통해 프레그먼트 셰이더에 전달
			{
				float2 uv : TEXCOORD0; 
				float4 vertexClip : SV_POSITION; 
				float4 vertexWorld : TEXCOORD2; // 프레그먼트 셰이더에서 광원 방향 벡터 계산
				float3 worldNormal : TEXCOORD1; 
			}; 

			sampler2D _DiffuseTex; 
			float4 _DiffuseTex_ST; 
			float4 _Color; 
			float _Ambient; 
			float _Shininess; 
			
			v2f vert (appdata v) //정점 셰이더 부분
			{
				v2f o;
				o.vertexClip = UnityObjectToClipPos(v.vertex); 
				o.vertexWorld = mul(unity_ObjectToWorld, v.vertex); 
				o.uv = TRANSFORM_TEX(v.uv, _DiffuseTex); //텍스쳐 영역
				float3 worldNormal = UnityObjectToWorldNormal(v.normal); 
				o.worldNormal = worldNormal;
				return o; 
			} 

			float4 frag (v2f i) : SV_Target //프레그먼트 셰이더 부분
			{
				//정규화된 월드 공간의 노멀 벡터
				float3 normalDirection = normalize( i.worldNormal); 
				
				// 정규화된 뷰 방향 벡터
				float3 viewDirection = normalize(UnityWorldSpaceViewDir(i. vertexWorld)); 
				
				// 정규화된 광원 방향 벡터
				float3 lightDirection = normalize(UnityWorldSpaceLightDir(i. vertexWorld));
                
				//텍스쳐 영역
				float4 tex =tex2D(_DiffuseTex, i.uv); 
				
				// 디퓨즈(람버트) 구현
				float nl = max(_Ambient, dot(normalDirection, lightDirection));
				float4 diffuseTerm = nl * _Color * tex * _LightColor0; 
	
				//스페큘러(퐁) 구현
				float3 reflectionDirection = reflect(-lightDirection, normalDirection); 
				float3 specularDot = max(0.0, dot(viewDirection, reflectionDirection)); 
				float3 specular = pow(specularDot, _Shininess);
				float4 specularTerm = float4( specular, 1) * _SpecColor * _LightColor0; 
				
	
				float4 finalColor = diffuseTerm + specularTerm;
				return finalColor; 
			} 
			ENDCG
		}


	}

}

참고서적: 유니티 물리 기반 셰이더 개발 

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

Unity Shader에 대한 이해  (0) 2021.01.01
Specular 다 광원지원  (0) 2020.12.21
diffuseShader  (0) 2020.12.15
좌표공간 변환  (0) 2020.12.12
내적(dot)  (0) 2020.12.12
Shader "ryoo/DiffuseShader1"
{
    Properties
    {
        _DiffuseTex ("Texture", 2D) = "white" {}
        _Color("Color",Color) = (1,0,0,1)
        _Ambient("Ambient",Range(0,1)) = 0.25
    }
    SubShader
    {
        Tags { "LightMode"="ForwardBase" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            
            #include "UnityCG.cginc"
            #include "UnityLightingCommon.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
                float4 worldNormal : TEXCOORD1;
            };

            sampler2D _DiffuseTex;
            float4 _DiffuseTex_ST;
            fixed4 _Color;
            float _Ambient;
            

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _DiffuseTex);
                float3 worldNormal = UnityObjectToWorldNormal(v.normal);
                //o. worldNormal = worldNormal;
                
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float3 normalDirection = normalize(i.worldNormal);
                
                float4 tex = tex2D(_DiffuseTex, i.uv);
                
                float nl = max(_Ambient, dot(normalDirection, _WorldSpaceLightPos0.xyz));
                float4 diffuseTerm = nl * _Color * tex *_LightColor0;
                
                return diffuseTerm;
            }
            ENDCG
        }
    }
}

참고서적: 유니티 물리 기반 셰이더 개발 

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

Specular 다 광원지원  (0) 2020.12.21
SpecularShader  (0) 2020.12.19
좌표공간 변환  (0) 2020.12.12
내적(dot)  (0) 2020.12.12
UnlitShader  (0) 2020.12.11

float3 UnityObjectToWorldDir(in float3 dir) 객체 공간의 방향을 취해 월드 공간에서의 방향 값으로 변환해준다.

 

float3 UnityObjectToWorldNormal(in float3 norm) 객체 공간이 노멀을 취해 월드 공간에서의 노멀 값으로 변환해준다.

빛을 계산하는데 유용하다.

 

float3 UnityWorldSpaceViewDir(in float3 worldPos) 월드 공간에서의 정점 위치를 취해 월드 공간에서의 뷰의 방향을 반환한다. 빛을 계산하는데 유용하다.

 

float3 UnityWorldSpaceLightDir(in float3 worldPos) 월드 공간에서의 정점 위치를 취해 공간에서의 빛의 방향을 반환한다. 빛을 계산하는데 유용하다.

 

unity_ObjectToWorld 객체 공간에서 월드공간으로 변환하는 행렬

unity_WorldToObject 위의 행열의 역행렬, 월드공간에서 객체 공간으로 변환하는 행렬

샘플) float4 vertexWorld = mul(unity_ObjectToWorld, v.vertex);

 

 

unity_WorldToCamer 월드 공간에서 카메라 공간으로 변환한다.

unity_CameraToWorld 위행열의 역행렬, 카메라 공간에서 월드 공간으로 변환한다.

float3 UnityViewToClipPos(in float3 pos) 뷰 공간에서 절단 공간으로 위치를 변환한다.

 

float4 UnityWorldToClipPos(in float pos) 위치를 월드 공간에서 절단 공간으로 변환

float4 UnityViewToClipPos(in float pos) 위치를 뷰 공간에서 절단 공간으로 변환

float4 UnityObjectToClipPos(in float pos) 정점 위치를 객체 공간에서 절단 공간으로 변환

 

 

밝기를 계산하는 방법

float brightness = cos(angle_of_incidence) // 입사각으로 구하는 밝기
float brightness = dot(normal,lightDir) // 노멀 벡터와 빛의 방향 벡터로 계산한 밝기
float3 pixelColor = brightness*lightColor*surfaceColor // 입사각으로 구하는 밝기

 

 

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

SpecularShader  (0) 2020.12.19
diffuseShader  (0) 2020.12.15
내적(dot)  (0) 2020.12.12
UnlitShader  (0) 2020.12.11
벡터(Vector)와 스칼라(Scalar)  (0) 2020.12.10