2017-09-24 25 views
5

Tôi vẽ các mẫu có pixel chi tiết và chúng thường phải đối mặt với hiệu ứng Moire. Tôi không giỏi trong việc tô bóng và tôi không chắc liệu vấn đề này có được giải quyết bởi shader hay không. Tôi đã không tìm thấy bất kỳ ví dụ cơ bản, dễ hiểu và đầy đủ về các trình đổ bóng. Hầu hết các trang web hướng dẫn bắt đầu một chương trình từ giữa bỏ tập tin tiêu đề bao gồm!C++: Loại bỏ hiệu ứng Moire khỏi openGL

Đây là MWE của mã của tôi. Có thể giảm thiểu hoặc loại bỏ hiệu ứng Moire khỏi nó?

#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

Vòng lặp này 'cho (r đôi = 0,5; r <= 1,0; r + = 0,03) 'không được bảo đảm để chạy cùng một số lần, tùy thuộc vào trình biên dịch, biên dịch cài đặt, vv Điểm nổi là không chính xác, do đó thêm 0,03 đến 0,5 sẽ mang lại một số không chính xác và lỗi tích lũy trên mỗi lần lặp. Sử dụng số nguyên làm bộ đếm vòng lặp, không phải là dấu phẩy động. – PaulMcKenzie

+0

@PaulMcKenzie. Không quan trọng. Tất cả các kịch bản cuối cùng dẫn đến hiệu ứng Moire. – ar2015

+1

Nếu bạn hiển thị các mẫu pixel chi tiết, với độ phân giải và vị trí gần độ phân giải màn hình, thì chỉ có nội dung được tinh chỉnh (ví dụ: KHÔNG có đường chéo, KHÔNG có pixel "bước" nghiêng ....) sẽ không có Moire. Bạn không thể giải quyết vấn đề miễn là bạn gắn bó với độ chính xác pixel và một vài màu. Giải pháp (mặc dù có thể không thỏa mãn với bạn) là thay đổi nội dung hoặc bắt đầu chống răng cưa và sống với hiệu ứng "bị cuốn trôi" hoặc "bị mờ", cả hai so với ấn tượng "sắc nét" và "chính xác" các pixel đơn màu. – Yunnosch

Trả lời

5

Nếu bạn sử dụng Multisampling, sau đó kết quả sẽ được cải thiện đáng kể:

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

mà không GLUT_MULTISAMPLE:
enter image description here

với GLUT_MULTISAMPLE:
enter image description here


Xem thêm câu trả lời cho GLUT + OpenGL multisampling anti aliasing (MSAA)

Các vấn đề liên quan