OpenGL, çakışan birden çok nesnenin ana hatlarını alır


10

Sadece c ++ 'da opengl ile yapılan oyunum için bir fikrim vardı: Oyuncu bir şey kazandığında birden fazla örtüşen nesne üzerinde büyük bir taslak (5-6 piksel) istiyorum.

Ben en iyi yol şablon tampon kullanmak olduğunu düşündüm ama şablon tampon bazı ekran dışı render yapmaya çalışıyorum ve bu yüzden olasılıkla herhangi bir sonuç elde edemez birkaç saat olduğunu düşündüm. başka teknikler de var!

Almak istediğim bu:

resim açıklamasını buraya girin

Herhangi bir fikir?


Kenar algılama filtresi kullanın, kenarları kalın renkli çizgilerle doldurun, ardından şekillerin işlenen görüntülerini çıkarın ve renkli çizgiler katmanının üstüne bindirin?
Shotgun Ninja

kenar algılayıcı filtre ile ne demek istiyorsun? bir gölgelendirici mi? görüntü işleme filtresi? opencv gibi (dokuya renderleme, dokuya filtre uygulama, değiştirilen dokuyu geri itme)?
nkint

Hiç bir fikrim yok; Başlamak için 3d render konusunda çok bilgili değilim.
Shotgun Ninja

böyle bir şablon tamponu örneği var mı? Ben şablon tampon kullanarak daha temiz bir yol olacağını düşünüyorum ama ben herhangi bir şablon tampon iş yapmak mümkün değil
nkint

Yanıtlar:


4
  1. Şablon arabelleğini etkinleştirin ve temizleyin.
  2. Şablon arabelleğini ayarlayarak nesneleri çizin. Nesneler yarı saydam olabilir.
  3. Şimdi şablon modunu yalnızca şablonun ayarlanmadığı pikselleri yazacak şekilde ayarlayın.
  4. Ve her nesneyi, hafifçe ölçeklendirilmiş, istenen kenarlık renginde ve dokular olmadan tekrar çizin.
  5. Şablon arabelleğini devre dışı bırakın.

İşte benim çalıştığım bazı webGL şablon kodundan uyarlanmış kod:

// drawing will set stencil stencil
    gl.enable(gl.STENCIL_TEST);
    gl.stencilFunc(gl.ALWAYS,1,1);
    gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
    gl.stencilMask(1);
    gl.clearStencil(0);
    gl.clear(gl.STENCIL_BUFFER_BIT);
// draw objects
for(var object in objects)
  objects[object].draw();
// set stencil mode to only draw those not previous drawn
    gl.stencilFunc(gl.EQUAL,0,1);
    gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
    gl.stencilMask(0x00);
// draw object halo
for(var object in objects)
  objects[object].drawHalo(1.1,red); // each mesh should be individually scaled e.g. by 1.1
// done
    gl.disable(gl.STENCIL_TEST);

Sanırım bu yaklaşımı RTS oyunlarında seçilen birimlerin etrafında haleler çizmek için kullandım, ancak uzun zaman önceydi ve herhangi bir gotchas ve tüm nüanslar olup olmadığını hatırlamıyorum.


böyle bir şablon tamponu örneği var mı? Ben şablon tampon kullanarak daha temiz bir yol olacağını düşünüyorum ama ben herhangi bir şablon tampon iş yapmak mümkün değil
nkint

7
Nesneleri hafifçe ölçeklendirmenin düzgün bir çizgi kalınlığına neden olmayacağını unutmayın. Daha uzak kenarlar daha ince olacaktır. Nesneleri ölçeklerken bunu hesaba katarsanız, mesafeye uzanan uzun nesneler eşit olmayan bir kalınlığa sahip olacaktır. Çizgileri güzel ve eşit hale getirmek için bu efektte biraz daha fazlası var.
Sean Middleditch

2
Nesneleri basitçe ölçeklemekten daha iyi, her bir tepe noktasını normal boyunca kısa bir mesafede dengeleyen bir tepe gölgelendirici yazmaktır. Pürüzsüz nesneler için oldukça iyi çalışır, ancak sert kenarlarda çatlaklar oluşturur. Mesh'i her yerde düzeltilmiş alternatif bir dizi normal ile oluşturmayı deneyebilir ve bunun sizi nereye götürdüğünü görebilirsiniz.
Nathan Reed

2

Bir nesne grubunun örtüşen bir nesne koleksiyonu olduğu tüm nesne gruplarını bularak başlayın. Standart çarpışma algılama işi yapmalıdır. Her gruba benzersiz bir renk atayın. Herhangi bir renk olurdu.

Grup rengini kullanarak tüm nesnelerinizi düz renkler olarak bir dokuya dönüştürün.

Oluşturma hedefiyle aynı boyutlara sahip yeni bir anahat dokusu oluşturun. Oluşturma hedefinin her bir metnini tarayın ve çevresindeki herhangi bir metinden farklı bir renk olup olmadığını belirleyin. Öyleyse, anahat dokusundaki karşılık gelen texeli istediğiniz çizgi rengiyle değiştirin.

Son olarak, bu anahat dokusunu alın ve ekranda çizmek istediğiniz görüntünün üzerine getirin (elbette bunu bir parça gölgelendiricideki kenar algılama ile aynı anda yapabilir ve ilkinde kenar dokusu oluşturmaktan kaçınabilirsiniz. yer).

Bu adımı cpu üzerinde, oluşturma hedefinin metinlerinden geçmek için bir for döngüsü kullanarak gerçekleştirirseniz, bu oldukça yavaş olacaktır, ancak bazı durumlarda test etmek ve hatta kullanmak için yeterince iyi olacaktır. Bunu gerçek zamanlı olarak kullanmak için, bunu bir gölgelendiricide kullanmak en iyisidir.

Bu kenar algılamasını yapmak için bir parça gölgelendirici şöyle görünebilir;

precision mediump float;

uniform sampler2D s_texture;

varying vec2 v_texCoord;

void main()
{
    gl_FragColor = vec4(0.0);

    vec4 baseColor = texture2D(s_texture, v_texCoord);
    gl_FragColor += baseColor - texture2D(s_texture, top);
    gl_FragColor += baseColor - texture2D(s_texture, topRight);
    gl_FragColor += baseColor - texture2D(s_texture, right);
    gl_FragColor += baseColor - texture2D(s_texture, bottomRight);
    gl_FragColor += baseColor - texture2D(s_texture, bottom);
    gl_FragColor += baseColor - texture2D(s_texture, bottomLeft);
    gl_FragColor += baseColor - texture2D(s_texture, left);
    gl_FragColor += baseColor - texture2D(s_texture, topLeft);
}

Texture2D aramasındaki ikinci değer v_texCoord'a göre 2d koordinattır. Bunu, ilk oluşturma hedefini tam ekran dörtlü doku olarak oluşturarak uygularsınız. Bu, guassian blur gibi tam ekran bulanıklaştırma efektlerini nasıl uygulayacağınıza benzer.

İlk oluşturma hedefini düz renklerle kullanmanın nedeni, üst üste binen farklı nesneler arasında algılanan kenar olmadığından emin olmaktır. Ekran görüntüsünde sadece kenar algılaması yaptıysanız, büyük olasılıkla örtüşmelerdeki kenarları da algıladığını görürsünüz (nesnelerin farklı renklere / dokulara / aydınlatmaya sahip olduğu varsayılarak).


2
üzgünüm ama "Her bir texeli tara" ile ne demek istiyorsun? her piksel olsa bir for döngüsü? CPU'da mı? yani bir şeye benziyor: bir dokuya düz renkle renderleme, görüntüyü cpu'ya aktarma, tarama yapma, tekrar dokuya koyma? veya gölgelendiricide mi?
nkint

Tercihen, bir işlem sonrası bulanıklaştırma efekti yapmaya benzer şekilde, oluşturma hedefini doku olarak kullanarak tam ekran dörtlü oluşturarak bir gölgelendiricide yapın, ancak yalnızca görmek için önce bir for döngüsü ile cpu üzerinde çalıştırabilirsiniz. yeterince iyi çalışıyorsa.
OriginalDaemon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.