2017-09-24 34 views
5

Detaylı piksellere sahip desenler çiziyorum ve bunlar genellikle Moire efekti ile karşı karşıya. Gölgeleme konusunda iyi değilim ve bu sorunun gölgelendiriciler tarafından çözülüp çözülmeyeceğinden emin değilim. Gölgelendiricilerin temel, anlaşılabilir ve eksiksiz bir örneğini bulamadım. Öğretici web sitelerinin çoğu, üstbilgi dosyasının içerdiği bir programın ortasından başlamasını içerir.C++: Moire efektini openGL'den kaldırma

Bu, kodumun bir MWE'sidir. Moire etkisinin azaltılması veya ortadan kaldırılması mümkün mü? Eğer Multisampling kullanırsanız

#include <cmath> 
#include <vector> 

#ifdef __APPLE__ 
#include <GLUT/glut.h> 
#else 
#include <GL/glut.h> 
#endif 

const int w=640,h=480; 
float cam_angle=0.0f; 

void init() 
{ 
    GLfloat LightAmbient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; 
    GLfloat LightDiffuse[] = { 0.5f, 0.5f, 0.5f, 1.0f }; 
    GLfloat LightPosition[] = { 5.0f, 5.0f, -10.0f, 1.0f }; 

    glClearColor(0.0, 0.0, 0.0, 0.0); 
    glShadeModel(GL_SMOOTH); 
    glEnable(GL_DEPTH_TEST); 
    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); 
    glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); 
    glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); 
    glEnable(GL_LIGHT1); 
} 

void onDisplay() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective (90, float(w)/float(h), 0.01, 10000); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    const double pi=3.1415926; 
    double cam_x=2.0*cos(pi/4.0)*cos(cam_angle);; 
    double cam_y=2.0*sin(pi/4.0)*cos(cam_angle);; 
    double cam_z=2.0*sin(cam_angle); 
    gluLookAt(cam_x, cam_y, cam_z, 0, 0, 0, 0, 0, 1); 

    struct Point3D 
    { 
     double x, y, z; 
     unsigned char r, g, b, a=255; 
    }; 

    for(double r=0.5;r<=1.0;r+=0.03) 
    { 
     std::vector<Point3D> points; 
     for(int i=0;i<1000;i++) 
     { 
      double theta=double(i)/1000.0*pi*2.0; 
      Point3D p; 
      p.x=r*sin(theta); 
      p.y=r*cos(theta); 
      p.z=r; 
      p.r=128; 
      p.g=200; 
      p.b=50; 
      points.push_back(p); 
     } 
    // draw 
     glPushMatrix(); 
     glColor3ub(255,255,255); 
     glEnableClientState(GL_VERTEX_ARRAY); 
     glEnableClientState(GL_COLOR_ARRAY); 
     glVertexPointer(3, GL_DOUBLE, sizeof(Point3D), &points[0].x); 
     glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Point3D), &points[0].r); 
     // glPointSize(3.0); 
     glLineWidth(2.0); 
     glDrawArrays(GL_LINE_STRIP, 0, int(points.size())); 
     glDisableClientState(GL_VERTEX_ARRAY); 
     glDisableClientState(GL_COLOR_ARRAY); 
     glPopMatrix(); 
    } 

    glFlush(); 
    glutSwapBuffers(); 
} 

void Timer(int /*value*/) 
{ 
    cam_angle+=0.01f; 
    glutPostRedisplay(); 
    // 100 milliseconds 
    glutTimerFunc(100, Timer, 0); 
} 

int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitWindowSize (w, h); 
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); 
    glutInitWindowPosition (100, 100); 
    glutCreateWindow ("my window"); 
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); 
    glEnable(GL_BLEND); 

    init(); 
    glutDisplayFunc(onDisplay); 
    Timer(0); 
    glutMainLoop(); 

    return 0; 
} 

Moire effect

+0

(çift r = 0.5; R <= 1.0; R * = 0.03) Bu döngü 'de cevap' derleyici bağlı olarak, aynı sayıda çalıştırmak için garanti derleyici ayarlar, vb. Kayan nokta kesin değildir, bu yüzden 0,03 ila 0,5 ekleyerek bir yanlış sayı elde edilir ve hata her yinelemede birikir. Tam sayıyı, döngü noktası değil, kayan nokta olarak kullanın. – PaulMcKenzie

+0

@PaulMcKenzie. Önemli değil. Tüm senaryolar sonunda Moire etkisine yol açar. – ar2015

+1

Ekran çözünürlüğünün yakınında bir çözünürlük ve konum periyoduyla ayrıntılı piksel desenleri görüntülerseniz, yalnızca ince ayarlı içerikler (örn. Çizgiler çapraz DEĞİL, piksel bilge "atlama" eğimlerine sahip DEĞİLDİR.) Moire. Piksel hassasiyeti ve birkaç renk ile çalıştığı sürece sorunu çözemezsiniz. Çözüm (sizin için muhtemelen tatmin edici olmamakla birlikte) ya içeriği değiştirmek ya da anti-aliasing başlatmak ve bazen "keskin" ve "hassas" izlenim ile karşılaştırıldığında "yıkanmış" veya "bulanık" etkisi ile yaşamaktır. tek renkli pikseller. – Yunnosch

cevap

5

, sonuç önemli ölçüde geliştirilmiş olacak:

glutSetOption(GLUT_MULTISAMPLE, 8); 
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE | GLUT_MULTISAMPLE); 

GLUT_MULTISAMPLE olmadan:
enter image description here

GLUT_MULTISAMPLE ile:
enter image description here


bakınız GLUT + OpenGL multisampling anti aliasing (MSAA)