Epic GamesのテクニカルアーティストMarien Elalaoui氏による、カスタムノードとHLSLシェーダーを使用し、UE4上でレイマーチングシェーダーを使ったブロブ表現を構築するチュートリアル「Blob with Raymarching」がYoutube上に公開されました。
英語ですが、少しづつ構築しながら解説されているので、一つ一つ手順をまねしていくだけでも勉強になると思います。
動画中登場するDistance関数参考サイト:Inigo Quilez :: fractals, computer graphics, mathematics, shaders, demoscene and more
シェーダーのコードとノード画像参考に張り付けておきますね。
カスタムノードの中身
#include "/Engine/RMBlob.ush"
return 0;
UE本体のインストール先にある、Engine/Shadersフォルダに保存したシェーダーを読み込んでるだけです
RMBlob.ushの中身
struct RMstruct
{
float RMSphere(float3 pos)
{
return length(pos) - 50;
}
float3 RMNormal(float3 pos)
{
float2 Off = float2(0.01,0);
return normalize(float3(
RMSphere(pos + Off.xyy) - RMSphere(pos - Off.xyy),
RMSphere(pos + Off.yxy) - RMSphere(pos - Off.yxy),
RMSphere(pos + Off.yyx) - RMSphere(pos - Off.yyx)
));
}
//Smooth Union
float opSmoothUnion( float d1, float d2, float k )
{
float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );
return lerp( d2, d1, h ) - k*h*(1.0-h);
}
};
RMstruct RM;
float4 Col = 0;
float3 pos = WorldPosition;
float3 Normal = 0;
for(int i=0; i<MaxSteps; i++)
{
if(SceneDepth < length(pos - CameraPosition))
break;
float d1 = RM.RMSphere(pos - ObjectPosition);
//メッシュディスタンスフィールドを使わない場合(コメントアウトしてます
//float d2 = SceneDepth - length(pos - CameraPosition);
//メッシュディスタンスフィールドを使う場合
float d2 = GetDistanceToNearestSurfaceGlobal(pos);
float distance = RM.opSmoothUnion(d1, d2, Smooth);
if(distance < 0.01)
{
Col = 1;
Normal = RM.RMNormal(pos - ObjectPosition);
break;
}
pos += CameraVector * 1;
}
return float4(Normal,Col.a);
マテリアルノード参考
今回がMarien Elalaoui氏初のチュートリアル動画との事ですが、
過去にアップされた動画の表現がとても気になります。今後の動きも楽しみですね。
コメント