Q100517: 리프 수준(인스턴스 ID) 인스턴싱으로 장면 그래프 쿡 성능 향상

팔로우

요약

반복되는 형상이 있는 모든 장면에서 인스턴싱을 사용하면 메모리 사용량을 줄이고 장면 그래프 쿠킹 성능을 높일 수 있습니다. 일반적으로 인스턴스화는 여러 복사본에서 형상이 동일하고 필요한 유일한 수정 사항은 변환일 때 잘 작동합니다. 이 기사에서는 "리프 수준 인스턴스화"라는 인스턴스 ID 속성을 사용하여 인스턴스화하는 방법을 설명하고 이를 포인트 클라우드의 포인트에 대한 인스턴스 형상에 사용하는 방법의 예를 제공합니다.

사용 가능한 다른 인스턴스화 접근 방식에 대한 개요를 보려면 Katana 개발자 가이드: 인스턴스화 의 다음 섹션을 읽어보세요 .

포인트 클라우드 인스턴스화에 대한 아래 섹션을 설명하는 예제 프로젝트는 Katana 프로젝트 파일 " PointcloudInstancingAndMaterialAssign_Arnold.katana "를 참조하십시오.

리프 수준 인스턴스화

다음 섹션은 리프 수준 인스턴스화에 대한 간략한 개요입니다. 인스턴싱에 대한 보다 심층적인 논의를 위해 Renderman 문서: RenderMan 25 Docs - Katana 의 인스턴싱에서는 인스턴싱에 대한 소개로서 세 가지 인스턴싱 방법을 모두 설정하는 방법을 보여줍니다.

리프 수준 인스턴스화에서는 기존의 반복되는 형상을 인스턴스화할 수 있습니다. 즉, 장면에 이미 여러 번 존재하는 형상은 한 번만 로드되고 추가로 발생하는 형상은 메모리에 있는 동일한 형상 데이터 세트를 참조합니다. 인스턴스화의 이점을 얻을 수 있는 반복 형상이 있는 기존 Katana 프로젝트는 장면 그래프의 반복 형상 위치에 instance.ID 속성을 추가하여 쉽게 수정할 수 있습니다. 그러나 단점은 자식이 없는 위치만 인스턴스화할 수 있다는 것입니다.

이를 달성하려면 모든 동일한 위치에 일치하는 인스턴스.ID 속성이 있어야 합니다. 한 위치는 렌더러에 의해 인스턴스 소스로 선택되고 다른 모든 위치는 해당 위치의 인스턴스로 처리됩니다.

참고: 모든 위치에 형상이 포함되어야 하는지 또는 장면 그래프의 가장 높은 위치에만 형상이 필요한지 결정하려면 형상을 인스턴스 소스로 선택하는 방법을 이해하는 것이 중요합니다. 인스턴스 소스 선택 방법을 이해하려면 렌더러 문서를 참조하세요.

포인트 클라우드에 대한 리프 수준 인스턴스화

포인트 클라우드에 인스턴스화하기 위해 인스턴스 ID를 사용하려면 OpScript가 인스턴스 소스를 포인트 클라우드의 각 포인트에 복사해야 합니다. 더 간단한 해결책은 OpScript 없이 계층적 인스턴스화를 사용하는 것입니다 (Q100508: Hierarchical (Instance Source) Instancing 참조). 그러나 두 인스턴스 방법 중 하나에 OpScript를 사용하면 개별 인스턴스 위치가 뷰어에 표시되고 재질을 각 인스턴스에 별도로 할당할 수 있다는 이점이 있습니다 . 잠재적인 단점은 특히 수천 개의 인스턴스가 있는 경우 약간 더 다루기 힘든 장면 그래프입니다.

OpScript는 인스턴스 위치를 생성하고 포인트 클라우드의 각 포인트에 대한 인스턴스.ID 속성을 복사합니다. OpScript에 의해 위치가 생성되면 렌더러는 하나의 위치를 지오메트리 소스로 선택한 다음 다른 모든 위치는 해당 위치의 인스턴스로 처리됩니다 . 다음은 포인트 클라우드에 대한 리프 수준 인스턴스화를 달성하는 단계입니다.

1. Alembic_In을 사용하여 포인트 클라우드와 인스턴스 소스를 가져옵니다. 그런 다음 인스턴스.ID 라는 속성을 포인트 클라우드 위치의 임의 문자열 값으로 설정합니다. 이 예에서 instance.ID는 "bob"입니다.

2. OpScript 노드를 생성하고 해당 위치 매개변수를 인스턴스가 생성될 장면 그래프 위치로 설정합니다 (예: "/root/world/geo/derivedassets").

3. OpScript 노드에서 user.instanceSourceLocation 매개변수를 생성하고 이를 인스턴스 소스의 장면 그래프 위치로 설정합니다. 그런 다음 포인트 클라우드의 장면 그래프 위치에 대한 user.pointCloudLocation 매개변수를 만듭니다. 사용자 매개변수 생성 단계는 Katana 사용자 가이드: 사용자 매개변수 추가를 참조하세요. 리프 수준 인스턴스화에서는 인스턴스 소스 위치에 하위 항목을 포함할 수 없습니다. 그렇지 않으면 인스턴스화가 작동하지 않습니다.

4. 그런 다음 다음 코드를 OpScript 노드의 스크립트 매개변수에 복사하여 포인트 클라우드의 각 포인트에 대한 인스턴스 위치를 생성합니다.

 -- Read op arguments
local instanceSourceLocation = Interface.GetOpArg( "user.instanceSourceLocation" ):getValue()
local pointCloudLocation = Interface.GetOpArg( "user.pointCloudLocation" ):getValue()

if Interface.AtRoot() then
 
-- Read the point cloud
 
local points = Interface.GetAttr( "geometry.point.P" , pointCloudLocation):getNearestSample(Interface.GetCurrentTime())

 
-- Read the instanceID
 
local instanceID = Interface.GetAttr( "instance.ID" , pointCloudLocation):getNearestSample(Interface.GetCurrentTime())

 
-- Loop over points
 
local x, y, z
 
local gb = GroupBuilder()
 
for i= 0 , #points/ 3 - 1 do
      x = points[
3 *i+ 1 ]
      y = points[
3 *i+ 2 ]
      z = points[
3 *i+ 3 ]

     
-- Build op arguments for the child location
      gb:update(Interface.GetOpArg())
      gb:set(
"childAttrs" , Interface.GetAttr( "" , instanceSourceLocation))
      gb:set(
"childAttrs.geometry.instanceSource" , StringAttribute(instanceSourceLocation))
      gb:set(
"childAttrs.xform.interactive.translate" , DoubleAttribute({x, y, z}))
      gb:set(
"childAttrs.instance.ID" , StringAttribute(instanceID))

     
-- Create the child
      Interface.CreateChild(
         
string . format ( "child%04d" , i),
          Interface.GetOpType(),
          gb:build())
 
end
else
 
local childAttrs = Interface.GetOpArg( "childAttrs" )
 
for i= 0 , childAttrs:getNumberOfChildren() -1 do
      Interface.SetAttr(childAttrs:getChildName(i), childAttrs:getChildByIndex(i))
 
end
end

위의 OpScript는 인스턴스 소스를 인스턴스 ID 속성을 포함하여 포인트 클라우드의 각 포인트에 복사합니다.

5. 마지막으로 Prune 노드를 사용하여 장면 그래프에서 포인트 클라우드를 제거하여 렌더링에서 생략합니다. 이 단계는 렌더러가 포인트 클라우드를 인스턴스 소스로 선택하지 않도록 하기 위해 필요합니다.

재료 할당을 통한 재료 변형

인스턴스별로 재질을 수정하면 모든 인스턴스가 재질과 같은 인스턴스 소스의 속성을 상속하므로 추가 작업이 발생할 수 있습니다. 이 섹션에서는 인스턴스화의 성능 이점을 유지하면서 인스턴스별로 재질과 셰이더를 변경하는 방법을 설명합니다.

OpScript를 사용하여 리프 수준 및 계층적 인스턴스화를 사용하여 포인트 클라우드의 각 포인트에 대한 인스턴스 위치를 생성하면 인스턴스 위치별로 재료를 할당할 수 있다는 이점이 있습니다.

인스턴스 위치를 생성한 후 각 인스턴스의 위치에 따라 재료가 달라질 수 있습니다. 특정 인스턴스를 식별하는 것은 장면 그래프에서 인스턴스 위치를 확장하고 뷰어에서 원하는 인스턴스를 선택하는 것만큼 간단합니다. 제공된 예제 프로젝트에서 인스턴스 위치는 /root/world/geo/derivedassets 위치 아래에서 찾을 수 있습니다.

그런 다음 MaterialAssign 노드를 사용하거나 인스턴스 위치에 MaterialAssign 속성을 설정하여 재질 위치를 가리키는 방식으로 원하는 위치에 재질을 할당할 수 있습니다.

추가 읽기
인스턴스화 개요는 아래 첫 번째 리소스 링크를 참조하세요. 아래의 다른 리소스에서는 각 인스턴스화 방법에 대한 기타 고급 인스턴스화 주제에 대해 자세히 설명합니다.

첨부 파일

우리는 문제로 불편을 끼쳐 드려 죄송합니다

이유를 알려주세요