1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RealityKitでMetalを使ったCustomMaterialを作る

Last updated at Posted at 2022-05-22
RealityKitではMetalをCustomMaterialとして使用する場合、SurfaceShaderとGeometryModifierが必要になる

SurfaceShader

描画対象となるエンティティの見た目をレンダリングするためのピクセルを決定できる。

GeometryShader

描画の対象となるモデルの頂点を操作することができるので、サイズ、形状を動的に操作できる。

AppleのRealityKitのMetalApiのドキュメント。

それぞれの二つのMetalファイルを作成して作るたいシェーダーを記述する。下記例

#include <metal_stdlib>
#include <RealityKit/RealityKit.h>
using namespace metal;

[[visible]]
void waveMotion(realitykit::geometry_parameters params)
{
    float xSpeed = 1;
    float zSpeed = 1.1;
    float xAmp = 0.01;
    float zAmp = 0.02;

    float3 localPos = params.geometry().model_position();

    float xPeriod = (sin(localPos.x * 40 + params.uniforms().time() /40) + 3) * 2;
    float zPeriod = (sin(localPos.z * 20 + params.uniforms().time() /13) + 3);

    float xOffset = xAmp * sin(xSpeed * params.uniforms().time() + xPeriod * localPos.x);
    float zOffset = zAmp * sin(zSpeed * params.uniforms().time() + zPeriod * localPos.z);
    params.geometry().set_model_position_offset(
        float3(0, xOffset + zOffset, 0)
    );
}

[[visible]]
void waveSurface(realitykit::surface_parameters params)
{
  auto surface = params.surface();
  float maxAmp = 0.03;
  half3 oceanBlue = half3(0, 0.412, 0.58);
  float waveHeight = (
    params.geometry().model_position().y + maxAmp
  ) / (maxAmp * 2);

  surface.set_base_color(
    oceanBlue + min(1.0f, pow(waveHeight, 8)) * (1 - oceanBlue)
  );
}

その後下記のようなコードでCustomMaterialをイニシャライザする際の引数にセットしてあげればMaterialとして扱う。

// deviceを取ってくる。
guard let device = MTLCreateSystemDefaultDevice() else { return }
        // metalLibraryを取ってくる
        guard let library = device.makeDefaultLibrary() else { return }
// ここで作成したGeometry ModifierとsurfaceShaderを用意してセットしてあげる。
        let geometryModifier = CustomMaterial.GeometryModifier(named: "myGeometryModifier", in: library)
        let surfaceShader = CustomMaterial.SurfaceShader(named: "mySurfaceShader", in: library)
        
        let customMaterial: CustomMaterial
        do {
            try customMaterial = CustomMaterial(surfaceShader: surfaceShader, geometryModifier: geometryModifier, lightingModel: .lit)
        } catch {
            fatalError()
        }
        
        let mesh = MeshResource.generateSphere(radius: 0.5)
        let modelEntity = ModelEntity(mesh: mesh, materials: [customMaterial])

意外とシンプルにCustomMaterialにセットすればできるが、そもそもMetalのAPIが難しい。。
そこさえできればいろんなMaterialを自在に扱えそう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?