- Landscape 활용 방법 탐구
- 머티리얼의 vector 값을 이용해서 Landscape를 왜곡하는 방식으로 층이 있는 월드맵 생성을 하고 싶었다.
- 선택한 방식은 두 가지였다.
- 방식 1
- 브러시 머티리얼 선택해서 맵 모양을 그림.
- 단점 1 : 맵이 커지면 오래 걸린다. 심하게..
- 단점 2 : 브러시의 알파값이 겹치면서 원하는 모양이 안 나올 수 있기에 크기를 설정해야하는데, 귀찮다. 그리고 맵 크기에 따라 어긋날 확율이 많다.
- 방식 2
- 브러시 모양을 맵 모양으로 만들어서 한 번만 찍기.
- 순서 : 텍스쳐 생성 -> 텍스쳐 모양으로 렌더타겟에 그림.
- Texture 생성은 성공했는데..
< 5 X 5 / 5층 테스트 UTexture2D >
- 방식 1
- 1차 시도 - 브러시 머티리얼의 Texture 파라미터를 텍스쳐로 바꾸기 위해 시도
- (해당 파라미터 변경은 UMaterialInstanceDynamic 타입만 가능.)
- (해당 파라미터 변경은 UMaterialInstanceDynamic 타입만 가능.)
- 2차 시도 - 브러시 머티리얼을 UMaterialInstanceDynamic 타입으로 설정 (
- (K2_DrawMaterial 함수의 매개 변수에 '다이나믹' 머티리얼은 사용 불가.)
- (K2_DrawMaterial 함수의 매개 변수에 '다이나믹' 머티리얼은 사용 불가.)
- 3차 시도 - 사용하는 UTextureRenderTarget2D 자체를 새롭게 만든 텍스쳐로 변환 시도
- 매크로 함수 ENQUEUE_RENDER_COMMAND(UpdateTextureRegionsData) 활용하려는데, 렌더타겟의 텍스쳐 접근시 오류로 포기
- 4차 시도 - 2차 시도 방식(K2_DrawMaterial)으로 재도전
- 형 변환 방법을 못 찾아 어려웠었는데(UMaterialInstanceDynamic -> UMaterialInterface), 갑자기 방법이 떠올랐다.
- UStaticMeshComponent->SetMaterial(), GetMaterial() 함수를 사용하면 다이나믹 머티리얼이 일반 머티리얼로 변환 가능하다.
< 8 X 8 / 16층 테스트 URenderTargetTexture2D > - 추가 문제를 발견했다.
- 언리얼의 Landscape 객체의 자동 LOD(LevelOfDetail) 관련.
- Height Deformation (텍스쳐의 Alpha값을 버텍스 높이에 반영한다.) 방법으로 Landscape 객체에 언덕을 만들었는데, 관찰자와 거리가 멀어지면 언덕이 다시 평평해진 듯 보였다.
< 강조 부분이 평평해져 보이는 부분 > - Landscape의 LOD 수치를 조정해보았으나 여기에 반영되지는 않았고, 테셀레이션(tessellation) 프로퍼티 수정시 반응을 보였다. Landscape 생성 시 자동으로 크기 감쇠 부분이 활성화 되었기에 비활성화 시켰다.
< 테셀레이션 감쇠 설명 >
< 이제 멀어져도 봉우리가 잘 솟아있다 > - Sample code
-
void AWorldCreator::BeginPlay() { Super::BeginPlay(); UTexture2D* texture = CreateTexture(); ALandscape* targetLandscape = Cast<ALandscape>(UGameplayStatics::GetActorOfClass(GetWorld(), ALandscape::StaticClass())); if (targetLandscape && RenderTarget && HeightBrushMI && texture) { // Tracing으로 위치 찾기 FHitResult outHit; FVector traceStart = GetActorLocation(); FVector traceEnd = traceStart + (FVector::UpVector * -9999.f); FCollisionQueryParams collisionParam; collisionParam.AddIgnoredActor(GetOwner()); GetWorld()->LineTraceSingleByChannel(outHit, traceStart, traceEnd, ECollisionChannel::ECC_Visibility, collisionParam); // HeightBrushMI 준비 UMaterialInstanceDynamic* DynamicMaterial = UMaterialInstanceDynamic::Create(HeightBrushMI, GetWorld()); DynamicMaterial->SetTextureParameterValue(FName("TextureParam"), texture); targetLandscape->UpdateAllComponentMaterialInstances(); MaterialConverter->SetMaterial(0, DynamicMaterial); // RenderTarget 위에 HeightBrushMI 마스킹 if (outHit.GetActor()) { UCanvas* canvas; FVector origin; FVector boxExtent; targetLandscape->GetActorBounds(false, origin, boxExtent); FVector2D HitScreenPosition = FVector2D( abs(targetLandscape->GetActorLocation().X - outHit.Location.X) / (boxExtent.X * 2), abs(targetLandscape->GetActorLocation().Y - outHit.Location.Y) / (boxExtent.Y * 2) ); FVector2D screenSize = FVector2D(RenderTarget->SizeX, RenderTarget->SizeY); FDrawToRenderTargetContext targetContext; UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(GetWorld(), RenderTarget, canvas, screenSize, targetContext); UKismetRenderingLibrary::ClearRenderTarget2D(GetWorld(), RenderTarget); FCanvasMaterialTransform CanvasMaterialTransform = GetCanvasMaterialTransform(HitScreenPosition, screenSize, 1.0f); canvas->K2_DrawMaterial(MaterialConverter->GetMaterial(0), CanvasMaterialTransform.Position, CanvasMaterialTransform.Size, FVector2D(0, 0)); UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(GetWorld(), targetContext); } } else { if (targetLandscape == nullptr) UE_LOG(LogTemp, Warning, TEXT("Null targetLandscape")); if (RenderTarget == nullptr) UE_LOG(LogTemp, Warning, TEXT("Null RenderTarget")); if (texture == nullptr) UE_LOG(LogTemp, Warning, TEXT("Null texture")); } } UTexture2D* AWorldCreator::CreateTexture() { uint8* pixels = (uint8*)malloc(Height * Width * 4); // x4 because it's RGBA. 4 integers, one for Red, one for Green, one for Blue, one for Alpha ... UPackage* package = CreatePackage(nullptr, *pathPackage); ... UTexture2D* texture = NewObject<UTexture2D>(package, textureName, RF_Public | RF_Standalone); ... free(pixels); pixels = NULL; return texture; }
'GameDevelopmentDiary > SteppingIsland : 가제' 카테고리의 다른 글
1일차 (6시간) (0) | 2021.08.11 |
---|