Свет и тень не работают в opengl и переполнении стека

Я создаю солнечную систему и продолжаю сталкиваться с проблемами освещения. Первая проблема состоит в том, что луна не отбрасывает тени на землю, а земля не отбрасывает тени на луну.
Другая проблема заключается в том, что свет, сияющий на землю и луну, исходит не от моего солнца, а от центральной точки орбиты. Я добавил красные линии на картинке ниже, чтобы показать, что я имею в виду.

Картинка ниже должна иллюстрировать мои две проблемы.

введите описание изображения здесь

Вот код, который имеет дело с огнями и планетами.

glDisable(GL_LIGHTING);
drawCircle(800, 720, 1, 50);
//SUN
//Picture location, major radius, minor radius, major orbit, minor orbit, angle
Planet Sun ("/home/rodrtu/Desktop/SolarSystem/images/Sun.png",
100, 99, 200.0, 0.0, 0.0);
double sunOrbS = 0;
double sunRotS = rotatSpeed/10;
cout << sunRotS << " Sun Rotation" << endl;

//orbit speed, rotation speed, moon reference coordinates (Parent planet's major and minor Axis)
Sun.displayPlanet(sunOrbS, sunRotS, 0.0, 0.0);

//Orbit path
//EARTHGLfloat light_diffuse[] = { 1.5, 1.5, 1.5, 1.5 };
GLfloat pos[] = { 0.0, 0.0, 0.0, 200.0 };
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_POSITION, pos);

Planet Earth ("/home/rodrtu/Desktop/SolarSystem/images/EarthTopography.png",
50, 49, 500.0, 450.0, 23.5);
double eaOrbS = orbitSpeed;
double eaRotS = rotatSpeed*3;

Earth.displayPlanet(eaOrbS, eaRotS, 0.0, 0.0);//EARTH'S MOON
Planet Moon ("/home/rodrtu/Desktop/SolarSystem/images/moonTest.png",
25, 23, 100.0, 100.0, 15);
double moOrbS = rotatSpeed*4;
double moRotS = eaOrbS;

Moon.displayPlanet(moOrbS, moRotS, Earth.getMajorAxis(), Earth.getMinorAxis());orbitSpeed+=.9;
if (orbitSpeed > 359.0)
orbitSpeed = 0.0;rotatSpeed+=2.0;
if (rotatSpeed > 7190.0)
rotatSpeed = 0.0;

Эта следующая функция используется для определения орбитальной координаты и местоположения каждой планеты.

void Planet::setOrbit(double orbitSpeed, double rotationSpeed,
double moonOrbitX, double moonOrbitY)
{
majorAxis = orbitSemiMajor * cos(orbitSpeed / 180.0 * Math::Constants<double>::pi);
minorAxis = orbitSemiMinor * sin(orbitSpeed / 180.0 * Math::Constants<double>::pi);

glTranslate(majorAxis+moonOrbitX, minorAxis+moonOrbitY, 0.0);
glRotatef(orbitAngle, 0.0, 1.0, 1.0);
glRotatef(rotationSpeed, 0.0, 0.0, 1.0);

}

void Planet::displayPlanet(double orbitSpeed,double rotationSpeed,
double moonOrbitX, double moonOrbitY)
{
GLuint surf;
Images::RGBImage surfaceImage;
surfaceImage=Images::readImageFile(texture);
glEnable(GL_TEXTURE_2D);
glGenTextures(0, &surf);
glBindTexture(GL_TEXTURE_2D, surf);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
surfaceImage.glTexImage2D(GL_TEXTURE_2D,0,GL_RGB);

glPushMatrix();
setOrbit(orbitSpeed,rotationSpeed, moonOrbitX, moonOrbitY);
drawSolidPlanet(equatRadius, polarRadius, 1, 40, 40);
glPopMatrix();

}

Что я делаю неправильно? Я прочитал о компоненте w GL_POSITION и изменил свою позицию на 200 (там, где солнце центрировано), но источник света все еще исходит из центра орбиты.

1

Решение

Чтобы правильно ответить на вопрос о светлой позиции ..

[X, Y, Z, W] называется однородными координатами

Координата [X, Y, Z, W] в однородном пространстве будет [X/W, Y/W, Z/W] в трехмерном пространстве.

Теперь рассмотрим следующие значения W:

  • W=1.0 : [1.0, 1.0, 1.0, 1.0] является [1.0, 1.0, 1.0] в 3D месте.
  • W=0.1 : [1.0, 1.0, 1.0, 0.1] является [10.0, 10.0, 10.0] в 3D месте.
  • W=0.001 : [1.0, 1.0, 1.0, 0.001] является [1000.0, 1000.0, 1000.0] в 3D месте.

Когда мы продолжаем двигаться к W=0 [X/W, Y/W, Z/W] значения приближаются к точке на бесконечности. На самом деле это уже не точка, а направление от [0,0,0] в [X,Y,Z],

Поэтому, когда мы определяем положение света, мы должны убедиться, что это правильно.

  • W=0 определяет направленный свет, поэтому x, y, z является направленным вектором
  • W=1 определен позиционный источник света, поэтому x, y, z — это позиция в трехмерном пространстве

Вы сможете много поиграть с этим, как только углубитесь в математику. Если вы попытаетесь изменить направление (W=0) с матрицей перевода, например, это не будет иметь никакого эффекта. Это очень актуально и здесь, поскольку на положение света будет влиять матрица вида модели.

Некоторые легко понять информацию здесь для дальнейшего чтения:
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/

2

Другие решения

Если в OpenGL нет функции «бросить тень», как я могу это сделать?

Что вы должны понять, так это то, что в OpenGL нет понятия «сцена». Все, что делает OpenGL, это рисование точек, линий или треугольников на экране, по одной за раз. После того, как он нарисован, он не влияет на следующие операции рисования.

Так что, чтобы сделать что-то причудливое, как тени, вы должны получить художественный. Под этим я подразумеваю, что, как художник, который рисует пластиковую картину с глубиной «просто» кистью и палитрой цветов, вы должны художественно использовать OpenGL, чтобы воссоздать с его помощью те эффекты, которые вы желаете. Рисование тени может быть сделано различными способами. Но самый популярный из них известен под термином Shadow Mapping.

Shadow Mapping — двухэтапный процесс. На первом этапе сцена визуализируется в виде «градаций серого», «видимых» с точек зрения источника света, где расстояние от источника света отображается как «серое» значение. Это называется Карта глубины тени.

На втором этапе сцена рисуется как обычно, где карты глубины тени источников проецируются в сцену, как если бы источники света были слайд-проектором (где все получает это изображение, поскольку OpenGL не затеняет). В шейдере значение глубины на карте глубины тени сравнивается с фактическим расстоянием до источника света для каждого обработанного фрагмента; если расстояние до источника света больше соответствующего пикселя в карте теней, это означает, что при рендеринге карты теней что-то попало перед текущим обрабатываемым фрагментом геометрии, который, следовательно, находится в тени, поэтому он рисуется в цвете тени ( обычно цвет окружающего освещения); Вы можете объединить это с Окружающая Окклюзия эффект для имитации мягкого, самозатенения окружающего освещения.

2

По вопросам рекламы [email protected]