頭と尻尾はくれてやる!

パソコンおやじのiPhoneアプリ・サイト作成・運営日記


SceneKitでマスクをしたい

ARKitを使ってごにょごにょしてるんだけど、どこでもドア的な表現をSceneKitでしようとしてふと固まってしまった。SceneKitでマスクってどうやるんだ?

どこでもドアの向こう側には別な世界があって、それらがドアの入り口形状の長方形でマスクされれば表現できるわけだけど、、、

いろいろ調べたつもりなんだがマスクのやり方がわからない。

Metalのステンシルバッファでマスクしてみる
↑Metalでステンシルバッファ使ってやったことはあるけど、、、超絶めんどくさい。天下の(?)SceneKitなんだからもっとサクッとできそうな気がしてならない。

結局、、、ステンシルバッファは使わずに、SceneKitでオフスクリーンレンダリング、つまり最初にマスクしたいオブジェクト(どこでもドアの向こうにあるオブジェクト)をMTLTextureに出力し、次にドアのこちら側のオブジェクトとドア入り口の長方形をディスプレイに表示する。その長方形の色はフラグメントシェーダーでMTLTextureから選んで表示してやる、という流れでやることにした。

オブジェクトの位置関係

↑位置関係はこんなの。黄色い四角形がドア入り口に相当。

↑床面がドアの向こうにも表示されてるのはご愛嬌(手抜き)。

GitHub - lachlanhurst/SceneKitOffscreenRendering: Using SCNRenderer to render a scene offscreen to a texture that's then displayed in another scene
↑すごく参考になったのがこちらのコード。不要な部分を排除してすんごい理解しやすいコード。感謝、感謝。SCNRendererクラスって初めて使ったわ。

上のサンプルコードと異なる部分だと、、、
出力するテクスチャの設定。
{
	MTLTextureDescriptor *textureDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm width:width height:height mipmapped:NO];
	offscreenTexture = [device newTextureWithDescriptor:textureDescriptor];
}

ドア入り口の長方形の表示にシェーダーを設定する。ここでシェーダーに渡してやるテクスチャ画像をoffscreen renderingの出力画像に設定してる。
-(void)setupShaderForNode:(SCNNode *)node
{
    SCNGeometry *geometry = node.geometry;
    
    SCNMaterial *material = geometry.firstMaterial;
    
    SCNProgram *program = [SCNProgram program];
    program.vertexFunctionName = @"myVertex";
    program.fragmentFunctionName = @"myFragment";
    material.program = program;
    
    SCNMaterialProperty *imageProperty = [SCNMaterialProperty materialPropertyWithContents:offscreenTexture];
    [material setValue:imageProperty forKey:@"offscreenTexture"];
}

こんな感じでマスクできそうだけど、、、
うーーーーん。やっぱりそのうちSceneKitでしれっと実装される気がする。

<< Harry Potter全巻読み終えた  TopPage  Anker PowerCore 13000と100均Type-CケーブルでSwitchを充電 >>

コメント


管理者にだけ表示を許可する
 

トラックバック

トラックバックURL
http://ringsbell.blog117.fc2.com/tb.php/1083-25db7001




Copyright ©頭と尻尾はくれてやる!. Powered by FC2 Blog. Template by eriraha.

FC2Ad