요약
반복되는 형상이 있는 모든 장면에서 인스턴싱을 사용하면 메모리 사용량을 줄이고 장면 그래프 쿠킹 성능을 높일 수 있습니다. 일반적으로 인스턴스화는 여러 복사본에서 형상이 동일하고 필요한 유일한 수정 사항은 변환일 때 잘 작동합니다. 이 문서에서는 "인스턴스 배열" 위치를 사용하여 인스턴스화하는 방법을 설명하고 이를 포인트 클라우드의 점에 대한 인스턴스 형상에 사용하는 방법에 대한 예를 제공합니다.
사용 가능한 다른 인스턴스화 접근 방식에 대한 개요를 보려면 Katana 개발자 가이드: 인스턴스화 의 다음 섹션을 읽어보세요 .
포인트 클라우드 인스턴스화에 대한 아래 섹션을 설명하는 예제 프로젝트는 다음 Katana 프로젝트 파일 " instanceArray_arnold_material.katana "를 참조할 수 있습니다.
인스턴스 어레이
다음 섹션은 어레이 인스턴스화에 대한 간략한 개요입니다. 인스턴싱에 대한 보다 심층적인 논의를 위해 Renderman 문서: RenderMan 25 Docs - Katana 의 인스턴싱에서는 인스턴싱에 대한 소개로서 세 가지 인스턴싱 방법을 모두 설정하는 방법을 보여줍니다.
인스턴스 어레이에서 인스턴스 위치는 "인스턴스 어레이" 유형의 단일 위치에 있는 속성을 통해 하나 이상의 인스턴스 소스에 매핑됩니다. 인스턴스 배열은 계층적 인스턴스화와 유사하며, 여러 인스턴스 소스를 쉽게 설정할 수 있다는 추가 이점도 있습니다. 한 가지 단점은 인스턴스별로 재질을 변경할 수 없다는 것입니다.
인스턴스 배열 위치에는 기하학.instanceSource 와 하나 이상의 변환 속성이 포함되어야 합니다. 인스턴스 소스 에 단일 경로만 포함되어 있으면 해당 인스턴스 소스가 인스턴스 배열의 모든 인스턴스에 사용되는 경우 Geometry.instanceIndex 는 선택 사항입니다.
기하학.인스턴스소스 | 하나 이상의 인스턴스 소스의 장면 그래프 위치 경로를 포함하는 문자열 또는 문자열 배열 속성 |
기하학.인스턴스 인덱스 | 필요한 인스턴스와 동일한 수의 요소가 있는 배열 특성입니다. 이 배열에 저장된 값은 기하학.instanceSource 배열에서 원하는 인스턴스 소스의 인덱스를 나타냅니다. 즉, instanceIndex는 인스턴스 인덱스에서 인스턴스 소스 인덱스로의 매핑을 구성합니다. |
기하학.instanceMatrix 기하학.instance기하학 변환.instanceRotateX 기하학.instanceRotateY | 이러한 각 속성은 인스턴스별 변환의 평면 배열입니다. 각 속성의 의미는 기존 변환 속성과 동일하며 애니메이션을 지원하기 위해 다중 샘플링이 가능합니다. 참고: RenderMan은 기하학.instanceMatrix 속성의 사용만 지원합니다. |
인스턴스화 속성 규칙에 대한 자세한 내용은 Katana 개발자 가이드: 인스턴스화를 참조하세요.
포인트 클라우드에 대한 어레이 인스턴싱
인스턴스 배열은 인스턴스를 보관하기 위해 한 위치만 사용한다는 이점이 있으며, 이는 수천 개의 인스턴스 위치가 있는 장면에서도 장면 그래프를 작게 유지합니다. 인스턴스 배열은 인스턴스 배열을 생성하기 위해 인스턴스 소스의 위치가 포함된 기하학.instanceSource 속성을 읽습니다. 여러 인스턴스 소스는 각 인스턴스에 대해 하나씩 인스턴스 소스의 인덱스 배열을 포함하는 기하학.indexArray 속성을 사용하여 참조할 수 있습니다. 다음은 포인트 클라우드의 포인트에 대한 인스턴스 형상에 대한 인스턴스 배열을 생성하는 단계입니다.
1. 포인트 클라우드 객체를 생성하거나 가져오고 AttributeSet 노드를 사용하여 해당 위치의 유형 속성을 포인트 클라우드 로 설정합니다. 포인트 클라우드는 PrimitiveCreate 노드의 것과 같은 기하학.point.P 속성을 가진 모든 형상일 수 있습니다.
그러면 장면 그래프에서 포인트 클라우드의 위치 유형이 변경된 것을 볼 수 있습니다.
2. 그런 다음 인스턴스 소스로 사용하려는 형상을 생성하거나 가져옵니다. 그런 다음 다른 AttributeSet 노드를 사용하여 상위 위치의 유형 속성을 인스턴스 소스 로 설정합니다.
예를 들어, 기하학이 /root/world/geo/src/teapot 에 있는 경우 /root/world/geo/src가 인스턴스 소스 위치여야 합니다. 나중에 이 위치 아래에 개체를 더 추가하여 여러 인스턴스 소스를 사용할 수 있습니다.
그러면 장면 그래프에서 인스턴스 소스의 위치 유형이 변경된 것을 볼 수 있습니다.
3. 두 네트워크를 병합하여 다음과 같은 결과를 얻습니다.
4. 병합 다운스트림에서 OpScript 노드를 생성하고 해당 applyWhere 매개변수를 특정 위치 로 변경합니다. 이제 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는 인스턴스 배열의 기하학.instanceSource 속성을 user.instanceSourceLocations 사용자 매개변수에 설정된 인스턴스 소스 위치로 설정합니다. 또한 인스턴스 배열의 기하학.instanceIndex 속성은 인스턴스 소스 간에 대체되도록 설정됩니다. 마지막으로 인스턴스 배열의 기하학.instanceMatrix 속성은 포인트 클라우드에 있는 각 포인트의 변환 정보로 채워집니다.
7. 이제 인스턴스가 생성되었으므로 포인트 클라우드는 더 이상 필요하지 않으며 Prune 노드를 사용하여 장면에서 제거할 수 있습니다.
이제 렌더링하여 인스턴스 배열을 볼 수 있습니다.
완성된 장면은 여기( instanceArray.katana) 에서 다운로드할 수 있습니다.
인스턴스별로 할당된 재질을 변경하는 인스턴스 배열 해결 방법
다른 인스턴스화 기술과 달리 인스턴스 배열에는 인스턴스별로 재질을 직접 변경하는 메커니즘이 없습니다. 그러나 다양한 재료가 포함된 인스턴스 소스 위치를 사용하여 인스턴스에 다른 재료를 사용할 수 있습니다. 인스턴스 배열을 사용하면 모든 인스턴스가 하나의 장면 그래프 위치에 포함된다는 이점이 있습니다. 그러나 이는 개별 인스턴스가 뷰어나 장면 그래프에 표시되지 않고 장면 렌더링에서만 볼 수 있으므로 특정 인스턴스를 찾는 것이 거의 불가능하다는 의미이기도 합니다.
인스턴스 배열을 생성하려면 위의 Pointcloud에 대한 인스턴스 배열 섹션을 참조하세요. 인스턴스 배열이 생성되면 각 인스턴스 소스의 재료를 변경하여 인스턴스 배치별로 재료를 변경할 수 있습니다. MaterialAssign 노드를 사용하여 인스턴스 소스의 재질을 변경하면 해당 특정 인스턴스 소스를 활용하는 각 인스턴스 위치에 재질 할당이 전달됩니다. 간단히 MaterialAssign 노드를 생성하고 인스턴스 소스로 선택한 장면 그래프 위치에 재질을 할당하면 됩니다.
추가 읽기
인스턴스화 개요는 아래 첫 번째 리소스 링크를 참조하세요. 아래의 다른 리소스에서는 각 인스턴스화 방법에 대한 기타 고급 인스턴스화 주제에 대해 자세히 설명합니다.
- Katana 개발자 가이드: 인스턴스화
- Q100508: 계층적(인스턴스 소스) 인스턴싱으로 장면 그래프 쿠킹 성능 향상
- Q100517: 리프 수준(인스턴스 ID) 인스턴싱으로 장면 그래프 쿡 성능 향상
- 렌더맨 문서: RenderMan 25 Docs - Katana 의 인스턴싱
첨부 파일
우리는 문제로 불편을 끼쳐 드려 죄송합니다
이유를 알려주세요