다음은 사용자 셰이더 코드를 사용하는 프로젝트를 Unity 4에서 Unity 5로 업그레이드할 때 주의해야 하는 참고 사항입니다.
셰이더는 더 이상 광원 강도의 2배수를 적용하지 않습니다. 그 대신 광원이 2배 밝기가 되도록 자동으로 업그레이드됩니다. 따라서 광원 릭의 일관성과 단순함이 개선됩니다. 예를 들어 흰색 디퓨즈 표면에 비추는 방향 광원에는 광원의 정확한 컬러가 표시됩니다. 업그레이드는 애니메이션에 영향을 주지 않으므로 애니메이션화된 광원 강도 값이 있는 경우 같은 외양을 얻으려면 애니메이션 커브나 스크립트 코드를 변경하고 2배 더 크게 만들어야 합니다.
자체 조명 기능을 정의하는 사용자 셰이더의 경우 * 2를 직접 제거해야 합니다.
// A common pattern in shader code that has this problem will look like this
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2);
// You need to fix the code so it looks more like this
c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten);
Unity 5에 내장된 조명 파이프라인은 경우에 따라 더 많은 텍스처 좌표 인터폴레이터 또는 수학 명령 수를 사용하여 비균일 메시 스케일, 인라이튼 실시간 전역 조명 등을 작동시킵니다. 기존 표면 셰이더 중 일부는 특히 셰이더 모델 2.0(기본)이 타겟인 경우 텍스처 좌표 또는 ALU 명령 제한에 도달할 수 있습니다. “#pragma target 3.0”을 추가하여 이 문제를 해결할 수 있습니다. 참고로 http://docs.unity.cn/Manual/SL-ShaderPrograms.html을 참조하십시오.
Unity 5.0에서는 더 이상 비균일 메시가 CPU에서 “미리 스케일”되지 않습니다. 따라서 버텍스 셰이더에서 노멀 및 탄젠트 벡터를 비정규화할 수 있습니다. 수동 조명 계산을 수행하는 경우 정규화해야 합니다. Unity의 표면 셰이더를 사용하는 경우 필요한 모든 코드가 자동으로 생성됩니다.
Unity 5.0은 내장된 안개가 Windows Phone 및 콘솔에서 작동하도록 하지만, 이렇게 하기 위해 안개 작업을 수행하는 방법을 조금 변경했습니다. 표면 셰이더와 고정 함수 셰이더의 경우, 추가로 수행할 작업은 없고 안개가 자동으로 추가됩니다. 표면 셰이더의 #pragma 라인에 “nofog”를 추가하여 안개를 지원하지 않도록 명시적으로 지정할 수 있습니다.
수동으로 작성되는 버텍스/프래그먼트 셰이더의 경우, 안개가 자동으로 발생하지 않습니다. #pragma multi_compile_fog와 안개 처리 매크로를 셰이더 코드에 추가해야 합니다. 이렇게 하는 방법은 예를 들어 Unlit-Normal과 같은 빌트인 셰이더 소스를 참조하십시오.
기본적으로 모든 불투명한 표면 셰이더는 이제 알파 채널에 1.0(“흰색”)을 출력합니다. 이렇게 되지 않게 하려면 “keepalpha” 옵션을 #pragma surface 라인에 사용해야 합니다.
모든 알파 블렌드 표면 셰이더는 이제 (s.Alpha 대신) 조명 함수를 통해 블렌드 인자로 계산된 알파 컴포넌트를 사용합니다. 커스텀 조명 함수를 사용하는 경우 “c.a = s.Alpha”와 같은 것을 끝부분에 추가할 수 있습니다.
Unity는 포워드 렌더루프의 머티리얼 인덱스를 기준으로 정렬하지 않습니다. 그러면 오브젝트 상태를 변경하지 않고도 더 많은 오브젝트를 렌더할 수 있으므로 성능이 향상됩니다. 하지만 머티리얼 인덱스를 정렬 방법으로 사용하는 콘텐츠가 더 이상 호환되지 않습니다. 4.x에서 머티리얼이 두 개 있는 메시는 항상 첫 번째 머티리얼을 먼저 렌더링하고 두 번째 머티리얼을 두 번째로 렌더링합니다. 하지만 Unity 5에서는 그러지 않고 씬을 렌더링하기 위한 상태 변경을 가장 많이 줄이는 순서에 따릅니다.
Unity 5.0에서는 다음 고정 함수 셰이더 기능에 대한 지원이 제거되었습니다.
상기 기능은 이제 작동하지 않고, 셰이더의 인스펙터에서 기능 사용에 대한 경고를 표시합니다. 프로그램 가능 버텍스+프래그먼트 셰이더를 대신 사용하여 영향을 받는 셰이더를 다시 작성해야 합니다. 이 셰이더는 현재 모든 플랫폼에서 지원되고, 고정 함수 셰이더를 사용하여 얻을 수 있는 장점이 전혀 없습니다.
프로젝트에 매우 오래된 프로젝터 또는 워터 셰이더 패키지가 있는 경우 해당 셰이더에서 이 기능을 사용 중일 수 있습니다. 패키지를 5.0 버전으로 업그레이드해야 합니다.
부분 고정 함수 셰이더와 부분 프로그램 가능 셰이더 혼용(예: 고정 함수 버텍스 조명과 픽셀 셰이더, 또는 버텍스 셰이더와 텍스처 결합)은 이제 지원되지 않고, 어차피 그 전부터 모바일, 콘솔 또는 DirectX 11에서 작동하지 않았습니다. 지원을 중단하기 위해 레거시/반사/버텍스 릿 셰이더가 이렇게 하지 않도록 동작을 변경해야 했습니다. 이에 대한 버텍스당 스페큘러 지원이 제거되었지만, 이제 여러 플랫폼에서 동일하게 동작한다는 장점이 있습니다.
대부분의 경우 전환은 보이지 않게 이루어집니다(codegen 버그가 감소하고 셰이더가 약간 빨라지는 결과로만 나타남). 하지만 HLSL 컴파일러는 구문에 대해 약간 더 엄격할 수 있습니다. 몇 가지 예는 다음과 같습니다.
“unity-Scale” 셰이더 프로퍼티가 제거되었습니다. 4.x에서 unity_Scale.w는 트랜스폼의 1/균일 스케일이었고, Unity 4.x는 스케일되지 않거나 균일하게 스케일된 모델만 렌더했습니다. 그 외의 스케일은 CPU에서 수행되었는데, 이 작업에는 리소스가 매우 많이 사용되고 메모리도 예기치 않게 많이 사용되었습니다.
Unity 5.0에서는 간단히 스케일이 균일하지 않은 매트릭스를 셰이더에 전달하여 이 모든 작업을 GPU에서 처리합니다. 따라서 unity-Scale은 전체 스케일을 나타낼 수 없기 때문에 제거되었습니다. “unity-Scale”이 사용된 대부분의 경우에는 월드 공간으로 먼저 변환하는 것이 좋습니다. 노멀을 변환하는 경우, 이제는 항상 변환된 노멀에서 정규화를 사용해야 합니다. 그러면 경우에 따라 버텍스 셰이더의 코드에 리드가 조금 더 많이 사용될 수 있습니다.
// Unity 4.x
float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal * unity_Scale.w);
// Becomes this in Unity 5.0
float3 norm = normalize(mul ((float3x3)UNITY_MATRIX_IT_MV, v.normal));
// Unity 4.x
temp.xyzw = v.vertex.xzxz * unity_Scale.xzxz * _WaveScale4 + _WaveOffset;
// Becomes this in Unity 5.0
float4 wpos = mul (_Object2World, v.vertex);
temp.xyzw = wpos.xzxz * _WaveScale4 + _WaveOffset;
포워드 렌더링으로 렌더링된 방향 광원 섀도우는 더 이상 “섀도우 컬렉터” 패스로 분리되지 않습니다. 이제는 카메라의 뎁스 텍스처를 토대로 스크린 공간 섀도우를 계산합니다(디퍼드 라이팅의 경우와 동일).
즉, 셰이더의 LightMode=ShadowCollector 패스는 아무런 용도로도 사용되지 않으므로 셰이더에서 제거해도 됩니다.
뎁스 텍스처 자체는 더 이상 셰이더 대체를 사용하여 생성되지 않고 ShadowCaster 셰이더 패스를 사용하여 렌더링됩니다. 따라서 오브젝트가 올바른 섀도우를 캐스트할 수 있는 경우 카메라의 뎁스 텍스처에도 올바르게 표시됩니다. 전에는 커스텀 버텍스 애니메이션이나 펑키 알파 테스트를 원하는 경우 이렇게 하기가 매우 어려웠습니다. 이로 인해 이제는 Camera-DepthTexture.shader도 사용되지 않습니다. 또한 모든 내장된 섀도우 셰이더는 후면 컬링을 사용하지 않았지만, 이제는 일반 렌더링의 컬링 모드와 일치하도록 변경되었습니다.