컬링(Culling)은 보는 사람의 반대 방향을 향하는 폴리곤을 렌더링하지 않는 최적화 방법입니다. 모든 폴리곤에는 앞면과 뒷면이 있습니다. 컬링은 대부분의 오브젝트가 닫혀있다는 점을 이용합니다. 큐브가 있는 경우, 보는 사람과 반대 방향을 향하는 면은 보이지 않습니다. 보는 사람이 있는 방향을 향하는 면이 항상 그 앞에 있기 때문입니다. 따라서 반대 방향을 향하는 면은 그리지 않아도 됩니다. 따라서 후면 컬링이라고 합니다.
렌더링을 올바르게 나타내는 다른 기능은 뎁스(Depth) 테스트입니다. 뎁스 테스트에서는 가장 가까운 표면 오브젝트만 씬에 드로우되는지 확인합니다.
Cull Back | Front | Off
폴리곤에서 컬링할(드로우하지 않을) 면을 제어합니다.
Back 보는 사람과 반대 방향을 향하는 폴리곤을 렌더링하지 않습니다(디폴트).
Front 보는 사람과 같은 방향을 향하는 폴리곤을 렌더링하지 않습니다. 오브젝트의 안팎을 뒤집는 데 사용됩니다.
Off 컬링을 비활성화합니다. 모든 면을 드로우하며, 특수 효과에 사용됩니다.
ZWrite On | Off
오브젝트의 픽셀이 뎁스 버퍼에 작성되는지 여부를 제어합니다(디폴트는 On 입니다). 불투명한 솔리드 오브젝트를 드로우하는 경우 On 상태로 유지합니다. 반투명한 효과를 드로우하는 경우 ZWrite Off
로 전환합니다. 자세한 내용은 아래를 참조하십시오.
ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always
뎁스 테스트를 수행할 방법입니다. 디폴트는 LEqual(기존 오브젝트와 같은 거리에 있거나 그 앞에 있는 오브젝트를 드로우하고 그 뒤의 오브젝트는 숨김)입니다.
Offset Factor, Units
factor 및 units 파라미터 2개를 사용하여 뎁스 오프셋을 지정할 수 있습니다. Factor 는 폴리곤의 X 또는 Y를 기준으로 최대 Z 기울기를 스케일하고 units 는 최소 분석 가능 뎁스 버퍼 값을 스케일합니다. 이를 통해 폴리곤 2개가 실제로는 같은 포지션에 있는 경우에도 폴리곤 하나를 다른 폴리곤 위에 강제로 드로우할 수 있습니다. 예를 들어, Offset 0, -1
은 폴리곤의 기울기를 무시하고 폴리곤을 카메라로 더 가까이 당깁니다. Offset -1, -1
은 지표각에서 폴리곤을 볼 때 더욱 가까이 당깁니다.
다음 오브젝트는 오브젝트의 후면만 렌더링합니다.
Shader "Show Insides" {
SubShader {
Pass {
Material {
Diffuse (1,1,1,1)
}
Lighting On
Cull Front
}
}
}
오브젝트를 큐브에 적용하려고 하면 주위 궤도를 돌 때 지오메트리가 전부 잘못되었다고 느껴집니다. 이는 큐브의 내부만 보이기 때문입니다.
일반적으로 반투명 셰이더는 뎁스 버퍼에 쓰지 않습니다. 그렇기 때문에 특히 복잡하고 볼록하지 않은 메시를 사용할 경우 드로우 순서 문제가 발생할 수 있습니다. 이렇게 메시를 페이드 인하고 페이드 아웃하려는 경우 투명성을 렌더링하기 전에 뎁스 버퍼를 채우는 셰이더를 사용하면 유용할 수 있습니다.
Shader "Transparent/Diffuse ZWrite" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 200
// extra pass that renders to depth buffer only
Pass {
ZWrite On
ColorMask 0
}
// paste in forward rendering passes from Transparent/Diffuse
UsePass "Transparent/Diffuse/FORWARD"
}
Fallback "Transparent/VertexLit"
}
다음은 더 흥미롭습니다. 우선 오브젝트를 노멀 버텍스 조명으로 렌더링한 다음 후면을 밝은 분홍색으로 렌더링합니다. 그러면 노멀을 플립해야 하는 모든 위치가 하이라이트되는 효과가 있습니다. 메시에 ‘빨려 들어가는’ 물리적으로 제어되는 오브젝트가 보일 경우 셰이더를 해당 오브젝트에 할당해 볼 수 있습니다. 분홍색 부분이 보일 경우, 해당 부분에 닿는 모든 것이 안으로 빨려 들어갑니다.
코드로 작성하면 다음과 같습니다.
Shader "Reveal Backfaces" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" { }
}
SubShader {
// Render the front-facing parts of the object.
// We use a simple white material, and apply the main texture.
Pass {
Material {
Diffuse (1,1,1,1)
}
Lighting On
SetTexture [_MainTex] {
Combine Primary * Texture
}
}
// Now we render the back-facing triangles in the most
// irritating color in the world: BRIGHT PINK!
Pass {
Color (1,0,1,1)
Cull Front
}
}
}
컬링 제어는 후면 디버깅을 비롯한 여러 가지 용도에 유용합니다. 투명 오브젝트가 있으면 오브젝트의 후면을 표시해야 하는 경우가 많습니다. 컬링 없이 렌더할 경우(Cull Off) 일부 뒷면이 일부 전면과 오버랩됩니다.
다음은 볼록 오브젝트(구체, 큐브, 자동차 앞 유리)에 사용 가능한 간단한 셰이더입니다.
Shader "Simple Glass" {
Properties {
_Color ("Main Color", Color) = (1,1,1,0)
_SpecColor ("Spec Color", Color) = (1,1,1,1)
_Emission ("Emmisive Color", Color) = (0,0,0,0)
_Shininess ("Shininess", Range (0.01, 1)) = 0.7
_MainTex ("Base (RGB)", 2D) = "white" { }
}
SubShader {
// We use the material in many passes by defining them in the subshader.
// Anything defined here becomes default values for all contained passes.
Material {
Diffuse [_Color]
Ambient [_Color]
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
Lighting On
SeparateSpecular On
// Set up alpha blending
Blend SrcAlpha OneMinusSrcAlpha
// Render the back facing parts of the object.
// If the object is convex, these will always be further away
// than the front-faces.
Pass {
Cull Front
SetTexture [_MainTex] {
Combine Primary * Texture
}
}
// Render the parts of the object facing us.
// If the object is convex, these will be closer than the
// back-faces.
Pass {
Cull Back
SetTexture [_MainTex] {
Combine Primary * Texture
}
}
}
}