본문 바로가기
AI Image

ComfyUI X UnrealEngine - ComfyTexture 개발 일지 (1)

by 도승이 2024. 5. 7.

2024.04.17 - [AI Image] - ComfyUI X UnrealEngine

 

ComfyUI X UnrealEngine

오늘의 주제 Unreal Engine 의 프로젝트에 ComfyUI를 플러그인으로 연결해주기 git : ComfyTextures https://github.com/AlexanderDzhoganov/ComfyTextures GitHub - AlexanderDzhoganov/ComfyTextures: Unreal Engine ⚔️ ComfyUI - Automatic tex

dose.tistory.com


이어지는 글이다.

 

ComfyTexture 기본 기능

Prompt에 따라 AI Image 생성 이후 Unreal Level의 Camera가 보고있는 Actor에 Image Projection한 Material을 생성 및 적용 해주는 기능.

 

기능을 추가
단순히 Prompt 만 입력해서 언리얼로 3d object를 생성하는 방법을 찾아보자.

 

ComfyTexture의 코드를 분석 해보기 위해 ChatGPT를 활용해 보자.

 

예제에 쓰인 코드 이다.

https://github.com/AlexanderDzhoganov/ComfyTextures/blob/main/Plugins/ComfyTextures/Source/ComfyTextures/Private/ComfyTexturesWidgetBase.cpp

 

ComfyTextures/Plugins/ComfyTextures/Source/ComfyTextures/Private/ComfyTexturesWidgetBase.cpp at main · AlexanderDzhoganov/Comfy

Unreal Engine ⚔️ ComfyUI - Automatic texturing using generative diffusion models - AlexanderDzhoganov/ComfyTextures

github.com

 

무려 2800줄의 긴 코드인데

이러한 코드도 ChatGPT로 분석이 가능하다.

 

물론 한번에 입력시 최대 입력 토큰제한으로 분석이 되지않는다.

ChatGPT는 사용자가 입력했던 내용을 어느정도 기억 할 수 있다.

또한 300~500줄정도를 나누어서 입력하면 전체적으로 분석이 가능하다.

 

새로 채팅을 하나 만든다음

 

"다음 구문을 코드 분석해줘."

 

또는 코드를 입력후 Shift + Enter로 빈 줄을 만든 다음 '코드 분석해줘' 라고 치면된다.

(ex  :  EXAMPLE CODE ~~

~~~ EXAMPLE CODE

한국어로 코드 분석 해줘 )

 

그럼 답변이 이와 같이 나온다.

 

실제 답변 1)
해당 코드는 "ComfyTextures"라는 네임스페이스를 사용하며, ComfyTexturesWidgetBase 클래스의 멤버 함수들을 정의하고 있습니다.
Connect() 함수는 HttpClient가 유효하지 않으면 새로운 ComfyTexturesHttpClient를 만들고 WebSocket 연결을 수립합니다. WebSocket 상태 변화 및 메시지 처리 콜백을 설정하고, Connect()를 호출하여 연결을 시작합니다.
IsConnected() 함수는 HttpClient의 유효성을 확인하고, 해당 HttpClient가 연결되었는지 여부를 반환합니다.
GetNumPendingRequests() 함수는 RenderQueue에 대기 중인 요청의 수를 반환합니다.
HasPendingRequests() 함수는 대기 중인 요청이 있는지 여부를 확인합니다.
ValidateAllRequestsSucceeded() 함수는 RenderQueue의 모든 요청이 성공했는지 여부를 확인합니다.
ProcessMultipleActors() 함수는 여러 개의 액터를 처리하는데, 연결된 상태인지와 현재 상태가 Idle인지 확인한 후, 씬 텍스처를 캡처하고 업로드합니다. 모드가 편집 모드인 경우, 액터의 텍스처를 수정하기 위해 MagentaPixel 텍스처를 사용합니다.
나머지는 정적으로 선언된 함수들로, 이중선형 보간법, 텍스처 아일랜드 확장 및 삼각형 래스터라이제이션과 같은 기능을 제공합니다.

 

실제 답변 2)

제공된 코드 세그먼트는 UComfyTexturesWidgetBase 클래스를 사용하여 텍스처를 렌더링하고 관리하는 여러 함수로 구성됩니다. 이러한 함수들의 주요 기능을 살펴보겠습니다:
SendRenderRequest: 이 함수는 HTTP POST 요청을 사용하여 렌더링 요청을 어떤 서비스(아마도 ComfyUI)로 보냅니다. 노이즈 시드, 스텝, 강도, 이미지 파일 이름 등과 같은 다양한 매개변수를 설정하여 요청 페이로드를 준비합니다. 그런 다음 요청을 렌더 큐에 추가하고 비동기적으로 응답을 처리합니다.
InterruptRender: 현재 진행 중인 렌더링 프로세스가 있는 경우 이 함수는 "interrupt" 명령을 사용하여 HTTP POST 요청을 보내어 해당 프로세스를 중단합니다.
ClearRenderQueue: 이 함수는 "queue" 명령과 큐를 지우기 위한 페이로드를 사용하여 HTTP POST 요청을 보내어 렌더 큐를 지웁니다.
FreeComfyMemory: 이 함수는 HTTP POST 요청을 사용하여 ComfyUI 관련 메모리를 해제합니다. 메모리 해제, 모델 언로드 및 히스토리 지우기와 같은 여러 명령을 사용하여 요청 페이로드를 설정합니다.
PrepareActors: 이 함수는 기본 재질 및 참조 텍스처와 같은 특정 옵션을 기반으로 배우들을 렌더링하기 위해 준비합니다. 배우의 화면 경계를 계산하고 적절한 텍스처 크기를 결정하며 참조 텍스처를 다시 크기 조정하고 새 텍스처를 만들어 배우의 정적 메시 구성 요소에 할당합니다.
이러한 함수들은 렌더링 요청을 시작하고, 진행 중인 렌더를 중단하고, 렌더 큐를 관리하며, 메모리를 해제하고, 배우를 렌더링하기 위해 모두 함께 작동합니다.

 

 

이와같이 수천줄에 달하는 코드도 몇번만 나누어서 입력한다면 어떤 메소드가 어떤 역할을 하는지 빠르게 파악 가능하다.

 

 

 

코드 전체 분석

ChatGPT 3.5 )

Connect() 함수는 HttpClient가 유효하지 않으면 새로운 ComfyTexturesHttpClient를 만들고 WebSocket 연결을 수립합니다. WebSocket 상태 변화 및 메시지 처리 콜백을 설정하고, Connect()를 호출하여 연결을 시작합니다.

IsConnected() 함수는 HttpClient의 유효성을 확인하고, 해당 HttpClient가 연결되었는지 여부를 반환합니다.

GetNumPendingRequests() 함수는 RenderQueue에 대기 중인 요청의 수를 반환합니다.

HasPendingRequests() 함수는 대기 중인 요청이 있는지 여부를 확인합니다.

ValidateAllRequestsSucceeded() 함수는 RenderQueue의 모든 요청이 성공했는지 여부를 확인합니다.

ProcessMultipleActors() 함수는 여러 개의 액터를 처리하는데, 연결된 상태인지와 현재 상태가 Idle인지 확인한 후, 씬 텍스처를 캡처하고 업로드합니다. 모드가 편집 모드인 경우, 액터의 텍스처를 수정하기 위해 MagentaPixel 텍스처를 사용합니다.

ProcessRenderResultForActor 함수는 특정 액터에 대한 렌더링 결과를 처리합니다. 이 함수는 액터의 정적 메시 컴포넌트에서 텍스처를 추출하고, 텍스처의 각 픽셀에 대해 렌더링 결과를 계산하여 텍스처를 업데이트합니다.

ProcessRenderResults 함수는 모든 액터에 대한 렌더링 결과 처리를 시작합니다. 이 함수는 액터 세트를 반복하고, 각 액터에 대해 ProcessRenderResultForActor를 호출하여 렌더링 결과를 처리합니다.

CancelJob 함수는 현재 렌더링 작업을 취소합니다. 렌더링 중인 경우 인터럽트하고 렌더링 대기열을 비워서 작업을 종료합니다.

QueueRender : 이 함수는 HTTP POST 요청을 사용하여 렌더링 요청을 어떤 서비스(아마도 ComfyUI)로 보냅니다. 노이즈 시드, 스텝, 강도, 이미지 파일 이름 등과 같은 다양한 매개변수를 설정하여 요청 페이로드를 준비합니다. 그런 다음 요청을 렌더 큐에 추가하고 비동기적으로 응답을 처리합니다.

InterruptRender: 현재 진행 중인 렌더링 프로세스가 있는 경우 이 함수는 "interrupt" 명령을 사용하여 HTTP POST 요청을 보내어 해당 프로세스를 중단합니다.

ClearRenderQueue: 이 함수는 "queue" 명령과 큐를 지우기 위한 페이로드를 사용하여 HTTP POST 요청을 보내어 렌더 큐를 지웁니다.

FreeComfyMemory: 이 함수는 HTTP POST 요청을 사용하여 ComfyUI 관련 메모리를 해제합니다. 메모리 해제, 모델 언로드 및 히스토리 지우기와 같은 여러 명령을 사용하여 요청 페이로드를 설정합니다.

PrepareActors: 이 함수는 기본 재질 및 참조 텍스처와 같은 특정 옵션을 기반으로 배우들을 렌더링하기 위해 준비합니다. 배우의 화면 경계를 계산하고 적절한 텍스처 크기를 결정하며 참조 텍스처를 다시 크기 조정하고 새 텍스처를 만들어 배우의 정적 메시 구성 요소에 할당합니다.

ParseWorkflowJson: 이 함수는 주어진 JSON 파일에서 텍스처 워크플로우 매개변수를 파싱합니다. JSON 파일을 로드하고 직렬화한 후에는 각 매개변수를 추출하여 OutParams 구조체에 저장합니다.

GetWorkflowJsonPath: 이 함수는 특정 텍스처 모드에 대한 JSON 파일 경로를 반환합니다. 각 모드에는 해당하는 JSON 파일이 있으며, 해당 모드에 대한 경로를 생성하여 반환합니다.

SetEditorFrameRate: 이 함수는 에디터의 프레임 속도를 설정합니다. 설정에서 편집기의 FPS 제한이 활성화되어 있으면 지정된 FPS로 설정됩니다.GetChildActorsRecursive: 이 함수는 주어진 액터의 하위 액터를 재귀적으로 검색하여 모든 하위 액터를 찾습니다. 정적 메시 구성 요소를 가진 액터만 선택합니다.

LoadParams 및 SaveParams: 이러한 함수들은 기본적인 워크플로우 매개변수를 JSON 파일에서 로드하고 저장합니다. 이러한 매개변수는 각 텍스처 모드에 대해 정의되며, 애플리케이션의 설정 파일에 저장됩니다.

HandleWebSocketMessage: 이 함수는 웹 소켓 메시지를 처리하고 해당 메시지에 따라 렌더링 상태를 업데이트합니다. 렌더링이 시작되면 시작되었음을 알리고, 진행 중인 렌더링 프로세스에서 메시지를 수신하면 해당 정보를 처리하여 진행률을 업데이트합니다.

ReadRenderTargetPixels 및 ConvertImageToPng: 이러한 함수들은 렌더 타겟 픽셀을 읽고 PNG 이미지로 변환하는 데 사용됩니다. 렌더 타겟 텍스처의 픽셀을 읽어와서 깊이, 노말 또는 색상 이미지로 변환하고, 해당 이미지를 PNG 형식으로 압축하여 저장합니다.

UploadImages 함수는 이미지와 파일명 배열을 받아서 이미지를 업로드하는 비동기 작업을 수행합니다. 이미지와 파일명 수가 다를 경우 에러를 출력하고 콜백을 호출합니다.

DownloadImage 함수는 파일명을 받아서 해당 이미지를 다운로드하는 비동기 작업을 수행합니다. 다운로드에 실패할 경우 에러를 출력하고 콜백을 호출합니다.

CalculateApproximateScreenBounds 함수는 액터의 대략적인 화면 영역을 계산합니다. 액터가 널인 경우 에러를 출력합니다.

CreateTexture2D 함수는 너비, 높이, 픽셀 배열을 받아서 UTexture2D 객체를 생성합니다. 픽셀 수가 너비와 높이의 곱과 다를 경우 에러를 출력합니다.

CreateAssetPackage 함수는 에셋과 패키지 경로를 받아서 에셋을 패키징합니다. 에셋이 널이거나 패키지 경로가 비어있을 경우 에러를 출력합니다.

CreateEditMaskFromImage 함수는 픽셀 배열을 받아서 마스크 이미지를 생성합니다. 주어진 픽셀이 특정 조건에 부합하는지 확인하여 마스크 이미지를 생성합니다.

CreateEdgeMask 함수는 깊이 이미지와 법선 이미지를 받아서 가장자리 마스크를 생성합니다. 깊이와 법선 이미지의 크기가 다를 경우 에러를 출력합니다.

LoadRenderResultImages 함수는 렌더링 결과 이미지를 로드하는 비동기 작업을 수행합니다. 로드에 실패할 경우 에러를 출력하고 콜백을 호출합니다.

TransitionToIdleState() 함수는 상태를 "Idle"로 전환하고, 상태 변경 콜백을 호출합니다.

CreateCameraTransforms() 함수는 카메라 트랜스폼을 만들어 반환합니다. 에디터 카메라 모드와 기존 카메라 모드에 따라 다른 동작을 합니다.

CaptureSceneTextures() 함수는 지정된 액터들의 장면을 캡처하여 출력합니다. 해당 장면을 렌더 타겟에 캡처하고, 캡처된 텍스처를 처리하여 출력에 추가합니다.

ProcessSceneTextures() 함수는 캡처된 텍스처를 처리하는데, 주로 텍스처의 크기를 조절하고 특정 처리를 수행합니다.

ResizeImage() 함수는 이미지의 크기를 조절하는데 사용되며, 입력 이미지를 새로운 크기에 맞게 조정합니다.

 

 

 

이를 이용해서

우리는 실제 작업하는 부분인 QueueRender() 메소드를 참고하여 새로운 기능을하는 메소드를 제작해보자.

 

목표 1. 

Prompt를 입력하고 한번의 버튼클릭으로  Unreal 컨텐츠 브라우저에  3D Object 를 생성하기.

 

 

생각나는대로 마음대로 그려보았다.

 

과정

StabilityMatrix의 ComfyUI를 사용한다.

UnrealEngine의 EditorUtilityWidget의 버튼을 클릭시 HTTP post request 를 ComfyUI로 요청할 것이고,

데이터가 전달되는 매체는 Json파일을 통해서 전달할 것이다.

 

이어서 계속..

'AI Image' 카테고리의 다른 글

Unreal에서 Python Script로 OBJ Import하기  (0) 2024.05.20
Perplexity AI  (0) 2024.05.09
Meta llama-3 소개 및 다운로드 및 설치  (0) 2024.04.30
ComfyUI X UnrealEngine  (0) 2024.04.17
ComfyUI 3D 생성형 AI (SV3D, TripoSR)  (0) 2024.04.09

댓글