忍者ブログ

DeltaLabWorks

UE4でレイマーチング

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

コメント

ただいまコメントを受けつけておりません。

UE4でレイマーチング




だいたいこちらのページに書いてある通りにやった
http://qiita.com/nkdtr/items/d2cdbf61f873cef5e952





注意点

UE4で録画をするとき、-DUMPMOVIE の引数を使って録画する方法があるが、バグっているらしい
https://answers.unrealengine.com/questions/203741/bug-in-benchmark-function-when-used-with-dumpmovie.html

マテリアルのCustomノードのコードの部分で、範囲選択してから何かやろうとするとフリーズする場合がある、コードを消すときはコードのとこの枠の右にある黄色い矢印をクリックして消す

マテリアルのCustomノードでは関数の定義ができないので、
C言語でマクロを組む-> "gcc -E xxxx.c > xxxx.fx" って感じでプリプロセッサにかける->Customノードにコピペ
とやるといい

rayMarchingMacros.h


// GenericFunctions
 // mod 返し値はfloat
 #define mod(x, y) (x - y * floor(x/y))
 // 変換行列の取得(オイラー角) ret:float4x4
 #define getTransformMatrix(rot, move, ret){\
  float sx = sin(rot.x); float cx = cos(rot.x);\
  float sy = sin(rot.y); float cy = cos(rot.y);\
  float sz = sin(rot.z); float cz = cos(rot.z);\
  ret[0][0] = cx*cy*cz - sx*sz;\
  ret[0][1] = -cx*cy*sz - sx*cz;\
  ret[0][2] = cx*sy;\
  ret[0][3] = move.x;\
  ret[1][0] = sx*cy*cz + cx*sz;\
  ret[1][1] = -sx*cy*sz + cx*cz;\
  ret[1][2] = sx*sy;\
  ret[1][3] = move.y;\
  ret[2][0] = -sy*cz;\
  ret[2][1] = sy*sz;\
  ret[2][2] = cy;\
  ret[2][3] = move.z;\
  ret[3][0] = 0;\
  ret[3][1] = 0;\
  ret[3][2] = 0;\
  ret[3][3] = 1;\
 }\

// DistanceFunctions
 // Primitive
  // 球
  #define sdSphere(p, s, ret) {ret = length(p)-s;}
  // 直方体
  #define udBox(p, b, ret) {ret = length(max(abs(p)-b,0.0));}
  // 直方体
  #define sdBox(p, b, ret) {float3 d = abs(p) - b; ret = min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));}
  // 角が丸い直方体
  #define udRoundBox(p, b, r, ret) {ret = length(max(abs(p)-b,0.0))-r;}
  // 円柱
  #define sdCappedCylinder(p, h, ret) {float2 d = abs(float2(length(p.xz),p.y)) - h; ret = min(max(d.x,d.y),0.0) + length(max(d,0.0));}
  // カプセル / ライン
  #define sdCapsule(p, a, b, r, ret) {float3 pa = p - a, ba = b - a; float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); ret = length( pa - ba*h ) - r;}

 // Domain operations
  // 複製
  #define opRep(p, c, func) {float3 tmp = p; p = mod(p, c)-0.5*c; {func;}; p = tmp;}
  // 回転・移動
  #define opTx(p, m, func) {float3 tmp = p; p = mul(transpose(m), p); func; p = tmp;}
 
 // Distance operations
  // 結合
  #define opU(a, b, ret) {ret = min(a, b);}
  // 減算
  #define opS(a, b, ret) {ret = max(a, -b);}
  // 乗算
  #define opI(a, b, ret) {ret = max(a, b);}
  // 滑らかな結合 k=32
  #define opSMin1(a, b, k, ret) {float res = exp( -k*a ) + exp( -k*b ); ret = -log( res )/k;}
  // k=0.1
  #define opSMin2(a, b, k, ret) {float h = clamp( 0.5+0.5*(b-a)/k, 0.0, 1.0 ); ret = lerp( b, a, h ) - k*h*(1.0-h);}
  // k=8
  #define opSMin3(a, b, k, ret) {float x = pow(a, k); float y = pow(b, k); ret = pow( (a*b)/(a+b), 1.0/k );}


// 大型汎用関数
 // 法線ベクトルを返す、ret:float3
 #define getNormal(p, ret) {\
  float d = 0.01;\
  float gn1, gn2, gn3, gn4, gn5, gn6;\
  float3 on1, on2, on3, on4, on5, on6;\
  on1 = p+float3( d,0.0,0.0);\
  on2 = p+float3(-d,0.0,0.0);\
  on3 = p+float3(0.0, d,0.0);\
  on4 = p+float3(0.0,-d,0.0);\
  on5 = p+float3(0.0,0.0, d);\
  on6 = p+float3(0.0,0.0,-d);\
  map(on1, gn1);\
  map(on2, gn2);\
  map(on3, gn3);\
  map(on4, gn4);\
  map(on5, gn5);\
  map(on6, gn6);\
  ret = normalize(float3(gn1-gn2, gn3-gn4, gn5-gn6));\
 }\

// ==================================================================
// .cファイル側でやることの例
// ==================================================================

/**
// ディスタンスファンクション、マクロ名と引数は固定
#define map(p, ret) {\
 float4x4 rotMatrix;\
 float3 rot = RotateAmount;\
 float3 zeroVect = float3(0,0,0);\
 getTransformMatrix(rot, zeroVect, rotMatrix);\
 float boxDist, towerDist;\
 opRep(p, RepDistance, udRoundBox(p, BoxSize, RoundRadius, boxDist), boxDist);\
 opRep(p, RepDistance, opTx(p, rotMatrix, sdCappedCylinder(p, CylinderSize, towerDist), towerDist), towerDist);\
 opSMin2(boxDist, towerDist, SMinK, ret);\
}\

// メイン部分
int main()
{
 float3 currentPos = CamLoc - ObjectLoc;
 float totalDistance = 0;
 float4 retval = float4(0,0,0,0);
 
 for( int i=0; i<64; i++)
 {
  float distance;
  map(currentPos, distance);
  totalDistance += distance;
  currentPos += distance * CamDir;
  if( distance < 0.1 )
  {
   float3 norm;
   getNormal(currentPos, norm);
   retval.x = norm.x;
   retval.y = norm.y;
   retval.z = norm.z;
   //retval.w = totalDistance;
   retval.w = 1;
   break;
  }
  else if( totalDistance > EndDistance )
  {
   retval.w = 0;
   break;
  }
 }
 return retval;
}

PR

コメント

プロフィール

HN:
Sankaku
性別:
非公開

P R