Ich werde Ihnen zeigen, wie Sie mit ARKit und Metal Ihre Hände schütteln können.
Das Finish sieht so aus.
Verwenden Sie ARKits People Occlusion.
People Occlusion bietet Ihnen eine humanoide Maskentextur, die das Masken- und Kamerabild gleichzeitig verzerrt, um ein verzerrtes zusammengesetztes Bild zu erhalten. Es fühlt sich an, als würde man verzerrt herausschneiden.
Sie können ein Bild wie dieses erhalten (es ist aus Gründen der Klarheit stärker verzerrt als das Video).
Sie können das obige Video erstellen, indem Sie das verzerrte Handbild und das Originalbild überlagern.
** 1. Holen Sie sich Apples offizielles Muster **
Apples offizielles Beispiel beschreibt den Prozess des Erhaltens einer humanoiden Maskentextur unter Verwendung von People Occlusion, daher werde ich darauf basierend schreiben.
Effecting People Occlusion in Custom Renderers
** 2. Übergeben Sie die verstrichene Zeit an den Shader **
Um es schwanken zu lassen, ist es notwendig, der Transformationsformel die verstrichene Zeit zu geben.
Deklarieren Sie die Struktur, die an den Shader übergeben werden soll.
Renderer.swift
struct Uniforms {
var time: Float = 0
}
Als nächstes deklarieren Sie die Variablen für die Verwaltung der verstrichenen Zeit und der Startzeit.
Renderer.swift
class Renderer {
var uniforms = Uniforms()
private var startDate: Date = Date()
var uniformsBuffer: MTLBuffer! //Puffer, der an den Shader übergeben werden soll
Dann übergeben wir in der Methode composImagesWithEncoder, die die Informationen an den Shader weitergibt, die verstrichene Zeit zusammen.
Renderer.swift
uniforms.time = time
uniformsBuffer = device.makeBuffer(bytes: &uniforms, length: MemoryLayout<Uniforms>.stride, options: [])
uniformsBuffer.label = "UniformsBuffer"
Bereiten Sie auf der Shader-Seite dieselbe Struktur vor wie auf der Swift-Seite, und erhalten Sie sie als Argument für die Funktion. Der Argumentname ist myUniforms.
Shaders.metal
struct Uniforms {
float time;
};
fragment half4 compositeImageFragmentShader(CompositeColorInOut in [[ stage_in ]],
texture2d<float, access::sample> capturedImageTextureY [[ texture(0) ]],
texture2d<float, access::sample> capturedImageTextureCbCr [[ texture(1) ]],
texture2d<float, access::sample> sceneColorTexture [[ texture(2) ]],
depth2d<float, access::sample> sceneDepthTexture [[ texture(3) ]],
texture2d<float, access::sample> alphaTexture [[ texture(4) ]],
texture2d<float, access::sample> dilatedDepthTexture [[ texture(5) ]],
constant SharedUniforms &uniforms [[ buffer(kBufferIndexSharedUniforms) ]],
constant Uniforms &myUniforms [[buffer(kBufferIndexMyUniforms)]])
{
** 3. Schreibe den Shader neu **
Schreiben Sie im offiziellen Beispiel die CompositeImageFragmentShader-Funktion von Shaders.metal wie folgt um.
Shaders.metal
@@ -219,8 +397,9 @@ fragment half4 compositeImageFragmentShader(CompositeColorInOut in [[ stage_in ]
half4 sceneColor = half4(sceneColorTexture.sample(s, sceneTexCoord));
float sceneDepth = sceneDepthTexture.sample(s, sceneTexCoord);
+ float2 modifier = float2(sin(cameraTexCoord.y + myUniforms.time*5)*0.2, 0); //Transformationsformel
half4 cameraColor = half4(rgb);
- half alpha = half(alphaTexture.sample(s, cameraTexCoord).r);
+ half alpha = half(alphaTexture.sample(s, cameraTexCoord + modifier).r); //Transformiere die humanoide Maske
half showOccluder = 1.0;
@@ -233,8 +412,11 @@ fragment half4 compositeImageFragmentShader(CompositeColorInOut in [[ stage_in ]
showOccluder = (half)step(dilatedDepth, sceneDepth); // forwardZ case
}
+ float2 displacedUV = sceneTexCoord + modifier; //Transformiere das Bild
- half4 occluderResult = mix(sceneColor, cameraColor, alpha);
+ half4 displacedCol = half4(sceneColorTexture.sample(s, displacedUV)); //Aufnahme eines deformierten humanoiden Bildes
+ half4 occluderResult = mix(sceneColor, displacedCol, alpha); //Kombinieren Sie das deformierte Bild mit dem Originalbild
half4 mattingResult = mix(sceneColor, occluderResult, showOccluder);
return mattingResult;
}
Hier kommt es darauf an.
Shaders.metal
float2 modifier = float2(sin(cameraTexCoord.y + myUniforms.time*5)*0.2, 0); //Transformationsformel
Die y-Koordinate des Eingabebildes plus die verstrichene Zeit wird der sin-Funktion gegeben, und diese wird dem Modifikator zugewiesen. Der Modifikator ist eine Variable, die der Kamera oder der humanoiden Maske hinzugefügt werden soll. Dieses Mal ist die Formel nur in x enthalten, sodass nur die Richtung der x-Achse schwankt.
Da das tatsächliche Video in vertikaler Richtung schwankt, widerspricht es der obigen Formel. Dies liegt jedoch daran, dass das im Querformat aufgenommene iPhone vertikal mit einer Bildbearbeitungssoftware konvertiert wurde.
Ich habe in diesem Artikel über die Transformation der Figur geschrieben, siehe auch hier.
So transformieren Sie ARKit- und SceneKit-Figuren mit Metal Shader
Ich habe auch ein Video auf Youtube hochgeladen. Fertiges Video (Youtube)
Hinweis veröffentlicht regelmäßig Informationen zur iOS-Entwicklung. Folgen Sie uns daher. https://note.com/tokyoyoshida
Wir senden einfache Tipps auf Twitter. https://twitter.com/jugemjugemjugem
Recommended Posts