ARCore, artık sorunsuz bir kamera önizlemesi oluşturmaya yardımcı olan Elektronik Görüntü Sabitleme'yi (EIS) destekliyor. EIS, jiroskopla telefonun hareketlerini gözlemleyerek ve küçük titremelere karşı koyan kamera dokusunun sınırları dahilinde dengeleme homografi ağı uygulayarak sabitlemeyi sağlar. EIS yalnızca cihazın dikey yönünde desteklenir. Tüm yönler, ARCore'un 1.39.0 sürümünde desteklenecektir.
EIS desteği için sorgu oluşturun ve EIS'yi etkinleştirin
EIS'yi etkinleştirmek için oturumunuzu ImageStabilizationMode.EIS
kullanacak şekilde yapılandırın. Cihaz EIS özelliğini desteklemiyorsa bu durum, ARCore'dan bir istisna gönderilmesine neden olur.
Java
if (!session.isImageStabilizationModeSupported(Config.ImageStabilizationMode.EIS)) { return; } Config config = session.getConfig(); config.setImageStabilizationMode(Config.ImageStabilizationMode.EIS); session.configure(config);
Kotlin
if (!session.isImageStabilizationModeSupported(Config.ImageStabilizationMode.EIS)) return session.configure( session.config.apply { imageStabilizationMode = Config.ImageStabilizationMode.EIS } )
Koordinatları dönüştürme
EIS açıkken oluşturucunun, kamera arka planını oluştururken EIS dengelemesini içeren değiştirilmiş cihaz koordinatlarını ve eşleşen doku koordinatlarını kullanması gerekir. EIS tarafından düzeltilmiş koordinatları almak için Frame.transformCoordinates3d()
tuşlarını, giriş olarak OPENGL_NORMALIZED_DEVICE_COORDINATES
ve çıkış olarak EIS_NORMALIZED_DEVICE_COORDINATES
ile 3D cihaz koordinatlarını almak için, çıkış olarak EIS_TEXTURE_NORMALIZED
kullanarak 3D doku koordinatlarını alın. Şimdilik, Frame.transformCoordinates3d()
için desteklenen tek giriş koordinatı türü OPENGL_NORMALIZED_DEVICE_COORDINATES
.
Java
final FloatBuffer cameraTexCoords = ByteBuffer.allocateDirect(COORDS_BUFFER_SIZE_3D) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); final FloatBuffer screenCoords = ByteBuffer.allocateDirect(COORDS_BUFFER_SIZE_3D) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); final FloatBuffer NDC_QUAD_COORDS_BUFFER = ByteBuffer.allocateDirect(COORDS_BUFFER_SIZE_2D) .order(ByteOrder.nativeOrder()) .asFloatBuffer() .put( new float[] { /*0:*/ -1f, -1f, /*1:*/ +1f, -1f, /*2:*/ -1f, +1f, /*3:*/ +1f, +1f, }); final VertexBuffer screenCoordsVertexBuffer = new VertexBuffer(render, /* numberOfEntriesPerVertex= */ 3, null); final VertexBuffer cameraTexCoordsVertexBuffer = new VertexBuffer(render, /* numberOfEntriesPerVertex= */ 3, null); NDC_QUAD_COORDS_BUFFER.rewind(); frame.transformCoordinates3d( Coordinates2d.OPENGL_NORMALIZED_DEVICE_COORDINATES, NDC_QUAD_COORDS_BUFFER, Coordinates3d.EIS_NORMALIZED_DEVICE_COORDINATES, screenCoords); screenCoordsVertexBuffer.set(screenCoords); NDC_QUAD_COORDS_BUFFER.rewind(); frame.transformCoordinates3d( Coordinates2d.OPENGL_NORMALIZED_DEVICE_COORDINATES, NDC_QUAD_COORDS_BUFFER, Coordinates3d.EIS_TEXTURE_NORMALIZED, cameraTexCoords); cameraTexCoordsVertexBuffer.set(cameraTexCoords);
Kotlin
val COORDS_BUFFER_SIZE_2D = 2 * 4 * Float.SIZE_BYTES val COORDS_BUFFER_SIZE_3D = 3 * 4 * Float.SIZE_BYTES val cameraTexCoords = ByteBuffer.allocateDirect(COORDS_BUFFER_SIZE_3D) .order(ByteOrder.nativeOrder()) .asFloatBuffer() val screenCoords = ByteBuffer.allocateDirect(COORDS_BUFFER_SIZE_3D) .order(ByteOrder.nativeOrder()) .asFloatBuffer() val cameraTexCoordsVertexBuffer = VertexBuffer(render, /* numberOfEntriesPerVertex= */ 3, null) val screenCoordsVertexBuffer = VertexBuffer(render, /* numberOfEntriesPerVertex= */ 3, null) val NDC_QUAD_COORDS_BUFFER = ByteBuffer.allocateDirect(COORDS_BUFFER_SIZE_2D) .order(ByteOrder.nativeOrder()) .asFloatBuffer() .apply { put( floatArrayOf( /* 0: */ -1f, -1f, /* 1: */ +1f, -1f, /* 2: */ -1f, +1f, /* 3: */ +1f, +1f ) ) } NDC_QUAD_COORDS_BUFFER.rewind() frame.transformCoordinates3d( Coordinates2d.OPENGL_NORMALIZED_DEVICE_COORDINATES, NDC_QUAD_COORDS_BUFFER, Coordinates3d.EIS_NORMALIZED_DEVICE_COORDINATES, screenCoords ) screenCoordsVertexBuffer.set(screenCoords) NDC_QUAD_COORDS_BUFFER.rewind() frame.transformCoordinates3d( Coordinates2d.OPENGL_NORMALIZED_DEVICE_COORDINATES, NDC_QUAD_COORDS_BUFFER, Coordinates3d.EIS_TEXTURE_NORMALIZED, cameraTexCoords ) cameraTexCoordsVertexBuffer.set(cameraTexCoords)
EIS kapalı olduğunda, çıkış 3D koordinatları 2D eşdeğerlerine eşdeğer olur ve z değerleri hiçbir değişiklik üretmeyecek şekilde ayarlanır.
Gölgelendiricileri değiştir
Hakkında hesaplanan 3D koordinatları, arka plan oluşturma gölgelendiricilerine iletilmelidir. Köşe tamponları artık EIS ile 3D hale getirildi:
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;
}
Buna ek olarak, parça gölgelendiricinin perspektif düzeltmesi uygulaması gerekir:
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);
}
Daha fazla bilgi için hello_eis_kotlin örnek uygulamasına göz atın.