Version: 2022.1
언어: 한국어
빌트인 셰이더 변수
샘플러 상태 사용

셰이더 데이터 타입 및 정밀도

The standard Shader language in Unity is HLSL, and general HLSL data types are supported. However, Unity handles some data types differently from HLSL, particularly to provide better support on mobile platforms.

기본 데이터 타입

Shaders carry out the majority of calculations using floating point numbers (which are float in regular programming languages like C#). In Unity’s implementation of HLSL, the scalar floating point data types are float, half, and fixed. These data types differ in precision and, consequently, performance or power usage. There are also several related data types for vectors and matrices such as half3 and float4x4.

고정밀도: float

This is the highest precision floating point data type. On most platforms, float values are 32 bits like in regular programming languages.

Full float precision is generally useful for world space positions, texture coordinates, or scalar calculations that involve complex functions such as trigonometry or power/exponentiation. If you use lower precision floating point data types for these purposes, it can cause precision-related artifacts. For example with texture coordinates, a half doesn’t have enough precision to accurately represent 1-texel offsets of larger textures.

중정밀도: half

This is a medium precision floating point data type. On platforms that support half values, they are generally 16 bits. On other platforms, this becomes float.

half values have a smaller range and precision than float values.

Half precision is useful to get better shader performance for values that don’t require high precision such as short vectors, directions, object space positions, and high dynamic range colors.

저정밀도: fixed

This is only supported by the OpenGL ES 2.0 Graphics API. On other APIs it becomes the lowest supported precision (half or float).

This is the lowest precision fixed point value and is generally 11 bits. fixed values range from –2.0 to +2.0 and have a precision of 1/256.

고정 정밀도는(일반 텍스처에 일반적으로 저장된) 일반 컬러와 간단한 컬러 작업 수행에 유용합니다.

Floating point numbers

Unity’s shader compiler ignores floating point number suffixes from HLSL. Floating point numbers with a suffix therefore all become float.

This code shows a possible negative impact of numbers with the h suffix in Unity: half3 packedNormal = ...; half3 normal = packedNormal * 2.0h - 1.0h;

Since the h suffix is ignored, the shader compiler generates code that executes these steps: 1. Calculate an intermediary normal value in high precision (float3) 2. Convert the intermediary value to half3. This reduces your shader’s performance.

This code is more efficient because it only uses half values in its calculations: half3 packedNormal = ...; half3 normal = packedNormal * half(2.0) - half(1.0);

정수 데이터 타입

정수(int 데이터 타입)는 종종 루프 카운터나 배열 인덱스로 사용됩니다. 이 용도로 사용할 경우 일반적으로 다양한 플랫폼에서 문제 없이 사용 가능합니다.

플랫폼에 따라 GPU에서 정수 타입을 지원하지 않을 수 있습니다. 예를 들어, Direct3D 9 및 OpenGL ES 2.0 GPU는 플로팅 포인트 데이터에만 동작하고(비트 또는 논리 연산을 수반하는) 간단해 보이는 정수식을 꽤 복잡한 플로팅 포인트 수학 명령을 사용하여 에뮬레이트할 수 있습니다.

Direct3D 11, OpenGL ES 3, Metal 및 기타 최신 플랫폼은 정수 데이터 타입을 제대로 지원하므로 비트 시프트와 비트 마스킹을 사용하면 올바르게 작동합니다.

복합 벡터/매트릭스 타입

HLSL에는 기본 타입을 토대로 만든 빌트인 벡터 및 매트릭스 타입이 있습니다. 예를 들어, float3은 .x, .y, .z 컴포넌트가 있는 3D 벡터고 half4는 .x, .y, .z, .w 컴포넌트가 있는 중정밀도 4D 벡터입니다. 또는 컬러 관련 작업을 수행할 때 유용한 .r, .g, .b, .a 컴포넌트를 사용하여 벡터를 인덱스할 수 있습니다.

매트릭스 타입도 유사한 방법으로 빌드됩니다. 예를 들어 float4x4는 4x4 변환 매트릭스입니다. OpenGL ES 2.0 같은 일부 플랫폼에서는 정사각형 매트릭스만 지원합니다.

텍스처/샘플러 타입

일반적으로 텍스처를 HLSL 코드에서 다음과 같이 선언합니다.

sampler2D _MainTex;
samplerCUBE _Cubemap;

모바일 플랫폼의 경우 “저정밀도 샘플러”로 변환됩니다. 즉, 텍스처에는 저정밀도 데이터가 있어야 합니다. Shader precision model 드롭다운을 사용하여 Player Settings에서 Unity 프로젝트 전체의 기본 샘플러 정밀도를 변경할 수 있습니다. 텍스처에 HDR 컬러가 포함되어 있음을 알고 있는 경우 반정밀도 샘플러를 사용할 수 있습니다.

sampler2D_half _MainTex;
samplerCUBE_half _Cubemap;

또는 텍스처에 전체 플로트 정밀도 데이터가 포함된 경우(예: 뎁스 텍스처), 전체 정밀도 샘플러를 사용합니다.

sampler2D_float _MainTex;
samplerCUBE_float _Cubemap;

정밀도, 하드웨어 지원 및 성능

float/half/fixed 데이터 타입을 사용하는 경우에 발생하는 복잡한 문제 중 하나는 PC GPU가 항상 고정밀도라는 점입니다. 즉, 모든 PC(Windows/Mac/Linu) GPU는 셰이더에서 float, half 또는 fixed 데이터 타입 중 무엇을 작성하든 상관없이 항상 모든 것을 전체 32비트 플로팅 포인트 정밀도로 연산합니다.

halffixed 타입은 모바일 GPU가 타겟인 경우에만 중요합니다. 이 경우 두 타입은 주로 전력(및 때로는 성능) 제약을 위해 존재합니다. 셰이더를 테스트하여 정밀도/숫자 문제가 발생하지 않는지 확인해야 함을 기억해야 합니다.

모바일 GPU의 경우에도 여러 정밀도 지원이 GPU 제품군에 따라 다릅니다. 다음은 각 모바일 GPU 제품군이 각 플로팅 포인트 타입(각 타입에 사용된 비트 수로 나타냄)을 처리하는 방법의 개요입니다.

GPU 제품 float half fixed
PowerVR Series 6/7 32 16
PowerVR SGX 5xx 32 16 11
Qualcomm Adreno 4xx/3xx 32 16
Qualcomm Adreno 2xx 32버텍스 24프래그먼트
ARM Mali T6xx/7xx 32 16
ARM Mali 400/450 32버텍스 16프래그먼트
NVIDIA X1 32 16
NVIDIA K1 32
NVIDIA Tegra 3/4 32 16

대부분의 최신 모바일 GPU는 실제로 32비트 숫자(float 타입에 사용됨) 또는 16비트 숫자(halffixed 타입에 모두 사용됨) 중 하나만 지원합니다. 일부 구형 GPU의 버텍스 셰이더 및 프래그먼트 셰이더 연산 정밀도는 다릅니다.

더 낮은 정밀도를 사용하면 GPU 레지스터 할당 개선으로 인해 또는 특정 저정밀도 수학 연산을 위한 특수 “빠른 경로” 실행 유닛으로 인해 종종 빨라질 수 있습니다. 순수한 성능상의 이점이 없는 경우에도 더 낮은 정밀도를 사용하면 종종 GPU에 전원이 덜 사용되어 배터리 수명이 연장됩니다.

일반적인 경험 법칙에 따르면, 포지션 및 텍스처 좌표를 제외한 모든 것에 대해 반정밀도로 시작해야 합니다. 계산의 일부분에 반정밀도가 충분하지 않은 경우에만 정밀도를 높여야 합니다.

무한, NaN 및 기타 특수 플로팅 포인트 값에 대한 지원

특수 플로팅 포인트 값에 대한 지원은 사용하는 GPU 제품군(대부분 모바일)에 따라 다를 수 있습니다.

Direct3D 10을 지원하는 모든 PC GPU는 매우 정확하게 규정된 IEEE 754 플로팅 포인트 스탠다드를 지원합니다. 즉, 플로트 숫자가 CPU에 일반적인 프로그래밍 언어에서 동작하는 것과 똑같이 동작합니다.

모바일 GPU의 지원 수준은 약간 다를 수 있습니다. 일부 GPU로 0을 0으로 나눈 결과는 NaN(“숫자 아님”)이 될 수 있고, 그 외의 GPU에서는 무한, 0, 또는 기타 지정되지 않은 값이 될 수 있습니다. 타겟 디바이스에서 셰이더를 테스트하여 지원되는지 확인해야 합니다.

외부 GPU 문서

GPU 제조사는 자사 GPU의 성능 및 기능에 대한 심층적인 가이드를 제공합니다. 자세한 내용은 다음을 참조하십시오.

참고 항목

빌트인 셰이더 변수
샘플러 상태 사용
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961