Özet
Altı sanatçı sanal gerçeklikte resim yapmaya, tasarlamaya ve heykeltırma yapmaya davet edildi. Bu, oturumlarını kaydetme, verileri dönüştürme ve kullanıcılara en iyi deneyimi sunma web tarayıcıları ile gerçek zamanlı olarak gönderin.
https://g.co/VirtualArtSessions
Ne büyük bir zaman ama! Tüketici olarak sanal gerçekliğin kullanıma sunulmasıyla birlikte yeni ve keşfedilmemiş olasılıklar keşfediliyor. Eğme Fırçası, bir HTC Vive'da sunulan Google ürünü ile üç karakter tanımlanabilir. Carousel Brush'ı ilk kez denediğimizde, hareket izleyen kumandalarla çizim yapma ve "insanların süper güçlere sahip bir oda" zamanınızı canlı tutmanızı sağlar. pek iyi bir deneyim yok. boş alanları çizmek gibi her şeyi
Google Veri Sanatları Ekibi’ne, Çevik’in geleceğine dair olmayanlara nasıl yardımcı olabileceğiyle ilgili daha fazla bilgi işleyeceğiz. Ekip bu amaca ulaşmak için bir heykeltıraş, bir çizer, bir sanat eseri Konsept tasarımcısı, moda sanatçısı, enstalasyon sanatçısı ve sokak sanatçıları kendi tarzında sanat eserleri ortaya koyuyor.
Sanal Gerçeklikte Çizimleri Kaydetme
Unity'de yerleşik olarak bulunan Carousel Brush yazılımının kendisi
başınızın konumunu izlemek için oda ölçeğinde VR kullanır (başa takılan ekran veya HMD)
olmasını sağlayın. Carousel Brush'ta oluşturulan poster
varsayılan olarak .tilt
dosyası biçiminde dışa aktarılır. Bu deneyimi web'e taşımak için
poster verilerinden daha fazlasına ihtiyacımız olduğunu fark ettik. Google'ın GeoX aracıyla
Carousel Brush ekibini eğerek geri alma/silme işlemlerini de dışa aktaracak şekilde değiştirmek için
bu şekilde, sanatçının başını ve elini saniyede 90 kez
konumlandırabilir.
eğerek çizim sırasında eğerek zamanla birden çok noktayı "vuruş" haline getirir. Açıklama kısmına burada bulabilirsiniz. Bu fırçaları çıkaran ve ham JSON biçiminde çıktı olarak veren eklentiler yazdık.
{
"metadata": {
"BrushIndex": [
"d229d335-c334-495a-a801-660ac8a87360"
]
},
"actions": [
{
"type": "STROKE",
"time": 12854,
"data": {
"id": 0,
"brush": 0,
"b_size": 0.081906750798225,
"color": [
0.69848710298538,
0.39136275649071,
0.211316883564
],
"points": [
[
{
"t": 12854,
"p": 0.25791856646538,
"pos": [
[
1.9832634925842,
17.915264129639,
8.6014995574951
],
[
-0.32014992833138,
0.82291424274445,
-0.41208130121231,
-0.22473378479481
]
]
}, ...many more points
]
]
}
}, ... many more actions
]
}
Yukarıdaki snippet, sketch JSON biçiminin biçimini belirtir.
Burada her fırça "STROKE" türüyle işlem olarak kaydedilir. Ek olarak kulağa inme hareketi yapan bir sanatçıyı, hata yaptığını ve bu yüzden "SİL"i kaydetmek çok önemliydi aynı işleve sahip silme veya geri alma işlemlerini yapabilirsiniz.
Her fırçayla ilgili temel bilgiler kaydedilir, böylece fırça türü, fırça boyutu, rengi büyük bir değişikliktir.
Son olarak, çizginin her bir tepe noktası kaydedilir. Bu köşe, konumun,
açı, süre ve kumandanın tetik basınç gücü (p
olarak belirtilir)
tıklayın).
Rotasyonun 4 bileşenli bir dördüncülük olduğuna dikkat edin. Bu adım daha sonra gimbal kilitlenmesini önlemek için fırça darbelerini oluşturuyoruz.
Sketches'i WebGL ile Oynatma
Çizimleri web tarayıcısında göstermek için THREE.js ve algoritmaya benzer bir geometri oluşturma Drop Brush'ın arka planda ne yaptığına bakın.
Drop Brush'ta kullanıcının eline göre gerçek zamanlı olarak üçgen şeritler oluşturulur varsa çizimin tamamı "bitti" gibi gösterime katılana kadar hale getirecektir. Bu sayede, gerçek zamanlı hesaplamanın büyük bir kısmını atlayıp daha hızlı Geometriyi gösterir.
Bir çizgideki her köşe çifti, bir yön vektörü (mavi çizgiler) üretir
her bir noktayı yukarıda gösterildiği gibi, aşağıdaki kod snippet'inde moveVector
) bağlayacağız.
Her noktanın yönü, yani yönü temsil eden dördün
kumandanın mevcut açısı. Üçgen bir şerit üretmek için her birinin
bu noktalar, yöne dik normaller üretir ve
kumandanın yönünü göreceksiniz.
Her çizgi için üçgen şeridi hesaplama işlemi neredeyse aynıdır kodu ile değiştirin:
const V_UP = new THREE.Vector3( 0, 1, 0 );
const V_FORWARD = new THREE.Vector3( 0, 0, 1 );
function computeSurfaceFrame( previousRight, moveVector, orientation ){
const pointerF = V_FORWARD.clone().applyQuaternion( orientation );
const pointerU = V_UP.clone().applyQuaternion( orientation );
const crossF = pointerF.clone().cross( moveVector );
const crossU = pointerU.clone().cross( moveVector );
const right1 = inDirectionOf( previousRight, crossF );
const right2 = inDirectionOf( previousRight, crossU );
right2.multiplyScalar( Math.abs( pointerF.dot( moveVector ) ) );
const newRight = ( right1.clone().add( right2 ) ).normalize();
const normal = moveVector.clone().cross( newRight );
return { newRight, normal };
}
function inDirectionOf( desired, v ){
return v.dot( desired ) >= 0 ? v.clone() : v.clone().multiplyScalar(-1);
}
Çizgi yönü ile yönünün kendi kendine birleştirilmesi (Matematiksel açıdan muğlak sonuçlar) türetilmiş birden fazla normal olabilir. çoğu zaman ”büyüme” görebilirsiniz.
Bir çizginin noktalarını tekrarlarken "tercih edilen sağ" değerini koruruz
vektörünü alıp computeSurfaceFrame()
fonksiyonuna geçirin. Bu işlev
Bu, bize, ATV'ye dayalı dörtlü şeritte dörtlü bir değer elde edebileceğimiz bir normal
çizginin yönü (son noktadan geçerli noktaya) ve
denetleyicinin yönü (dördün) Daha da önemlisi,
yeni bir "tercih edilen hak" vektörü kullanılır.
Her vuruşun kontrol noktalarına göre dörtlüler oluşturduktan sonra, tüm kulaçları köşelerini ara değer duruma getirerek dörtlü dolaştı.
function fuseQuads( lastVerts, nextVerts) {
const vTopPos = lastVerts[1].clone().add( nextVerts[0] ).multiplyScalar( 0.5
);
const vBottomPos = lastVerts[5].clone().add( nextVerts[2] ).multiplyScalar(
0.5 );
lastVerts[1].copy( vTopPos );
lastVerts[4].copy( vTopPos );
lastVerts[5].copy( vBottomPos );
nextVerts[0].copy( vTopPos );
nextVerts[2].copy( vBottomPos );
nextVerts[3].copy( vBottomPos );
}
Her dörtlüde de sonraki adım olarak üretilen UV'ler bulunur. Bazı fırçalar her çizginin olduğu izlenimini vermek için çeşitli çizgi farklı bir fırça darbesi gibi hissettim. Bu, _texture atlasing, _her fırça dokusunun mümkün olan tüm için de geçerlidir. Doğru doku, çizgi.
function updateUVsForSegment( quadVerts, quadUVs, quadLengths, useAtlas,
atlasIndex ) {
let fYStart = 0.0;
let fYEnd = 1.0;
if( useAtlas ){
const fYWidth = 1.0 / TEXTURES_IN_ATLAS;
fYStart = fYWidth * atlasIndex;
fYEnd = fYWidth * (atlasIndex + 1.0);
}
//get length of current segment
const totalLength = quadLengths.reduce( function( total, length ){
return total + length;
}, 0 );
//then, run back through the last segment and update our UVs
let currentLength = 0.0;
quadUVs.forEach( function( uvs, index ){
const segmentLength = quadLengths[ index ];
const fXStart = currentLength / totalLength;
const fXEnd = ( currentLength + segmentLength ) / totalLength;
currentLength += segmentLength;
uvs[ 0 ].set( fXStart, fYStart );
uvs[ 1 ].set( fXEnd, fYStart );
uvs[ 2 ].set( fXStart, fYEnd );
uvs[ 3 ].set( fXStart, fYEnd );
uvs[ 4 ].set( fXEnd, fYStart );
uvs[ 5 ].set( fXEnd, fYEnd );
});
}
Her çizimin çizgi sayısı sınırsız olduğu ve çizgilerin değiştirildikten sonra, çizgi geometrisini önceden hesaplar ve bunları tek bir ağa bölebilirsiniz. Her yeni fırça türü kendine ait olsa da bu da, çizim çağrılarımızı fırça başına bir taneye düşürüyor.
Sistemde stres testi yapmak için, her Sprint'i doldurmak üzere 20 dakika süren bir bir alan oluşturmaya çalıştık. Ortaya çıkan skeç WebGL'de 60 fps.
Bir darbenin orijinal köşelerinin her biri zaman içerdiğinden, kolayca oynatabilirsiniz. Kare başına vuruş sayısını yeniden hesaplamak, Bunun yerine, yükleme sırasında tüm çizimi önceden hesapladık ve yardımcı olacak bir uygulamadır.
Dörtlüyü gizlemek, köşelerini 0,0,0 noktasına daraltmak anlamına geliyordu. ne zaman ortaya çıkacağına karar verdiğimizde, köşeleri tekrar yerlerine yerleştirin.
İyileştirme gereken bir alan da köşe noktalarının tamamen GPU üzerinde değiştirilmesidir. gölgelendiriciler. Mevcut uygulama, bunları tepe noktasından döngü yaparak yerleştiriyor diziyi mevcut zaman damgasından çıkarır, hangi köşelerin açıklanması gerektiğini kontrol eder ve sonra geometriyi güncelleyin. Bu da CPU üzerinde çok fazla yük oluşturur. pervanenizin dönmesini sağlar ve pil ömrünün boşa harcanır.
Sanatçıları Kaydetme
Eskizlerin yeterli olmayacağını düşündük. Demoda, her fırça darbesini çiziyor.
Sanatçıların fotoğrafını çekmek için Microsoft Kinect kameralardan yararlanarak sanatçılarının verileri kadrajda görebilirsiniz. Bu sayede ekip üyelerinizin üç boyutlu şekillerle birlikte gösterilir.
Sanatçının vücudu kendini kapattığı için burada paylaşılanları görmemiz odanın iki karşı tarafında da çift Kinect sistemi kullandık ortada olacak şekilde düşünün.
Derinlik bilgilerine ek olarak, görüntülerin renk bilgilerini de kameralarla rahatça sergileyebilirsiniz. Mükemmel hizmeti kullandık Kalibre etmek ve birleştirmek için DepthKit yazılımı renkli kameralardan alınan görüntülere yer verir. Kinect Ancak DSLR'leri kullanmayı tercih ettik çünkü pozlama ayarlarını yapabilir, şık ve lüks lensler kullanabilir ve yüksek çözünürlüklü kayıt yapabilirsiniz.
Görüntüleri kaydetmek için sanatçı HTC Vive'ın bulunduğu özel bir oda oluşturduk. ve kamera. Tüm yüzeyler kızılötesi emici malzemeyle kaplandı bize daha temiz bir nokta bulutu (duvarlara örtülmüş örtü, yivli kauçuk) sağlayacak Döşeme). Materyalin puan bulutunda gösterilmesi ihtimali siyah malzeme seçeneğini tercih ettik. Bu nedenle görsel bu da beyazdı.
Ortaya çıkan video kayıtları bize bir parçacığı yansıtmak için yeterli bilgi sağladı bahsedeceğim. Belgenin altında bazı ek araçlar openFrameworks kullanarak görüntülerin temizlenmesi için zemini, duvarları ve tavanı çıkarmak,
Sanatçılara göstermenin yanı sıra, HMD ve 3D olarak da çalışır. Bu, hem HMD'nin hem bu ülkede net bir şekilde görülebildiği gibi (HTC Vive'ın yansıtıcı lensleri Kinect'in IR okumaları), parçacığın hata ayıklaması için bize temas noktaları sağladı çıkarımda bulunur ve videoları skeçle hizalar.
Bu, Drop Brush'a dosyanın içeriğini temizleyen özel bir eklenti ve denetleyicilerin konumunu görüntüler. Carousel Brush 90 fps'de çalıştığından tonlarca veri akışı gerçekleştirildi ve bir çizimin giriş verisi 20 MB'ın üzerindeydi sahip olmayabilir. Bu tekniği, kaydedilmeyen etkinlikleri yakalamak için de kullandık veya sanatçının bir seçenek belirlemesi gibi tipik widget'ın konumuna ve araçlar paneline gidin.
Topladığımız 4 TB'lık verinin işlenmesinde en büyük zorluklardan biri tüm farklı görsel/veri kaynaklarını uyumlu hale getirme. Bir DSLR kameradan alınan her video piksellerin hizalanması için ilgili Kinect ile hem de zamandır. Daha sonra, bu iki kamera düzeneğindeki görüntülerin birbirleriyle uyumlu bir şekilde çalışmak için kullanır. Sonra 3D reklamlarımızı kendi çiziminden alınan verilerle sanatçıyı otomatikleştirir. Bora Tarayıcı tabanlı araçlarına sahip olursunuz. Bu araçları kendiniz de deneyebilirsiniz burada
Veriler hizalandıktan sonra, verileri işlemek için NodeJS'de yazılan bazı komut dosyaları kullandık tümü kırpılmış ve biçiminde bir video dosyası ile JSON dosyası dizisi çıktısı senkronize edildi. Dosya boyutunu küçültmek için üç şey yaptık. İlk olarak, her bir kayan nokta sayısının doğruluğu, maksimum 3 olacak şekilde değerini belirlemektir. İkinci olarak, puan sayısını üçte bir 30 fps'de oynatıldı ve istemci tarafındaki konumların ara değeri hesaplandı. Son olarak, bu nedenle, anahtar/değer çiftleriyle düz JSON kullanmak yerine, HMD ve denetleyicilerin konumlandırılması ve döndürülmesi için oluşturulmuştur. Bu, dosyayı kesip 3 MB'tan küçük bir boyuta ulaştı. Bu, kablo üzerinden teslim edilebilir.
Videonun kendisi tarafından okunan bir HTML5 video öğesi olarak sunulduğundan WebGL dokusunun parçacıklara dönüşmesi, videonun arka planın içinde gizli bir şekilde oynatılması arka plan. Gölgelendirici, derinlik görüntülerindeki renkleri arka plandaki konumlara dönüştürür. 3D alan. James George mükemmel bir örnek paylaştı. nasıl yapabileceğinizi açıklayacağım.
iOS'te satır içi video oynatmayla ilgili kısıtlamalar vardır. Bu kısıtlamaları önlemek için kullanıcıların otomatik olarak oynatılan web video reklamları tarafından rahatsız edilmesini önler. Önceki videoda diğer geçici çözümlere benzer Web'i tıklayın. Bu işlem, video karesini tuvale serpiştirip video sarma süresini manuel olarak güncelleyin. bir saniye.
videoElement.addEventListener( 'timeupdate', function(){
videoCanvas.paintFrame( videoElement );
});
function loopCanvas(){
if( videoElement.readyState === videoElement.HAVE\_ENOUGH\_DATA ){
const time = Date.now();
const elapsed = ( time - lastTime ) / 1000;
if( videoState.playing && elapsed >= ( 1 / 30 ) ){
videoElement.currentTime = videoElement.currentTime + elapsed;
lastTime = time;
}
}
}
frameLoop.add( loopCanvas );
Yaklaşımımızın, iOS'i önemli ölçüde düşürmenin talihsiz bir yan etkisi vardı piksel arabelleğinin videodan tuvale kopyalanması çok yüksek olduğundan CPU'yu yoğun şekilde kullanır. Bu sorunu aşmak için küçük boyutlu versiyonları iPhone 6'da en az 30 fps'ye izin veren videolar.
Sonuç
2016 itibarıyla VR yazılımı geliştirme konusunda genel fikir birliği, geometrileri ve gölgelendiricileri basit hale getirerek HMD'de 90+ fps'de çalıştırabilmenizi sağlar. Bu tekniklerin kullanıldığından, WebGL demoları için gerçekten çok iyi bir hedef olduğu ortaya çıktı. çok güzel bir şekilde ayarlayabilirsiniz.
Karmaşık 3D örgüler görüntüleyen web tarayıcıları Bu, VR çalışmasının çapraz polenasyonunun ve web tamamen mümkün.