Rysuję desenie, które mają szczegółowe piksele i często napotykają efekt Moire. Nie jestem dobry w cieniowaniu i nie jestem pewien, czy ten problem zostanie rozwiązany przez shadery. Nie znalazłem żadnego podstawowego, zrozumiałego i pełnego przykładu shaderów. Większość tutorialowych stron internetowych rozpoczyna program od środka, pomijając plik nagłówkowy!C++: Usuwanie efektu Moire z biblioteki OpenGL
To jest MWE mojego kodu. Czy możliwe jest złagodzenie lub usunięcie efektu Moire z niego?
#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;
}
tej pętli 'dla (podwójne r = 0,5; R <= 1,0; R + = 0.03)' nie ma gwarancji uruchomienia taką samą ilość czasu, w zależności od kompilatora kompilatora ustawienia itp. Punkt zmienny nie jest dokładny, dlatego dodanie od 0,03 do 0,5 da niedokładną liczbę, a błąd narasta w każdej iteracji. Użyj liczby całkowitej jako liczników pętli, a nie zmiennoprzecinkowych. – PaulMcKenzie
@ PaulMcKenzie. Nie ważne. Wszystkie scenariusze ostatecznie prowadzą do efektu Moire. – ar2015
Jeśli wyświetlasz szczegółowe wzorce pikseli, o rozdzielczości i okresie lokalizacji w pobliżu rozdzielczości wyświetlania, wtedy tylko precyzyjnie dostrojona treść (np. NIE mające linii przecinających się, NIE posiadająca pikselowych "kroków" nachylenia ...) będzie wolna od Mora. Nie możesz rozwiązać problemu tak długo, jak trzymasz się precyzji pikseli i kilku kolorów. Rozwiązaniem (choć być może nie satysfakcjonującym) jest zmiana zawartości lub uruchomienie wygładzania i używanie efektu "wymycia" lub "zamazania", zarówno w porównaniu z wrażeniem "ostrym", jak i "precyzyjnym". pojedynczych kolorowych pikseli. – Yunnosch