Nano Hash - криптовалюты, майнинг, программирование

OpenGL, соединяющий купол неба и плоскую плоскость земли

Я строю простой город с помощью OpenGL и GLUT, я создал текстурированный купол неба, и теперь я хотел бы соединить его с плоской плоскостью, чтобы создать видимость горизонта. Чтобы дать относительный размер, небесный купол имеет радиус 3,0 с отключенной маской глубины, и к нему применяется только вращение камеры, и он находится над камерой. Здание имеет размер около 30,0, и я смотрю на него с y=500,0 вниз.

У меня есть плоскость земли размером 1000x1000, я текстурирую текстуру с разрешением 1024x1024, которая хорошо выглядит вблизи, когда я нахожусь на земле. Моя текстура загружается с помощью GL_REPEAT с координатой текстуры 1000, чтобы повторить ее 1000 раз.

У меня возникли некоторые проблемы с соединением купола неба с плоскостью земли. Я перечислю ряд вещей, которые я пробовал.

Проблемы:

1) Когда я поворачиваю курс, из-за квадратной формы самолета я вижу край, как на прикрепленном изображении, вместо плоского горизонта.

Горизонт не плоский

2) Вместо этого я попробовал круговую плоскость земли, но у меня получился кривой горизонт, который становится более извилистым, когда я взлетаю.

Горизонт искривлен

3) Чтобы избежать черного промежутка между бесконечным куполом неба и моей плоской плоскостью ограниченного размера, я устанавливаю ограничение на то, как далеко я могу летать, и немного сдвигаю купол неба по мере подъема, чтобы я не видел черный промежуток между бесконечным небосводом и моей плоской плоскостью, когда я высоко. Существуют ли другие способы плавного перехода плоскости в купол неба и устранения зазора, когда зазор различается по размеру в разных местах (например, круг, описывающий квадрат)? Я пытался применить цвет тумана к горизонту, но у меня получается фиолетовая дымка на белой земле.

4) Если я прикрепил землю в качестве нижней крышки полусферы Skydome, то при увеличении и уменьшении масштаба это выглядит странно, похоже, что текстурированная земля скользит и отсоединяется от моего здания.

5) Я попытался нарисовать бесконечно большую плоскость, используя концепцию точки схода, установив w=0. Визуализация бесконечно большой плоскости Горизонт выглядит плоским, но правильное текстурирование кажется сложным, поэтому я застрял с одним цветом.

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

7) Если я увеличу свою плоскость, например, 10000x10000, то горизонт будет казаться плоским, но, если я нажму клавишу со стрелкой, чтобы скорректировать мой курс, горизонт будет трястись в течение нескольких секунд, прежде чем стабилизироваться, в чем причина, и как я мог предотвратить это. Связанный с этим вопрос, похоже, что тайлинг и текстурирование 1000x1000 наземной плоскости и 10000x10000 не влияют на мою частоту кадров, почему это так? Разве больше плитки не означает больше работы?

8) Я читал о каком-то математическом подходе к вычислению прямоугольника отсечения для рисования горизонта, но мне интересно, есть ли более простые подходы http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/a-super-simple-method-for-creating-infinite-sce-r2769

В большинстве тредов, которые я читал о горизонте, говорилось: используйте скайбокс, используйте скайдоум, но я не наткнулся на конкретный учебник, в котором хорошо рассказывается о слиянии скайдома с большой наземной плоскостью. Указатель на такой учебник было бы здорово. Не стесняйтесь отвечать на любые части вопроса, указывая номер, я не хотел их разбивать, потому что все они связаны. Спасибо.

Вот некоторый соответствующий код в моей настройке:

void Display()
    {        

        // Clear frame buffer and depth buffer
        glClearColor (0.0,0.0,0.0,1.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);     

        glLoadIdentity();
        camera.Update();

        GLfloat accumulated_camera_rotation_matrix[16];
        GetAccumulatedRotationMatrix(accumulated_camera_rotation_matrix);

        SkyDome_Draw(accumulated_camera_rotation_matrix);

        FlatGroundPlane_Draw();     

        // draw buildings

        // swap buffers when GLUT_DOUBLE double buffering is enabled
        glutSwapBuffers();

    }

    void SkyDome_Draw(GLfloat (&accumulated_camera_rotation_matrix)[16])
    {
        glPushMatrix();
        glLoadIdentity();
        glDepthMask(GL_FALSE);
        glDisable(GL_LIGHTING);     

        glMultMatrixf(accumulated_camera_rotation_matrix);

        // 3.0f is the radius of the skydome        
        // If we offset by 0.5f in camera.ground_plane_y_offset, we can offset by another 1.5f 
        // at skydome_sky_celing_y_offset of 500.  500 is our max allowable altitude
        glTranslatef( 0, -camera.ground_plane_y_offset - camera.GetCameraPosition().y /c amera.skydome_sky_celing_y_offset/1.5f, 0);

        skyDome->Draw();                
        glEnable(GL_LIGHTING);
        glDepthMask(GL_TRUE);       
        glEnable(GL_CULL_FACE);
        glPopMatrix();
    }

    void GetAccumulatedRotationMatrix(GLfloat (&accumulated_rotation_matrix)[16])
    {
        glGetFloatv(GL_MODELVIEW_MATRIX, accumulated_rotation_matrix);
        // zero out translation is in elements m12, m13, m14
        accumulated_rotation_matrix[12] = 0;
        accumulated_rotation_matrix[13] = 0;
        accumulated_rotation_matrix[14] = 0;
    }

    GLfloat GROUND_PLANE_WIDTH = 1000.0f;

    void FlatGroundPlane_Draw(void) 
    {   

        glEnable(GL_TEXTURE_2D);            
        glBindTexture( GL_TEXTURE_2D, concreteTextureId); 
        glBegin(GL_QUADS);  


        glNormal3f(0, 1, 0);

        glTexCoord2d(0, 0);


        // repeat 1000 times for a plane 1000 times in width
        GLfloat textCoord = GROUND_PLANE_WIDTH;

        glVertex3f( -GROUND_PLANE_WIDTH, 0, -GROUND_PLANE_WIDTH);

        // go beyond 1 for texture coordinate so it repeats
        glTexCoord2d(0, textCoord);

        glVertex3f( -GROUND_PLANE_WIDTH, 0, GROUND_PLANE_WIDTH);

        glTexCoord2d(textCoord, textCoord);
        glVertex3f( GROUND_PLANE_WIDTH, 0, GROUND_PLANE_WIDTH);

        glTexCoord2d(textCoord, 0);
        glVertex3f( GROUND_PLANE_WIDTH, 0, -GROUND_PLANE_WIDTH);

        glEnd();

        glDisable(GL_TEXTURE_2D);
    }

    Void Init()
    {
        concreteTextureId = modelParser->LoadTiledTextureFromFile(concreteTexturePath);
    }

    ModelParser::LoadTiledTextureFromFile(string texturePath)
    {
        RGBImage image; // wrapping 2-d array of data
        image.LoadData(texturePath);
        GLuint texture_id;
        UploadTiledTexture(texture_id, image);
        image.ReleaseData();
        return texture_id;
    }


    void ModelParser::UploadTiledTexture(unsigned int &iTexture, const RGBImage &img)
    {
        glGenTextures(1, &iTexture); // create the texture
        glBindTexture(GL_TEXTURE_2D, iTexture);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        // the texture would wrap over at the edges (repeat)
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
        glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

        gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img.Width(), img.Height(), GL_RGB, GL_UNSIGNED_BYTE, img.Data());

}
31.03.2014

  • Что касается [2], горизонт становится более извилистым по мере увеличения высоты — это то, что происходит и в реальной жизни. Так что, возможно, это не так уж и плохо. 01.04.2014
  • @MattFichman, спасибо, Мэтт, да, это выглядит не так уж плохо, за исключением, может быть, на больших высотах по сравнению с размером круга, тогда оно становится довольно изогнутым. Но высота может быть ограничена. 02.04.2014

Ответы:


1

Попробуйте использовать рандомизированную карту высот, а не плоскую плоскость. Это не только будет выглядеть более реалистично, но и сделает край плоскости земли невидимым из-за изменения высоты. Вы также можете попробовать добавить вершинный туман, чтобы размыть область, где встречаются скайбокс и плоскость земли. Примерно так я сделал здесь.

Многие 3D-рендеринг основаны на трюках, чтобы все выглядело реалистично. Если посмотреть на большинство игр, то в них либо целая куча объектов на переднем плане, закрывающих горизонт, либо «горы» вдалеке (а-ля карты высот), которые также заслоняют горизонт.

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

31.03.2014
  • @MattRichman, спасибо за советы. Это похоже на то, что я читал, различные методы затемнения обзора. Время от времени я вижу какую-нибудь сцену от океана до неба, которая кажется бесконечной, и при этом не будет каких-либо затемняющих объектов. 02.04.2014
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..