“Unlit/URP_UnlitBase“
Shader "URP/Unlit/URP_UnlitBase" { Properties { [MainTexture] _BaseMap("Texture", 2D) = "white" {} [MainColor] _BaseColor("Color", Color) = (1, 1, 1, 1) } SubShader { Tags { "RenderType" = "Opaque" "Queue" = "Geometry" "RenderPipeline" = "UniversalPipeline" } LOD 100 Pass { Name "URP_UnlitBase" Tags {"LightMode" = "SRPDefaultUnlit"} // 이 Pass는 Unlit(조명이 없는) 모드로 작동함을 선언 HLSLPROGRAM #pragma target 4.5 // Shader 모델 4.5를 대상 // vertex shader 선언 (vert 함수) // vert라는 이름의 함수를 vertex shader로 사용 선언 // vert는 입력으로 Attributes 구조체를 받고, 처리된 결과를 반환 #pragma vertex vert // vertex shader 선언 (vert 함수) #pragma fragment frag // fragment shader 선언 (frag 함수) #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" // Constant Buffer // Unity의 각 Material 상수를 정의 CBUFFER_START(UnityPerMaterial) float4 _BaseMap_ST; // TEXTURE UV 좌표 변환에 사용되는 정보 (offset, tiling) float4 _BaseColor; // 설정 색상 CBUFFER_END TEXTURE2D(_BaseMap); // TEXTURE2D 선언 SAMPLER(sampler_BaseMap); // SAMPLER 선언 // vertex shader의 입력 구조체 struct Attributes { float4 positionOS : POSITION; // 모델 공간에서의 정점 위치 (float3, float4) float3 normalOS : NORMAL; // 모델 공간에서의 정점 법선 (float3) float2 uv : TEXCOORD0; // 첫 번째 UV 텍스처 좌표 (float2, float3, float4) float2 uv2 : TEXCOORD1; // 두 번째 UV 텍스처 좌표 (float2, float3, float4) float2 uv3 : TEXCOORD2; // 세 번째 UV 텍스처 좌표 (float2, float3, float4) float2 uv4 : TEXCOORD3; // 넷 번째 UV 텍스처 좌표 (float2, float3, float4) float4 tangentOS : TANGENT; // 모델 공간에서의 접선 벡터 (normal mapping에 사용) float4 color : COLOR; // 정점 별 색상 (float4) int4 blendIndices : BLENDINDICES; // 스킨 매싱에서 뼈대 인덱스 }; // Varyings 구조체 정의 // 출력 구조체로, fragment Shader에서 사용할 데이터(예: 변환된 위치, UV 좌표 등)를 포함 struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float4 color : COLOR; }; // vertex shader가 Attributes를 사용 Varyings vert(Attributes input) { // 출력 변수를 정의 Varyings output = (Varyings)0; // Varyings 초기화, 모든 필드에 기본값을 할당 // 모델 공간에서의 정점 위치를 float4 형태로 저장 float4 positionOS = input.positionOS; // 모델 공간에서 월드 공간으로의 변환을 수행 float3 positionWS = TransformObjectToWorld(positionOS.xyz); // 월드 공간에서 뷰 공간으로의 변환을 수행 float3 positionVS = TransformWorldToView(positionWS); // 월드 공간에서 클립 공간으로의 변환을 수행 // 클립 공간 : 렌더링 파이프라인에서 최종적으로 화면에 출력될 좌표계 float4 positionCS = TransformWorldToHClip(positionWS); // 변환된 클립 공간 위치를 출력 구조체 output에 저장 output.positionCS = positionCS; // 입력으로 받은 UV 좌표를 출력 구조체 output에 저장 output.uv = input.uv; output.color = input.color; return output; } // 프래그먼트 셰이더(fragment shader) // 픽셀 단위로 호출되며, 각 픽셀의 최종 색상을 계산해 화면에 출력 // 기본적으로 입력된 UV 좌표를 이용해 텍스처 색상을 샘플링하고, // 최종적으로 머티리얼의 색상과 결합하여 픽셀의 색상을 반환하는 역할 float4 frag(Varyings input) : SV_Target { // UV 좌표 변환을 위한 계산 // input.uv.xy는 입력된 UV 좌표이며, _BaseMap_ST.xy는 텍스처 타일링(scale)을 나타내고, // _BaseMap_ST.zw는 오프셋을 나타냅니다. // 따라서, 기본 UV 좌표에 타일링 및 오프셋을 적용하여 최종적으로 텍스처 좌표를 결정합니다. float2 baseMapUV = input.uv.xy * _BaseMap_ST.xy + _BaseMap_ST.zw; // SAMPLE_TEXTURE2D 함수를 사용하여 텍스처를 샘플링합니다. // _BaseMap은 텍스처 리소스, sampler_BaseMap은 해당 텍스처를 샘플링하는 샘플러입니다. // baseMapUV는 변환된 UV 좌표입니다. // 이 과정에서 지정된 텍스처 좌표를 기준으로 텍스처 색상을 가져옵니다. float4 texColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, baseMapUV); // 텍스처 색상과 기본 색상을 곱하여 최종 색상을 계산합니다. // _BaseColor는 머티리얼에서 설정된 색상이며, 이를 텍스처 샘플링 결과와 곱하여 결과적으로 // 텍스처와 색상이 결합된 최종 색상을 생성합니다. float4 finalColor = texColor * _BaseColor; // 최종 계산된 색상을 출력합니다. SV_Target은 이 값이 픽셀 셰이더의 출력으로 화면에 렌더링된다는 것을 의미합니다. return finalColor; } ENDHLSL } } }
참고
“Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl“
#ifndef UNIVERSAL_PIPELINE_CORE_INCLUDED #define UNIVERSAL_PIPELINE_CORE_INCLUDED // 현재 URP에서는 가상 텍스처링(Virtual Texturing)을 지원하지 않으므로, // 가상 텍스처링을 사용하는 셰이더가 일반 텍스처 샘플링으로 대체되도록 강제합니다. #define FORCE_VIRTUAL_TEXTURING_OFF 1 // 포워드 플러스(Forward+) 렌더링이 활성화된 경우와 그렇지 않은 경우에 따라 // 추가 조명을 지원하는지 여부와 포워드 플러스 사용 여부를 설정합니다. #if defined(_FORWARD_PLUS) #define _ADDITIONAL_LIGHTS 1 #undef _ADDITIONAL_LIGHTS_VERTEX #define USE_FORWARD_PLUS 1 #else #define USE_FORWARD_PLUS 0 #endif // URP와 관련된 공통 헤더 파일들을 포함합니다. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Packing.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl" // Z-버퍼의 방향과 관련된 매크로 정의 #if UNITY_REVERSED_Z // Z-버퍼가 반전된 경우에 대한 처리입니다. // GL과 D3D의 경우 Z-값의 클립 범위를 조정합니다. #if (defined(SHADER_API_GLCORE) && !defined(SHADER_API_SWITCH)) || defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) // GL에서는 Z-클립 범위가 [near, -far]이므로, 이를 [0, far]로 변환합니다. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max((coord - _ProjectionParams.y)/(-_ProjectionParams.z-_ProjectionParams.y)*_ProjectionParams.z, 0) #else // D3D에서는 Z-클립 범위가 [near, 0]이므로, 이를 [0, far]로 변환합니다. // max를 사용하는 것은 경사 행렬의 경우 근접 평면이 올바르지 않거나 의미가 없을 때를 대비합니다. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(((1.0-(coord)/_ProjectionParams.y)*_ProjectionParams.z),0) #endif #elif UNITY_UV_STARTS_AT_TOP // D3D에서는 Z-클립 범위가 [0, far]이므로, 추가적인 변환이 필요하지 않습니다. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord) #else // OpenGL에서는 Z-클립 범위가 [-near, far]이므로, 이를 [0, far]로 변환합니다. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(((coord + _ProjectionParams.y)/(_ProjectionParams.z+_ProjectionParams.y))*_ProjectionParams.z, 0) #endif // 스테레오 렌더링 관련 매크로 정의 #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) // 스테레오 렌더링이 활성화된 경우, 텍스처를 배열로 처리합니다. #define SLICE_ARRAY_INDEX unity_StereoEyeIndex // 스테레오 렌더링 시 사용하는 텍스처 배열 매크로 정의 #define TEXTURE2D_X(textureName) TEXTURE2D_ARRAY(textureName) #define TEXTURE2D_X_PARAM(textureName, samplerName) TEXTURE2D_ARRAY_PARAM(textureName, samplerName) #define TEXTURE2D_X_ARGS(textureName, samplerName) TEXTURE2D_ARRAY_ARGS(textureName, samplerName) #define TEXTURE2D_X_HALF(textureName) TEXTURE2D_ARRAY_HALF(textureName) #define TEXTURE2D_X_FLOAT(textureName) TEXTURE2D_ARRAY_FLOAT(textureName) #define LOAD_TEXTURE2D_X(textureName, unCoord2) LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, SLICE_ARRAY_INDEX) #define LOAD_TEXTURE2D_X_LOD(textureName, unCoord2, lod) LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, SLICE_ARRAY_INDEX, lod) #define SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2) SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, SLICE_ARRAY_INDEX) #define SAMPLE_TEXTURE2D_X_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, SLICE_ARRAY_INDEX, lod) #define GATHER_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, SLICE_ARRAY_INDEX) #define GATHER_RED_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_RED_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX)) #define GATHER_GREEN_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_GREEN_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX)) #define GATHER_BLUE_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_BLUE_TEXTURE2D(textureName, samplerName, float3(coord2, SLICE_ARRAY_INDEX)) #else // 스테레오 렌더링이 비활성화된 경우, 일반적인 2D 텍스처 샘플링 매크로 정의 #define SLICE_ARRAY_INDEX 0 #define TEXTURE2D_X(textureName) TEXTURE2D(textureName) #define TEXTURE2D_X_PARAM(textureName, samplerName) TEXTURE2D_PARAM(textureName, samplerName) #define TEXTURE2D_X_ARGS(textureName, samplerName) TEXTURE2D_ARGS(textureName, samplerName) #define TEXTURE2D_X_HALF(textureName) TEXTURE2D_HALF(textureName) #define TEXTURE2D_X_FLOAT(textureName) TEXTURE2D_FLOAT(textureName) #define LOAD_TEXTURE2D_X(textureName, unCoord2) LOAD_TEXTURE2D(textureName, unCoord2) #define LOAD_TEXTURE2D_X_LOD(textureName, unCoord2, lod) LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) #define SAMPLE_TEXTURE2D_X(textureName, samplerName, coord2) SAMPLE_TEXTURE2D(textureName, samplerName, coord2) #define SAMPLE_TEXTURE2D_X_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) #define GATHER_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_TEXTURE2D(textureName, samplerName, coord2) #define GATHER_RED_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) #define GATHER_GREEN_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) #define GATHER_BLUE_TEXTURE2D_X(textureName, samplerName, coord2) GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) #endif /// /// 텍스처 샘플링 매크로 오버라이드: 스케일링 지원 /// /// mip bias가 지원되는 플랫폼에서는 모든 2D 텍스처 샘플링 작업을 글로벌 mip bias 기능을 지원하도록 재정의합니다. /// 이 기능은 이미지 스케일링이 활성화된 경우 렌더링 품질을 향상시키기 위해 사용됩니다. /// 최종 이미지 해상도에 따라 mip 레벨을 선택할 수 있도록 mip lod 계산에 bias 값을 추가합니다. #ifdef PLATFORM_SAMPLE_TEXTURE2D_BIAS #ifdef SAMPLE_TEXTURE2D #undef SAMPLE_TEXTURE2D #define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) \ PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, _GlobalMipBias.x) #endif #ifdef SAMPLE_TEXTURE2D_BIAS #undef SAMPLE_TEXTURE2D_BIAS #define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) \ PLATFORM_SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, (bias + _GlobalMipBias.x)) #endif #endif #ifdef PLATFORM_SAMPLE_TEXTURE2D_GRAD #ifdef SAMPLE_TEXTURE2D_GRAD #undef SAMPLE_TEXTURE2D_GRAD #define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) \ PLATFORM_SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, (dpdx * _GlobalMipBias.y), (dpdy * _GlobalMipBias.y)) #endif #endif #ifdef PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS #ifdef SAMPLE_TEXTURE2D_ARRAY #undef SAMPLE_TEXTURE2D_ARRAY #define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) \ PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, _GlobalMipBias.x) #endif #ifdef SAMPLE_TEXTURE2D_ARRAY_BIAS #undef SAMPLE_TEXTURE2D_ARRAY_BIAS #define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) \ PLATFORM_SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, (bias + _GlobalMipBias.x)) #endif #endif #ifdef PLATFORM_SAMPLE_TEXTURECUBE_BIAS #ifdef SAMPLE_TEXTURECUBE #undef SAMPLE_TEXTURECUBE #define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) \ PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, _GlobalMipBias.x) #endif #ifdef SAMPLE_TEXTURECUBE_BIAS #undef SAMPLE_TEXTURECUBE_BIAS #define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) \ PLATFORM_SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, (bias + _GlobalMipBias.x)) #endif #endif #ifdef PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS #ifdef SAMPLE_TEXTURECUBE_ARRAY #undef SAMPLE_TEXTURECUBE_ARRAY #define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index)\ PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, _GlobalMipBias.x) #endif #ifdef SAMPLE_TEXTURECUBE_ARRAY_BIAS #undef SAMPLE_TEXTURECUBE_ARRAY_BIAS #define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)\ PLATFORM_SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, (bias + _GlobalMipBias.x)) #endif #endif // 글로벌 mip bias 곱셈기 #define VT_GLOBAL_MIP_BIAS_MULTIPLIER (_GlobalMipBias.y) // 구조체 정의 // 정점의 위치 정보를 담는 구조체입니다. struct VertexPositionInputs { float3 positionWS; // 월드 공간에서의 위치 float3 positionVS; // 뷰 공간에서의 위치 float4 positionCS; // 동차 클립 공간에서의 위치 float4 positionNDC;// 동차 정규화된 장치 좌표 }; // 정점의 법선 정보를 담는 구조체입니다. struct VertexNormalInputs { real3 tangentWS; // 월드 공간에서의 탄젠트 벡터 real3 bitangentWS; // 월드 공간에서의 비탄젠트 벡터 float3 normalWS; // 월드 공간에서의 법선 벡터 } // 추가적인 셰이더 변수와 함수 정의를 포함한 헤더 파일들 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderVariablesFunctions.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Deprecated.hlsl" #endif
“Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl”
#ifndef UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED #define UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl" // 주의: '_WorldSpaceCameraPos'는 Unity의 레거시 코드에 의해 설정됩니다. float3 GetPrimaryCameraPosition() { #if (SHADEROPTIONS_CAMERA_RELATIVE_RENDERING != 0) // 카메라 상대 렌더링이 활성화된 경우, 카메라 위치는 (0, 0, 0)으로 간주합니다. return float3(0, 0, 0); #else // 그렇지 않은 경우, 실제 월드 좌표계를 기준으로 카메라 위치를 반환합니다. return _WorldSpaceCameraPos; #endif } // 예: 주 카메라 또는 그림자를 캐스팅하는 빛의 위치일 수 있습니다. float3 GetCurrentViewPosition() { #if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS) // 그림자 패스가 아닌 경우 주 카메라 위치를 반환합니다. return GetPrimaryCameraPosition(); #else // 일반적인 해결책입니다. // 그러나 주 카메라의 경우 '_WorldSpaceCameraPos'를 사용하는 것이 더 좋습니다. 이는 캐시 일관성에도 유리하고, // 카메라 상대 렌더링이 활성화된 경우 위치를 0으로 설정할 수 있기 때문입니다. return UNITY_MATRIX_I_V._14_24_34; #endif } // 현재 뷰의 월드 공간에서의 전방(중앙) 방향을 반환합니다. float3 GetViewForwardDir() { float4x4 viewMat = GetWorldToViewMatrix(); return -viewMat[2].xyz; } // 현재 뷰가 원근 투영을 수행하는 경우 'true'를 반환합니다. bool IsPerspectiveProjection() { #if defined(SHADERPASS) && (SHADERPASS != SHADERPASS_SHADOWS) // 그림자 패스가 아닌 경우 원근 투영 여부를 검사합니다. return (unity_OrthoParams.w == 0); #else // TODO: 그림자 패스에서 'unity_OrthoParams'를 설정해야 합니다. return UNITY_MATRIX_P[3][3] == 0; #endif } // 월드 공간에서의 뷰 방향을 정규화하여 계산합니다 (뷰어를 향해 있음). float3 GetWorldSpaceNormalizeViewDir(float3 positionWS) { if (IsPerspectiveProjection()) { // 원근 투영인 경우 float3 V = GetCurrentViewPosition() - positionWS; return normalize(V); } else { // 정사영인 경우 return -GetViewForwardDir(); } } // UNITY_MATRIX_V는 Z 축이 뷰어를 향하는 오른손 좌표계를 정의합니다. // 이 함수는 Z 축의 방향을 반전하여(앞쪽을 향하게) 뷰 공간 좌표계를 왼손 좌표계로 만듭니다. void GetLeftHandedViewSpaceMatrices(out float4x4 viewMatrix, out float4x4 projMatrix) { viewMatrix = UNITY_MATRIX_V; viewMatrix._31_32_33_34 = -viewMatrix._31_32_33_34; projMatrix = UNITY_MATRIX_P; projMatrix._13_23_33_43 = -projMatrix._13_23_33_43; } // Z 클리핑과 관련된 부분으로, 뒤집어진 Z 버퍼를 사용하는 경우에 대한 조건부 매크로 정의 #if UNITY_REVERSED_Z #if (defined(SHADER_API_GLCORE) && !defined(SHADER_API_SWITCH)) || defined(SHADER_API_GLES) || defined(SHADER_API_GLES3) // 뒤집어진 Z를 사용하는 OpenGL에서는 클리핑 범위가 [near, -far]입니다. // 성능을 위해 리매핑하지 않고 그대로 사용합니다 (범위가 충분히 가깝기 때문입니다). #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(-(coord), 0) #else // 뒤집어진 Z를 사용하는 Direct3D에서는 클리핑 범위가 [near, 0]입니다. // [0, far]로 리매핑합니다. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(((1.0-(coord)/_ProjectionParams.y)*_ProjectionParams.z),0) #endif #elif UNITY_UV_STARTS_AT_TOP // 뒤집어진 Z를 사용하지 않는 Direct3D에서는 클리핑 범위가 [0, far]이므로 아무것도 할 필요가 없습니다. #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord) #else // OpenGL에서는 클리핑 범위가 [-near, far]이므로 성능을 위해 리매핑하지 않고 그대로 사용합니다 (범위가 충분히 가깝기 때문입니다). #define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord) #endif #endif // UNITY_SHADER_VARIABLES_FUNCTIONS_INCLUDED