導言

上個文章中我們已經操作了一遍Houdini & UE4的管線。但是應用到實際工作中時會發現其實還是有很多不方便的地方。

比如當你自己定義的layer導入houdini engine再導出後,會變成temp里的layerinfo文件。

再次input地形的話,自己定義的layer就沒有了。

再然後,如果修改了houdini engine導出的層,會發現修改的信息並不能正確的傳入houdini engine。

當然一些world compostion相關的易用性和區域更新也是很大的問題。但是這些會放在後面來講,歡迎關注哦!

houdini導出地形到UE4

在解決問題之前,我們還是應該先啃一下代碼,拋開其他流程不管,我們直接關注最後創建地形的地方。

UHoudiniAssetComponent::CreateAllLandscapes

------->

FHoudiniLandscapeUtils::CreateAllLandscapes

這裡就是最終創建地形的地方了,大致的流程是從houdini engine吧cook好的地形數據取出來,讀取一些屬性,從houdini的float數據轉化為UE4的uint8數據,然後創建新的地形或者是更新到輸入的地形當中。

具體的流程可以看下面的流程圖,了解清楚了houdini engine 導入地形到UE4中的流程後,我們就可以在其中想要修改流程的地方做自己的定製啦!

還有一個藏得比較深的代碼是,houdini engine在將layerinfo導入後,會把原來的的float數據保存在debugcolor中,用於導回houdini engine的時候保留一個較高的精度。

UE4將地形輸入到houdini engine

我們再看一下地形輸入houdini engine的流程,其實和導入一樣,主要還是一些數據的提取和float->uint8的轉化。

再反覆的踩坑和調試之後,發現流程中有一步恢復導入數據的代碼,後面居然夾帶了清除由houdini engine導入的層的功能。這就很奇怪了,上面明明還特意把信息存在debugcolor中用於導回,這裡居然反手就是一波清空(懵逼臉)。

關於layer的一些定製化

在看完流程之後,這裡做兩處簡單的修改,是的真的很簡單啦。

講道理下面這兩部都是隱式的處理並不太有很好,有需要的話可以修改houdiniengine的slate部分,讓操作流程更加友好。

1、layername或者layerinfoname中帶有_custom的話,不傳入houdini的層。

bool
FHoudiniLandscapeUtils::CreateHeightfieldFromLandscape(
ALandscapeProxy* LandscapeProxy, HAPI_NodeId& CreatedHeightfieldNodeId )
{
...

// 1. Extract the uint8 values from the layer
TArray<uint8> CurrentLayerIntData;
FLinearColor LayerUsageDebugColor;
FString LayerName;
if ( !GetLandscapeLayerData( LandscapeInfo, n, CurrentLayerIntData, LayerUsageDebugColor, LayerName ) )
continue;

////////////////////////////////////////////////////
// Exclude the layers with "_custom" it indicate this layers is customized and only use in Unreal
if (LayerName.Contains(TEXT("_custom")) || LandscapeInfo->Layers[n].LayerInfoObj->GetName().Contains(TEXT("_custom")))
{
continue;
}
////////////////////////////////////////////////////

// 2. Convert unreal uint8 values to floats
// If the layer came from Houdini, additional info might have been stored in the DebugColor to convert the data back to float
HAPI_VolumeInfo CurrentLayerVolumeInfo;
TArray < float > CurrentLayerFloatData;
if ( !ConvertLandscapeLayerDataToHeightfieldData(
CurrentLayerIntData, XSize, YSize, LayerUsageDebugColor,
CurrentLayerFloatData, CurrentLayerVolumeInfo ) )
continue;

...
}

2、layername中帶有_remain的話,不會在輸入houdini engine的時候被清除

bool
FHoudiniLandscapeUtils::RestoreLandscapeFromFile( ALandscapeProxy* LandscapeProxy )
{
...
// Iterate on the landscape infos layer to remove any layer that could have been added by Houdini
for (int LayerIndex = 0; LayerIndex < LandscapeInfo->Layers.Num(); LayerIndex++)
{
ULandscapeLayerInfoObject* CurrentLayerInfo = LandscapeInfo->Layers[LayerIndex].LayerInfoObj;
if ( SourceLayers.Contains( CurrentLayerInfo ) )
continue;

////////////////////////////////////////////////////
// Exclude the layer with "_remain" so it wont be clear before upload to houdini
FString CurLayerName = LandscapeInfo->Layers[LayerIndex].LayerName.ToString();
if (CurLayerName.Contains(TEXT("_remain")))
{
continue;
}
////////////////////////////////////////////////////

// Delete the added layer
FName LayerName = LandscapeInfo->Layers[LayerIndex].LayerName;
LandscapeInfo->DeleteLayer(CurrentLayerInfo, LayerName);
}
...
}

總結

在我們看過一遍地形在UE4和houdini engine中導入和導出的代碼後,已經對整體流程有了一個基礎的了解,也是為後面的定製化開發打下了一個基礎。

這裡我們只是做了兩個簡單的修改,來修改layer導入導出的流程,為一些非houdini engine製作的layer加上保護,使得地形可以在UE4中編輯也可以在houdini中編輯。

下一篇會介紹如何定製化的把houdini engine中製作的地形導入UE4並拆散為關卡流,用於開啟了world composition的大世界場景製作,歡迎關注!

如果圖看不清,可以打開下面有道雲筆記的鏈接。

有道雲筆記?

note.youdao.com


推薦閱讀:
相关文章