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;
}
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
@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
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