ייצוב תמונות המצלמה ב-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.