ייצוב תמונות המצלמה ב-Android NDK (C)

ARCore תומך עכשיו בייצוב תמונה אלקטרוני (EIS), שעוזר ליצור תצוגה מקדימה חלקה של המצלמה. טכנולוגיית EIS משיגה ייצוב על ידי צפייה בתנועת הטלפון באמצעות ג'יירו והחלה של רשת הומוגרפיה פיצוי בתוך גבולות מרקם המצלמה שמודדים את הרעידות הקלות. EIS נתמך רק בפריסה לאורך של המכשיר. כל הכיוונים ייתמכו בגרסה 1.39.0 של ARCore.

שאילתה לתמיכה ב-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 כפלט לקבלת קואורדינטות מכשיר בתלת-ממד וב-AR_COORDINATES_3D_EIS_TEXTURE_NORMALIZED כפלט לקבלת קואורדינטות של טקסטורה תלת-ממדית. נכון לעכשיו, הסוג היחיד של קואורדינטות הקלט הנתמך עבור 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 כבוי, הקואורדינטות התלת-ממדיות של הפלט שוות ערך לקואורדינטות הדו-ממדיות שלהן, כאשר ערכי z מוגדרים כך שלא יניבו שינוי.

שינוי של תוכנות הצללה

יש להעביר את הקואורדינטות התלת-ממדיות שמחושבות עליהן אל תוכנות הצללה לעיבוד רקע. חוצץ הקודקודים הוא עכשיו תלת-ממדי עם EIS:

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.