ARCore で電子式手ぶれ補正(EIS)がサポートされるようになりました。これにより、スムーズなカメラ プレビューを生成できます。EIS は、ジャイロスコープを使用してスマートフォンの動きを確認し、カメラ テクスチャの境界内で補正ホモグラフィ メッシュを適用することで、軽微な手ぶれを補正します。EIS は、デバイスの縦向きでのみサポートされます。すべての向きは、ARCore の 1.39.0 リリースでサポートされます。
EIS サポートをクエリして EIS を有効にする
EIS を有効にするには、AR_IMAGE_STABILIZATION_MODE_EIS
を使用するようにセッションを構成します。デバイスが EIS 機能をサポートしていない場合、ARCore から例外がスローされます。
int enableEis = 0; ArSession_isImageStabilizationModeSupported( ar_session, AR_IMAGE_STABILIZATION_MODE_EIS, &enableEis); if (!enableEis) { return; } // Create a session config. ArConfig* ar_config = NULL; ArConfig_create(ar_session, &ar_config); // Enable Electronic Image Stabilization. ArConfig_setImageStabilizationMode(ar_session, ar_config, AR_IMAGE_STABILIZATION_MODE_EIS); CHECK(ArSession_configure(ar_session, ar_config) == AR_SUCCESS); // Release config resources. ArConfig_destroy(ar_config);
座標を変換する
EIS がオンの場合、レンダラはカメラの背景をレンダリングするときに、変更されたデバイス座標と、EIS 補正を組み込んだ一致するテクスチャ座標を使用する必要があります。EIS 補正座標を取得するには、ArFrame_transformCoordinates3d
を使用します。入力として AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES
を使用し、出力として AR_COORDINATES_3D_EIS_NORMALIZED_DEVICE_COORDINATES
を使用して 3D デバイス座標を取得し、出力として AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED
を使用して 3D テクスチャ座標を取得します。現時点では、ArFrame_transformCoordinates3d
でサポートされている入力座標タイプは AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES
のみです。
int kNumVertices = 4; // Positions of the quad vertices in clip space (X, Y). const GLfloat kVertices[] = { -1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f, }; float transformed_vertices_[4 * 3]; float transformed_uvs_[4 * 3]; ArFrame_transformCoordinates3d( session, frame, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES, kNumVertices, kVertices, AR_COORDINATES_3D_EIS_NORMALIZED_DEVICE_COORDINATES, transformed_vertices_); ArFrame_transformCoordinates3d( session, frame, AR_COORDINATES_2D_OPENGL_NORMALIZED_DEVICE_COORDINATES, kNumVertices, kVertices, AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED, transformed_uvs_); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_EXTERNAL_OES, camera_texture_id_); glUseProgram(camera_program_); glUniform1i(camera_texture_uniform_, 0); // Set the vertex positions and texture coordinates. glVertexAttribPointer(camera_position_attrib_, 3, GL_FLOAT, false, 0, transformed_vertices_); glVertexAttribPointer(camera_tex_coord_attrib_, 3, GL_FLOAT, false, 0, transformed_uvs_); glEnableVertexAttribArray(camera_position_attrib_); glEnableVertexAttribArray(camera_tex_coord_attrib_);
EIS がオフの場合、出力 3D 座標は 2D 座標と同じで、z 値は変化しないように設定されます。
シェーダーを変更する
計算された 3D 座標は、バックグラウンド レンダリング シェーダーに渡す必要があります。頂点バッファは EIS で 3D になりました。
layout(location = 0) in vec4 a_Position;
layout(location = 1) in vec3 a_CameraTexCoord;
out vec3 v_CameraTexCoord;
void main() {
gl_Position = a_Position;
v_CameraTexCoord = a_CameraTexCoord;
}
また、フラグメント シェーダーでパースペクティブ補正を適用する必要があります。
precision mediump float;
uniform samplerExternalOES u_CameraColorTexture;
in vec3 v_CameraTexCoord;
layout(location = 0) out vec4 o_FragColor;
void main() {
vec3 tc = (v_CameraTexCoord / v_CameraTexCoord.z);
o_FragColor = texture(u_CameraColorTexture, tc.xy);
}
詳しくは、hello_eis_kotlin サンプルアプリをご覧ください。