Unity 3에서 Unity는 서피스 셰이더라는 셰이더 작성 시스템을 추가했습니다. 서피스 셰이더 시스템은 셰이더에서 조명 처리를 직접하지 않도록 최대한 추상화 하여, 개발자는 단순히 Albedo, Emission, Alpha등이 어떻게 보이면 될지 처리하면 됩니다. 그러면 서피스 셰이더 시스템은 전체 셰이더를 생성하여 처리합니다. 이것은 Unity 멋진 추상화입니다.
VR의 다양한 조명 시스템, 포워드 및 디퍼드 렌더링, 물리적 기반 렌더링, 다양한 라이트매핑 및 전역 조명 엔진 등 셰이더 작성은 몇 년 전 Unity에서 최신 버전에서 로드되고 작성자의 변경 없이 모든 새로운 기능이 작동합니다. 그러나 Unity가 스크립터블 렌더 파이프라인을 도입하면서 서피스 셰이더 시스템은 사용되지 않게 되었습니다. 이제 모든 팀이 각자의 방향으로 직접 작성해야 합니다. 단순한 셰이더 작성은 수십 줄의 코드를 작성하는 것에서 몇 천 줄로 늘어났습니다. 또한, Unity에서 변경 사항이 있을 때마다 셰이더가 손상되어 셰이더의 많은 부분을 다시 작성해야 합니다. 또한 고화질용으로 작성된 셰이더 렌더 파이프라인(HDRP)은 유니버설 렌더로 작성된 파이프라인과 호환되지 않습니다. URP 또는 그 반대이면 이전 파이프라인용으로 작성된 모든 셰이더는 호환됩니다. 이전에는 셰이더를 작성하기에 좋은 장소였지만, 이제는 빠르게 셰이더 작성하기가 어려워진 상황입니다. 수년간 커뮤니티에서 논쟁이 있었지만, Unity는 이 문제를 해결하기 위한 어떤 조치도 취하지 않았습니다. 또한 에셋 스토어 작성자의 경우 이제 사용자가 에셋을 설치하고 작동하도록 하는 것이 불가능합니다. 올바른 Unity 버전 및 SRP를 사용하려면 사용자가 추출해야 하는 zip 파일로 모든 자산의 여러 복사본을 배송해야 합니다. Unity 버전이 증가함에 따라 Unity 2019용 HDRP로 작성된 셰이더는 2020년 HDRP용으로 작성된 셰이더와 호환되지 않으므로 유지해야 하는 복사본의 수가 늘어납니다. 이 문제를 해결하기 위해 Better Shader가 만들어졌으며, 이것은 좋은 해결책입니다.
Better Shaders는 Lit 및 테셀레이션된 셰이더에서 쌓을 수 있는 효과까지 제공합니다. BetterShaders/Samples/Basic에서 찾을 수 있습니다.
기본을 자랑하는 다양한 셰이더들이 있습니다. BetterShaders/Samples/Stackable 폴더 아래에 효과를 적용하는 데 사용할 수 있는 쌓을 수 있는 셰이더 모음이 있습니다. 기존 쉐이더를 대체할 수 있습니다.
Better Shaders에는 시작할 때 사용할 수 있는 일련의 템플릿이 있습니다. 새로운 셰이더를 생성하려면 프로젝트의 오른쪽 클릭 만들기 메뉴에서 액세스할 수 있습니다. Create/Shader/BetterShaders에서 Documented 쉐이더는 각 기능에 대한 설명과 함께 모든 주요 블록과 코드가 포함된 템플릿을 생성합니다.
셰이더의 주요 블록은 모두 START_ 및 END_ 블록 표기법으로 정의되며 모든 블록은 선택 사항입니다.
다음 코드는 Better Shader의 코드 작성의 예제 옵션들 설명입니다.
//안녕하세요, 이것은 많은 문서화가 필요한 셰이더입니다.
//그러나 많은 기능을 수행하지는 않고, 단순히 보여주기만 합니다.
BEGIN_OPTIONS
// ShaderName "Path/ShaderName" // 기본값은 파일 이름을 사용하지만 셰이더의 경로/이름을 지정하려면
// Tessellation "Distance" // automatic tessellation, distance, edge, phong
// Alpha "Blend" // Blend, PreMultiply, Add
// Fallback "Diffuse" // fallback shader
// CustomEditor "MyCustomEditor" // Custom Editor
// Tags { "RenderType" = "Opaque" "Queue" = "Geometry+100" } // Tags는 항상 Standard 파이프라인 스타일로 작성됩니다.
// Workflow "Metallic" // Metallic, Specular, or Unlit
// StripV2F { vertexColor texcoord2 } // 이 데이터를 Vertex 단계에서 Fragment 단계로 전달하지 마십시오.
// Stackable "True" // 만약 false이면, 이 쉐이더의 한 복사본만 서브쉐이더 블록을 통해 포함됩니다. include guard와 비슷합니다.
// VertexColorModifier "_centroid" // v2f interpolator에 수정자 추가
// ExtraV2F3Require "_MyDefine" // define이 설정되어 있을 때만 extraV2F3 레지스터를 생성합니다.
// Pipeline "HDRP" // Stacked 일 경우, 이 기능은 해당 파이프라인에만 포함됩니다. Standard, URP, HDRP가 옵션입니다.
// DisableGBufferPass "True" // disable gbuffer pass
// DisableShadowPass "True" // disable shadow pass
END_OPTIONS
BEGIN_PASS("All")
// Cull Front // add various pass semantics to all passes, or individual passes with pass blocks
END_PASS
// "Relative/Path/File.surfshader" // merge all blocks into this shader. Like a better include.
BEGIN_SUBSHADERS
END_SUBSHADERS
// Put any properties you have between the begin/end property blocks
BEGIN_PROPERTIES
_Color ("Main Color", Color) = (0, 1, 0, 1)
END_PROPERTIES
// Any variables you want to have in the per material CBuffer go here.
BEGIN_CBUFFER
half4 _Color;
END_CBUFFER
//정의 블록을 사용하여 코드 앞에 포함, 정의 등을 삽입할 수 있습니다.
//하위 셰이더를 작성하는 경우 기본 셰이더에 설정해야 하는 모든 정의가 여기에 정의됩니다.
BEGIN_DEFINES
END_DEFINES
// All code goes here
BEGIN_CODE
//(선택사항) 만약 처리되기 전에 어떤 정점 데이터를 수정하려면,
//ModifyVertex 함수에 넣으세요. 해당 구조체는:
struct VertexData
{
float4 vertex
float3 normal
float4 tangent
float4 texcoord0
float4 texcoord1
float4 texcoord2
float4 texcoord3
float4 vertexColor
}
// ExtraV2F 구조체는 사용자 정의 데이터를 할당하고,
//이를 픽셀 셰이더로 전달할 수 있습니다.
float4 extraV2F0;
float4 extraV2F1;
etc..
float4 extraV2F7;
//HDRP에서 모션 벡터 패스는 이전 프레임에서 객체의 정점 위치를 재계산합니다.
//따라서 _Time을 사용하여 정점을 애니메이션화하는 경우 올바른 모션 벡터를 위해
//현재가 아닌 마지막 프레임이 될 수 있으므로 이를 대신 사용하십시오.
float4 time;
//(optional)vertex 수정
void ModifyVertex(inout VertexData v, inout ExtraV2F d)
{
}
//(선택 사항) 테셀레이션 및 변위를 사용하는 경우
//여기에서 테셀레이션 거리 및 세분화를 반환할 수 있습니다.
float3 GetTessDistanceFactors()
{
float minDistance = 0;
float maxDistance = 35;
float subDiv = 12;
return float3(minDistance, maxDistance, subDiv);
}
//(필수) 조명 방정식에 대한 입력을 채우는 서피스 함수를 작성합니다.
//서피스에는 다음이 포함됩니다.
Surface
{
half3 Albedo;
half3 Normal;
half Smoothness;
half Metallic;
half Occlusion;
half3 Emission;
half Height;
half Alpha;
float outputDepth; // 작성된 경우 SV_Depth 시맨틱이 사용됩니다. ShaderData.clipPos.z는 사용되지 않는 값입니다.
// HDRP 전용, 특정 플래그 정의 등을 사용하도록 설정해야 할 수 있음
half SpecularOcclusion;
half SubsurfaceMask;
half Thickness;
half CoatMask;
half CoatSmoothness;
half Anisotropy;
half IridescenceMask;
half IridescenceThickness;
int DiffusionProfileHash;
// _ENABLE_GEOMETRIC_SPECULAR_AA를 정의해야 합니다.
float SpecularAAThreshold;
float SpecularAAScreenSpaceVariance;
}
must define (_REFRACTION_PLANE || _REFRACTION_SPHERE || _REFRACTION_THIN)
float ior;
float3 transmittanceColor;
float atDistance;
float transmittanceMask;
requires _OVERRIDE_BAKEDGI가 정의되지만 모든 파이프라인에서 매핑됩니다.
float3 DiffuseGI;
float3 BackDiffuseGI;
float3 SpecularGI;
//SurfaceData 함수에는 미리 계산된 일반적인 데이터가 포함되어 있습니다.
//시스템은 구조에서 사용하지 않는 요소를 자동으로
//제거하므로 사용하지 않는 항목에 대한 비용이 없습니다.
ShaderData
{
float3 localSpacePosition;
float3 localSpaceNormal;
float3 localSpaceTangent;
float3 worldSpacePosition;
float3 worldSpaceNormal;
float3 worldSpaceTangent;
float tangentSign; // tangent.w
float3 worldSpaceViewDir;
float3 tangentSpaceViewDir;
bool isFrontFace; // 사용되는 경우 SV_IsFrontFace 시맨틱이 셰이더에서 사용됩니다.
float4 texcoord0;
float4 texcoord1;
float4 texcoord2;
float4 texcoord3;
float2 screenUV; // 화면 좌표에 대한 0-1 UV
float4 screenPos;
float4 vertexColor;
float3x3 TBNMatrix; // 세계와 접선 및 세계 행렬에 접선. TransformWorldToTangent(ShaderData, normal) 및 그 반대도 사용할 수 있습니다.
float4 extraV2F0; // v2f 버스를 통한 추가 데이터
etc..
float4 extraV2F7;
float4 clipPos; // 클립 위치, SV_POSITION
}
void SurfaceFunction(inout Surface o, ShaderData d)
{
o.Albedo = _Color.rgb;
o.Alpha = _Color.a;
}
//(선택 사항) 조명 후 셰이더 출력의 최종 색상 수정
void FinalColorForward(Surface o, ShaderData d, inout half4 color)
{
}
//(선택 사항) GBuffer 데이터의 최종 출력 수정
void FinalGBufferStandard(Surface o, ShaderData d,
inout half4 GBuffer0, inout half4 GBuffer1, inout half4 GBuffer2, inout half4 emission,
inout half4 shadowMask)
{
}
END_CODE
옵션 블록을 사용하면 Better Shaders 시스템의 컴파일 시간 기능을 설정할 수 있습니다. 예를 들어 테셀레이션, 알파 등을 켤 수 있습니다. 옵션에 설명되어 있습니다. 아래의 블록 옵션 섹션 또는 메뉴에서 문서화된 셰이더를 생성합니다.