요약
반복되는 지오메트리가 있는 모든 장면에서 인스턴싱을 사용하면 메모리 사용량을 줄이고 씬 그래프 쿡 성능을 향상시킬 수 있습니다. 일반적으로 인스턴싱은 여러 복사본에서 지오메트리가 동일하고 필요한 수정 사항이 변환뿐일 때 효과적입니다. 이 문서에서는 "인스턴스 배열" 위치를 사용하여 인스턴싱하는 방법을 설명하고, 이를 사용하여 포인트 클라우드의 포인트에 지오메트리를 인스턴스화하는 방법을 예시로 보여줍니다.
사용 가능한 다른 인스턴싱 접근 방식에 대한 개요는 Katana 개발자 가이드의 다음 섹션인 인스턴싱을 읽어보세요.
아래 섹션의 포인트 클라우드 인스턴싱을 설명하는 예제 프로젝트는 Katana 프로젝트 파일 " instanceArray_arnold_material.katana "를 참조하세요.
인스턴스 배열
다음 섹션에서는 배열 인스턴싱에 대한 간략한 개요를 제공합니다. 인스턴싱에 대한 자세한 내용은 RenderMan 설명서를 참조하십시오. RenderMan 26 Docs - Katana 의 인스턴싱에서는 인스턴싱에 대한 소개로서 세 가지 인스턴싱 방법을 모두 설정하는 방법을 보여줍니다.
인스턴스 배열에서 인스턴스 위치는 "인스턴스 배열" 유형의 단일 위치에 있는 속성을 통해 하나 이상의 인스턴스 소스에 매핑됩니다. 인스턴스 배열은 계층적 인스턴싱과 유사하지만, 여러 인스턴스 소스를 쉽게 설정할 수 있다는 장점이 있습니다. 한 가지 단점은 인스턴스별로 재료를 변경할 수 없다는 것입니다.
인스턴스 배열 위치에는 geometry.instanceSource 와 하나 이상의 변환 속성이 포함되어야 합니다. instanceSource 에 단일 경로만 포함된 경우 geometry.instanceIndex 는 선택 사항이며, 이 경우 해당 인스턴스 소스가 인스턴스 배열의 모든 인스턴스에 사용됩니다.
geometry.instanceSource |
하나 이상의 인스턴스 소스의 장면 그래프 위치 경로를 포함하는 문자열 또는 문자열 배열 속성 |
geometry.instanceIndex |
필요한 인스턴스 수와 동일한 개수의 요소를 갖는 배열 속성입니다. 이 배열에 저장된 값은 geometry.instanceSource 배열에서 원하는 인스턴스 소스의 인덱스를 나타냅니다. 즉, instanceIndex는 인스턴스 인덱스에서 인스턴스 소스 인덱스로의 매핑을 구성합니다. |
geometry.instanceMatrix geometry.instanceTranslate geometry.instanceRotateX geometry.instanceRotateY |
이러한 각 속성은 인스턴스별 변환의 평면 배열입니다. 각 속성의 의미는 기존 변환 속성과 동일하며, 애니메이션을 지원하기 위해 다중 샘플링이 가능합니다. 참고: RenderMan은 geometry.instanceMatrix 속성의 사용만 지원합니다. |
속성 규칙 인스턴싱에 대한 자세한 내용은 Katana 개발자 가이드: 인스턴싱을 참조하세요.
포인트 클라우드에 대한 어레이 인스턴싱
인스턴스 배열은 인스턴스를 저장하는 데 하나의 위치만 사용한다는 장점이 있어, 수천 개의 인스턴스 위치가 있는 씬에서도 씬 그래프를 작게 유지할 수 있습니다. 인스턴스 배열은 인스턴스 소스의 위치가 포함된 geometry.instanceSource 속성을 읽어 인스턴스 배열을 생성합니다. 각 인스턴스마다 하나씩 인스턴스 소스의 인덱스 배열이 포함된 geometry.indexArray 속성을 사용하여 여러 인스턴스 소스를 참조할 수 있습니다. 다음은 포인트 클라우드의 포인트에 지오메트리를 인스턴스화하기 위한 인스턴스 배열을 생성하는 단계입니다.
1. 포인트 클라우드 객체를 생성하거나 가져오고, AttributeSet 노드를 사용하여 해당 위치의 유형 속성을 pointcloud 로 설정합니다. 포인트 클라우드는 PrimitiveCreate 노드의 객체처럼 geometry.point.P 속성을 가진 모든 지오메트리일 수 있습니다.
그러면 장면 그래프에서 포인트 클라우드의 위치 유형이 변경된 것을 볼 수 있습니다.
2. 인스턴스 소스로 사용할 지오메트리를 생성하거나 가져옵니다. 그런 다음 다른 AttributeSet 노드를 사용하여 해당 부모 위치의 type 속성을 인스턴스 소스 로 설정합니다.
예를 들어, 지오메트리가 /root/world/geo/src/teapot 에 있는 경우 /root/world/geo/src가 인스턴스 소스 위치여야 합니다. 나중에 이 위치 아래에 객체를 더 추가하여 여러 인스턴스 소스를 사용할 수 있습니다.
그러면 씬 그래프에서 인스턴스 소스의 위치 유형이 변경된 것을 볼 수 있습니다.
3. 두 네트워크를 병합하면 다음과 같은 결과가 나옵니다.
4. 병합 후 OpScript 노드를 생성하고 applyWhere 매개변수를 'at specific location' 으로 변경합니다. 이제 OpScript 노드 매개변수 상단에 새 위치 매개변수가 표시됩니다. 위치 매개변수 값은 씬 그래프에서 인스턴스 배열이 생성되는 위치를 결정합니다. 이 예제에서는 /root/world/geo/instances를 사용합니다.
5. OpScript 노드에서 user.pointCloudLocation 문자열 매개변수를 생성하고 포인트 클라우드의 씬 그래프 위치 경로로 설정합니다. 그런 다음, 위젯 유형을 Scene Graph Locations 로 설정하고 인스턴스 소스 씬 그래프 위치 경로를 배열에 값으로 추가하는 user.instanceSourceLocations 문자열 배열 매개변수를 생성합니다.
사용자 매개변수를 만들고 위젯 유형을 변경하는 방법에 대한 자세한 내용은 Katana 사용자 가이드: 사용자 매개변수 추가를 참조하세요.
6. Renderman Docs: Instancing 에서 찾을 수 있는 Pixar 예제에서 축소한 다음 OpScript Lua 코드는 포인트 클라우드와 인스턴스 소스 위치를 기반으로 인스턴스 배열을 생성합니다.
이 코드를 OpScript 노드의 스크립트 매개변수에 복사하여 포인트 클라우드의 각 지점에 인스턴스가 배치된 인스턴스 배열을 생성합니다.
-- Read the op arguments
local instanceSourceLocations = Interface.GetOpArg("user.instanceSourceLocations")
local pointCloudLocation = Interface.GetOpArg("user.pointCloudLocation"):getValue()
-- Read the point cloud's points
local pointAttr = Interface.GetAttr("geometry.point.P", pointCloudLocation)
local points = pointAttr :getNearestSample(Interface.GetCurrentTime())
-- Create a single location which will generate an array of instances
-- Set type for this location to 'instance array'
Interface.SetAttr( 'type' , StringAttribute( 'instance array' ))
-- This instance array location must point to the instance source locations
-- through the attribute 'geometry.instanceSource'
Interface.SetAttr( 'geometry.instanceSource' , instanceSourceLocations)
-- The indexArray attribute determines which instance source each instance location represents
local indexArray = {}
-- for each instance create an instance index
for i= 0 ,#points/ 3-1 do
-- For this example, the instances are arbitrarily assigned to an
-- instance source
-- a more stable apporach would be to use an arbitrary attribute
-- on the point cloud to assign an instance source
indexArray[#indexArray +1 ] = i%instanceSourceLocations:getNumberOfTuples()
end
-- Set index for instance array element
Interface.SetAttr( 'geometry.instanceIndex' , IntAttribute(indexArray, 1 ))
-- geometry.instanceMatrix
-- Get the transforms from the points
local numTimeSamples = pointAttr:getNumberOfTimeSamples()
local matrixArrayMap = {}
-- to get motion blur on the instances, create an instanceMatrix at each
-- time sample available from the point cloud points attribute
for idx=0,numTimeSamples -1 do
local sampleTime = pointAttr:getSampleTime(idx)
local points = pointAttr:getNearestSample(sampleTime)
-- each instance in array has its own matrix
local matrixArray = {}
local workMatrix = Imath.M44d():toTable()
-- for each instance build a matrix with a mocked up transformation
for i=0,#points/ 3-1 do
-- grab the points that represent this instance
x = points[ 3 *i +1 ]
y = points[ 3 *i +2 ]
z = points[ 3 *i +3 ]
-- set the translate of the matrix to the points in the point cloud
workMatrix[ 13 ] = x
workMatrix[ 14 ] = y
workMatrix[ 15 ] = z
for j = 1 , 16 do
matrixArray[#matrixArray +1 ]=workMatrix[j]
end
end
matrixArrayMap[sampleTime] = matrixArray
end
Interface.SetAttr('geometry.instanceMatrix', DoubleAttribute (matrixArrayMap, #matrixArrayMap))
위의 OpScript는 인스턴스 배열 geometry.instanceSource 속성을 user.instanceSourceLocations 사용자 매개변수에 설정된 인스턴스 소스 위치로 설정합니다. 또한, 인스턴스 배열 geometry.instanceIndex 속성은 인스턴스 소스 간에 번갈아 배치되도록 설정합니다. 마지막으로, 인스턴스 배열 geometry.instanceMatrix 속성은 포인트 클라우드의 각 포인트에서 가져온 변환 정보로 채워집니다.
7. 이제 인스턴스가 생성되었으므로 포인트 클라우드는 더 이상 필요하지 않습니다. Prune 노드를 사용하여 장면에서 제거할 수 있습니다.
이제 인스턴스 배열을 보고 렌더링할 수 있습니다.
완성된 장면은 여기에서 다운로드할 수 있습니다: instanceArray.katana
인스턴스당 할당된 재료를 변경하기 위한 인스턴스 배열 해결 방법
다른 인스턴싱 기법과 달리 인스턴스 배열에는 인스턴스별로 재질을 직접 변경할 수 있는 메커니즘이 없습니다. 하지만 인스턴스 소스 위치와 재질을 다르게 지정하여 인스턴스에 다른 재질을 사용할 수 있습니다. 인스턴스 배열을 사용하면 모든 인스턴스가 하나의 씬 그래프 위치에 포함된다는 장점이 있습니다. 하지만 이는 개별 인스턴스가 뷰어나 씬 그래프에 나타나지 않고 씬 렌더링에서만 표시되기 때문에 특정 인스턴스를 찾는 것이 거의 불가능하다는 것을 의미합니다.
인스턴스 배열을 생성하려면 위의 "인스턴스 배열 에서 포인트클라우드" 섹션을 참조하세요. 인스턴스 배열이 생성되면 각 인스턴스 소스의 재질을 변경하여 인스턴스 배치별로 재질을 변경할 수 있습니다. MaterialAssign 노드를 사용하여 인스턴스 소스의 재질을 변경하면, 해당 인스턴스 소스를 사용하는 각 인스턴스 위치로 재질 할당이 전달됩니다. MaterialAssign 노드를 생성하고 인스턴스 소스로 선택된 씬 그래프 위치에 재질을 할당하기만 하면 됩니다.
추가 읽기
인스턴싱 개요는 아래 첫 번째 리소스 링크를 참조하세요. 아래의 다른 리소스에서는 각 인스턴싱 방법과 관련된 고급 인스턴싱 주제에 대해 자세히 설명합니다.
- Katana 개발자 가이드: 인스턴싱
- Q100508: 계층적(인스턴스 소스) 인스턴싱을 통한 씬 그래프 쿡 성능 향상
- Q100517: Leaf 수준(인스턴스 ID) 인스턴싱을 통한 씬 그래프 쿠킹 성능 향상
- Renderman 문서: RenderMan 26 문서 - Katana 에서 인스턴싱
첨부 파일
우리는 문제로 불편을 끼쳐 드려 죄송합니다
이유를 알려주세요