# 4-4 [Rim Light]

Ricon·2024년 8월 13일

URP Shader Basic

목록 보기
17/17
post-thumbnail

Rim Light

// Shader 시작. 셰이더의 폴더와 이름을 여기서 결정합니다.
Shader "URPTraining/24_Rim Light"
{
	Properties
	{
		// Properties Block : 셰이더에서 사용할 변수를 선언하고 이를 material inspector에 노출시킵니다
		_RimPower("Rim Power", Range(0.01, 0.1)) = 0.1
		_RimInten("Rim Intensity", Range(0.01, 100)) = 1
		[HDR] _RimColor("Rim Color", Color) = (1, 1, 1, 1)
	}

	SubShader
	{
		Tags
		{
			//Render type과 Render Queue를 여기서 결정합니다.
			"RenderPipeline" = "UniversalPipeline"
			"RederType" = "Opaque"
			"Queue" = "Geometry"
		}
		Pass
		{
			Name "Universal Forward"
			Tags { "LightMode" = "UniversalForward"}

			HLSLPROGRAM
			#pragma prefer_hlslcc gles
			#pragma exclude_renderers d3d11_9x
			#pragma vertex vert
			#pragma fragment frag

			//cg shader는 .cginc를 hlsl shader는 .hlsl을 include하게 됩니다.
			#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"

			//vertex buffer에서 읽어올 정보를 선언합니다. 
			struct VertexInput
			{
				float4 vertex	: POSITION;
				float3 normal	: NORMAL;
			};

			//보간기를 통해 버텍스 셰이더에서 픽셀 셰이더로 전달할 정보를 선언합니다.
			struct VertexOutput
			{
				float4 vertex	: SV_POSITION;
				float3 normal	: NORMAL;
				float3 WorldSpaceviewDirection	: TEXCOORD0;
			};

			float _RimPower, _RimInten;
			half4 _RimColor;

			//버텍스 셰이더
			VertexOutput vert(VertexInput v)
			{
				VertexOutput o;
				o.vertex = TransformObjectToHClip(v.vertex.xyz);
				o.normal = TransformObjectToWorldNormal(v.normal);

				//지정된 객체 공간 정점 위치에서 카메라 방향으로 월드 공간 방향을 계산하고 정규화 함.
				// 월드 공간에서 카메라 좌표 - 월드 공간 버텍스 좌표
				o.WorldSpaceviewDirection = normalize(_WorldSpaceCameraPos.xyz - TransformObjectToWorld(v.vertex.xyz));

				return o;
			}
			
			//픽셀 셰이더
			half4 frag(VertexOutput i) : SV_TARGET
			{
				float3 light = _MainLightPosition.xyz;
				float4 color = float4(0.5, 0.5, 0.5, 1);

				half3 ambient = SampleSH(i.normal);
				//월드 카메라 벡터와 노멀을 내적해 방향에 대한 값을 구합니다. 바라보는 방향이 같으면 1(밝음), 90도면 0(어두움)이 됩니다.
				half face = saturate(dot(i.WorldSpaceviewDirection, i.normal));

				half3 rim = 1.0 - (pow(face, _RimPower));

				//emissive term
				color.rgb *= saturate(dot(i.normal, light)) * _MainLightColor.rgb + ambient;

				//emissive term
				color.rgb += rim * _RimInten * _RimColor;

				return color;
			}

			ENDHLSL
		}
	}
}

0개의 댓글