AGSL과 GLSL의 차이

AGSL과 GLSL은 구문이 매우 비슷하므로 최소한의 변경만으로 많은 GLSL 프래그먼트 셰이더 효과를 Android로 가져올 수 있습니다. AGSL은 GLSL ES 1.0 (OpenGL ES 2.0에서 사용하는 셰이딩 언어)에서 설정된 GLSL 기능을 수정하여 최대 기기 도달범위를 제공합니다.

GLSL 프래그먼트 셰이더는 래스터라이저와 블렌딩 하드웨어 간의 전체 GPU 동작을 제어합니다. 이 셰이더는 색상을 계산하기 위한 모든 작업을 실행하며 셰이더가 생성하는 색상은 정확히 파이프라인의 블렌딩 단계에 공급되는 색상입니다. AGSL에서 셰이더를 작성하면 Android 그래픽 파이프라인의 단계를 프로그래밍하게 됩니다. 언어 차이의 상당수는 바로 여기에서 비롯됩니다.

셰이더 실행

GLSL 셰이더에서와 마찬가지로 AGSL 셰이더는 main 함수에서 실행을 시작합니다. GLSL과 달리 이 함수는 '로컬' 좌표의 셰이더 위치를 매개변수로 사용합니다. 이는 gl_FragCoord와 비슷하지만, 셰이더를 호출하기 전에 프레임 버퍼 좌표가 아닌 이러한 좌표가 변환되었을 수 있습니다. 그런 다음 셰이더는 중간 정밀도 또는 높은 정밀도로 픽셀 색상을 vec4로 반환합니다 (GLSL의 out vec4 color 또는 gl_FragColor과 유사).

mediump vec4 main(in vec2 fragCoord)

좌표 공간

GLSL과 AGSL 좌표 공간의 비교

GLSL을 사용하여 그려진 셰이더와 AGSL을 사용하여 그려진 거의 동일한 셰이더

AGSL과 GLSL은 기본적으로 다른 좌표 공간을 사용합니다. GLSL에서 프래그먼트 좌표 (fragCoord)는 왼쪽 하단을 기준으로 합니다. AGSL은 캔버스의 화면 좌표계와 일치합니다. 즉, Y축이 왼쪽 상단에서 시작됩니다. 필요한 경우 해상도를 균일하게 전달하고 Y축 값에 resolution.y - fragCoord.y를 사용하여 두 공간 간에 변환할 수 있습니다. 또는 로컬 변환 행렬을 셰이더에 적용할 수 있습니다.

// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)

정밀도 및 유형

GLSL과 호환되는 정밀도 수정자가 지원되지만, AGSL에는 중간 정밀도도 나타내는 halfshort 유형이 도입되었습니다.

벡터 유형은 명명된 <base type><columns>로 선언할 수 있습니다. vec2 대신 float2를, bvec4 대신 bool4를 사용할 수 있습니다. 행렬 유형은 명명된 <base type><columns>x<rows>로 선언할 수 있으므로 mat3 대신 float3x3입니다. 또한 AGSL은 matvec의 GLSL 스타일 선언을 허용하며 이러한 유형은 부동 소수점 수에 매핑됩니다.

전처리기

AGSL은 GLSL 스타일 전처리기 지시어를 지원하지 않습니다. #define 문을 const 변수로 변환합니다. AGSL의 컴파일러는 const 변수의 지속적인 접기와 브랜치 제거를 지원하므로 효율적입니다.

색상 공간

Android 애플리케이션은 색상이 관리됩니다. 캔버스의 색공간은 그리기를 위한 작업 색공간을 결정합니다. 소스 콘텐츠 (예: BitmapShader 등의 셰이더)에도 색상 공간이 있습니다.

물리적으로 정확한 조명과 같은 특정 효과의 경우 계산은 선형 색 공간에서 실행해야 합니다. 이를 돕기 위해 AGSL은 다음과 같은 내장 기능을 제공합니다.

half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)

이는 작업 색상 공간과 Android의 LINEAR_EXTENDED_SRGB 색상 공간 간에 색상을 변환합니다. 이 공간은 sRGB 원색 (영역)과 선형 전송 함수를 사용합니다. 확장 범위 값 (0.0 미만 및 1.0 이상)을 사용하여 sRGB 영역 밖의 값을 나타냅니다.

유니폼

AGSL은 유니폼에 색상이 포함되어 있는지 알 수 없으므로 색상 변환이 자동으로 적용되지 않습니다. half4/float4/vec4layout(color)로 라벨을 지정하면 Android에서 유니폼이 색상으로 사용된다는 사실을 알 수 있어 Android에서 균일한 값을 작업 색상 공간으로 변환할 수 있습니다.

AGSL에서 다음과 같이 유니폼을 선언합니다.

layout(color) uniform half4 iColor;  // Input color
uniform float2 iResolution;          // Viewport resolution (pixels)

그러면 Android 코드에서 다음과 같이 유니폼을 설정할 수 있습니다.

shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())