Софтверный рендеринг

Модератор: Модераторы разделов

frp
Сообщения: 1445
ОС: Debian Squeeze

Софтверный рендеринг

Сообщение frp »

Какие существуют техники софтверного рендеринга? Где о них почитать? Желательно на русском. Где почитать как это реализовать?

Мне главное - быстрота (качество не сильно важно, желательно только чтобы как минимум на уровне первого дума (а лучше первой кваки)) и простота реализации.

Также интересует как реализовать raytracing и возможно ли использовать его для рендеринга в реальном времени.
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: Софтверный рендеринг

Сообщение Denjs »

была такая книжка - "как написать игру типа DOOM" ))))
но там правда алгоритмы и фишки оптимизации для игрушки типа первого "вульфа 3Д"

но помню когда я оную читал - "пёрся" как кот которому дали валерьянки)
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали:
Аватара пользователя
Lyset
Сообщения: 107
ОС: Ubuntu

Re: Софтверный рендеринг

Сообщение Lyset »

У Андре Ламота есть книжка, где всё разжёвывается. Хоть там под винду, но алгоритмы везде одинаковые.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

frp писал(а):
21.12.2009 22:07
Какие существуют техники софтверного рендеринга? Где о них почитать? Желательно на русском. Где почитать как это реализовать?

1) 2.5D - рисуем обычными двумерными полигонами с пересчётом координат по матрице. Цвет по нормали считаем.
Плюсы - быстро и сурово просто.
Минусы - отсутствует полноценное понятие глубины - определяется лишь порядком обработки - надо рисовать от дальних к ближним (невозможно отобразить пересекающиеся или циклически перекрывающие друг-друга объекты)
Полутоновые закраски трудны в реализации, т.е. на на "гладких" поверхностях будут заметны грани.
2) Буфер глубины, цвета, модель Фонга в растеризацию... - короче полный комплект. Теоретически и шейдеры реально прикрутить, но тормозить будет и без них :).
3) Ray casting - неплохой метод - как раз он и использовался в Wolfenstein 3D. Суть метода - из каждого пиксела пускаем луч до столкновения с объектом. По нормали считаем цвет, если будет считать по билинейно пересчитанной нормали, то можно получить "гладкую" поверхность.

Во всех методах проблемы с тенями. Во 2 - теневые объемы или карты. И в 1 это можно прикрутить... просто расчет тени делать до отрисовки, сортировку производить с учётом тень это или объект (считать тень ближе). В 3 можно внести элемент ray tracing. После попадания на объект пускать лучи ко всем источникам и считать - есть ли что-то на пути. Если нет - то вводить в учет этот источник. Если попадается, то не учитывать.

Во всех методах параллельность значительно ускоряет работу, но в 1 методе нужно очень аккуратно и осторожно, можно допустить ошибки.

frp писал(а):
21.12.2009 22:07
Мне главное - быстрота (качество не сильно важно, желательно только чтобы как минимум на уровне первого дума (а лучше первой кваки)) и простота реализации.

Если скорость - то 1 или 3. 2 можно кое-где схалтурить для ускорения, но всё же ресурсоёмко.

frp писал(а):
21.12.2009 22:07
Также интересует как реализовать raytracing и возможно ли использовать его для рендеринга в реальном времени.

Софтверный ray tracing - нереально в real time. Лучше сделайте ray casting с проверкой доступности источников света. Можно добавить элемент отражения (но 100% чтобы не дробить, хотя можете попробовать дробить, но это всё будет съедать ресурсы). Но с отражениями есть проблема взаимного отражения... Поэтому лучше ограничить глубину рекурсии. Преломление... Ну, можно попробовать.

Если что-то заинтересовало могу немного подробнее рассказать.
По литературе... даже не знаю... Могу просто по 3D графике пару книг посоветовать. Для общего понимания так сказать. Но там больше OpenGL рассматривается.
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Софтверный рендеринг

Сообщение Yaros »

Еще только начинаю изучать программирование, но уже интересно: а сильно ли различаются кодинг OpenGL в Linux и Windows?
Книги видел только под Win, сейчас раздумываю, брать или нет...
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Yaros писал(а):
23.12.2009 17:01
Еще только начинаю изучать программирование, но уже интересно: а сильно ли различаются кодинг OpenGL в Linux и Windows?
Книги видел только под Win, сейчас раздумываю, брать или нет...

Прикольно... А я учился по книге в которой говорилось о каком-то "X Window" (но в итоге всё свелось к GLUT)... А надо было под винду. Книга для начинающих хорошая - Эдвард Энджел "Интерактивная компьютерная графика. Вводный курс на базе OpenGL", ISBN: 5-8459-0209-6.

Берите под винду, разница будет только в паре моментов:
1. Инициализация - создание окна, связывание OpenGL с окном.
2. Смена буферов.
3. Подгрузка векторных (TTF) шрифтов.
В остальном разница не заметна. А если использовать GLUT, SDL, то и кроссплатформенность можно сделать.
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Софтверный рендеринг

Сообщение Yaros »

Эдвард Энджел "Интерактивная... " - это никсовая? О_О Фап-фап...
Проблема в том, что многие книги сейчас пишутся про DirectX only, либо DirectX + OpenGL, но о последнем больше вскользь =(
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Yaros писал(а):
23.12.2009 18:40
Эдвард Энджел "Интерактивная... " - это никсовая? О_О Фап-фап...
Проблема в том, что многие книги сейчас пишутся про DirectX only, либо DirectX + OpenGL, но о последнем больше вскользь =(

Ну, там о никсах не очень много сказано. Используется в примерах GLUT и сказано, что автор использовал в обучении никсы.
Могу подкинуть код-болванку под никсы без GLUT.

Книга интересна не только как OpenGL - там достаточно много уделено внимания вообще основам 3D графики. Сплайны рассмотрены, работа с векторами и матрицами, перспективные преобразования. В общем, книга полезная, особенно если знаний линейной алгебры не очень много.
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Софтверный рендеринг

Сообщение Yaros »

NickLion писал(а):
24.12.2009 11:28
Yaros писал(а):
23.12.2009 18:40
Эдвард Энджел "Интерактивная... " - это никсовая? О_О Фап-фап...
Проблема в том, что многие книги сейчас пишутся про DirectX only, либо DirectX + OpenGL, но о последнем больше вскользь =(

Ну, там о никсах не очень много сказано. Используется в примерах GLUT и сказано, что автор использовал в обучении никсы.
Могу подкинуть код-болванку под никсы без GLUT.

Можно.
И что такое GLUT? =)
NickLion писал(а):
24.12.2009 11:28
Книга интересна не только как OpenGL - там достаточно много уделено внимания вообще основам 3D графики. Сплайны рассмотрены, работа с векторами и матрицами, перспективные преобразования. В общем, книга полезная, особенно если знаний линейной алгебры не очень много.

Не очень много, да. Что-то разрозненное помню, но не углублялся, к сожалению...
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Yaros писал(а):
24.12.2009 14:48
И что такое GLUT? =)

GLUT - библиотечка, позволяет упростить всю эту инициализацию, плюс не завязываться конкретно на систему (кроссплатформенная). Есть ещё SDL - эта помощнее будет.

Вот примерчик:

Код: Выделить всё

#include <sys/time.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <string.h>

struct t_pd {
    Display* pDisplay;
    XVisualInfo *visualInfo;
    int screen;
    Window window;
    GLXContext glxContext;
    Atom wm_protocols;
    Atom wm_delete_window;
    int old_width, old_height;
    bool loop_continue;
};

enum t_error {
    err_ok = 0,
    err_open_display,
    err_query_glx,
    err_no_appropriate_visual,
    err_create_context,
};

typedef bool (*fn_render) ( t_pd* );

t_error create_window( t_pd* pd, int x, int y, int width, int height, const char* title );
bool init_gl( t_pd* pd );
bool msg_loop( fn_render render, t_pd* pd );
bool render_scene( t_pd* pd );

int main( int /*argc*/, char * /*argv*/[] ) {
    t_pd pd;
    if( err_ok == create_window( &pd, 0, 0, 640, 480, "Заголовок" ) ) {
        init_gl( &pd );
        msg_loop( render_scene, &pd );
    }
    return 0;
}

bool init_gl( t_pd* pd ) {
    XWindowAttributes wa;
    XGetWindowAttributes( pd->pDisplay, pd->window, &wa );

    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    glEnable( GL_TEXTURE_2D );
    glEnable( GL_DEPTH_TEST );
    glShadeModel( GL_SMOOTH );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    gluPerspective( 45.0f, wa.width / (double) wa.height, 0.1f, 100.0f);
    glMatrixMode( GL_MODELVIEW );
    return true;
}

bool render_scene( t_pd* /*pd*/ ) {
    static struct timeval tv;
    gettimeofday( &tv, NULL );
    float a = tv.tv_usec * 1e-6f + ( tv.tv_sec % 86400 );

    float xrf = a * 10, yrf = a * 20, zrf = a * 15;
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glTranslatef( 0.0f, 0.0f, -7.0f );

    glRotatef( xrf, 1.0f, 0.0f, 0.0f );
    glRotatef( yrf, 0.0f, 1.0f, 0.0f );
    glRotatef( zrf, 0.0f, 0.0f, 1.0f );

    glBegin(GL_QUADS);

    glColor3f( 0.0f, 1.0f, 0.0f );
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);

    glColor3f(1.0f,0.5f,0.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);

    glColor3f(1.0f,0.0f,0.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);

    glColor3f(1.0f,1.0f,0.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f);

    glColor3f(0.0f,0.0f,1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);

    glColor3f(1.0f,0.0f,1.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);

    glEnd();

    return true;
}

t_error create_window( t_pd* pd, int x, int y, int width, int height, const char *title ) {
    int errorBase;
    int eventBase;
    pd->pDisplay = XOpenDisplay( NULL );
    if( pd->pDisplay == NULL )
        return err_open_display;

    if( !glXQueryExtension( pd->pDisplay, &errorBase, &eventBase ) )
        return err_query_glx;

    // Необходимый visual
    int doubleBufferVisual[] = {
        GLX_RGBA,
        GLX_DEPTH_SIZE, 16,
        GLX_DOUBLEBUFFER,
        None
    };

    pd->screen = DefaultScreen( pd->pDisplay );
    pd->visualInfo = glXChooseVisual( pd->pDisplay, pd->screen, doubleBufferVisual );

    if( pd->visualInfo == NULL )
        return err_no_appropriate_visual;

    // Создаем контекст отображения
    pd->glxContext = glXCreateContext( pd->pDisplay, pd->visualInfo, NULL, GL_TRUE );

    if( pd->glxContext == NULL )
        return err_create_context;

    pd->wm_protocols = XInternAtom( pd->pDisplay, "WM_PROTOCOLS", False );
    pd->wm_delete_window = XInternAtom( pd->pDisplay, "WM_DELETE_WINDOW", False );

    XSetWindowAttributes windowAttributes = { };
    Colormap colorMap;

    colorMap = XCreateColormap(
        pd->pDisplay,
        RootWindow( pd->pDisplay, pd->visualInfo->screen ),
        pd->visualInfo->visual,
        AllocNone
    );

    windowAttributes.colormap     = colorMap;
    windowAttributes.border_pixel = 0;
    windowAttributes.event_mask   =
                                    VisibilityChangeMask   |
                                    KeyPressMask           |
                                    KeyReleaseMask         |
                                    ButtonPressMask        |
                                    ButtonReleaseMask      |
                                    PointerMotionMask      |
                                    StructureNotifyMask    |
                                    FocusChangeMask        |
                                    0;

    // Создаем окно с выбранным визуалом

    pd->window = XCreateWindow(
        pd->pDisplay,
        RootWindow( pd->pDisplay, pd->visualInfo->screen ),
        x, y,
        width, height,
        0,
        pd->visualInfo->depth,
        InputOutput,
        pd->visualInfo->visual,
        CWBorderPixel | CWColormap | CWEventMask,
        &windowAttributes
    );

    XSetWMProtocols( pd->pDisplay, pd->window, &pd->wm_delete_window, 1 );

    XTextProperty xtp;
    xtp.nitems = strlen( title );
    xtp.format = 8;
    xtp.encoding = XInternAtom( pd->pDisplay, "UTF8_STRING", 0 );
    xtp.value = (unsigned char*) title;
    XSetWMName( pd->pDisplay, pd->window, &xtp );

    // Связываем контекст с окном
    glXMakeCurrent( pd->pDisplay, pd->window, pd->glxContext );

    // Отображаем окно
    XMapWindow( pd->pDisplay, pd->window );
    return err_ok;
}

bool msg_loop( fn_render render, t_pd* pd ) {
    XEvent event;
    pd->loop_continue = true;
    while( pd->loop_continue ) {
        while( pd->loop_continue && XPending( pd->pDisplay ) ) {
            XNextEvent( pd->pDisplay, &event );
            switch( event.type ) {
            case ButtonPress:
                break;

            case ButtonRelease:
                break;

            case KeyPress:
                break;

            case KeyRelease:
                break;

            case MotionNotify:
                break;

            case ConfigureNotify:
                if( pd->old_width != event.xconfigure.width || pd->old_height != event.xconfigure.height ) {
                    pd->old_width = event.xconfigure.width;
                    pd->old_height = event.xconfigure.height;
                    glViewport( 0, 0, event.xconfigure.width, event.xconfigure.height );
                }
                break;
            case ClientMessage:
                if( event.xclient.message_type == pd->wm_protocols && (Atom) event.xclient.data.l[0] == pd->wm_delete_window ) {
                    pd->loop_continue = false;
                }
                break;
            }
        }

        render( pd );
        glXSwapBuffers( pd->pDisplay, pd->window );
    }
    XDestroyWindow( pd->pDisplay, pd->window );
    return true;
}
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Софтверный рендеринг

Сообщение Yaros »

NickLion писал(а):
25.12.2009 13:56
Yaros писал(а):
24.12.2009 14:48
И что такое GLUT? =)

GLUT - библиотечка, позволяет упростить всю эту инициализацию, плюс не завязываться конкретно на систему (кроссплатформенная). Есть ещё SDL - эта помощнее будет.

А что тогда лучше? Кроссплатформенность - не скажу что особо нужна.
NickLion писал(а):
25.12.2009 13:56
Вот примерчик:

Глядя на него, чуть не передумал изучать))
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Yaros писал(а):
25.12.2009 15:38
А что тогда лучше? Кроссплатформенность - не скажу что особо нужна.

Лучше GLUT или SDL? Или использовать/не использовать их?

Yaros писал(а):
25.12.2009 15:38
Глядя на него, чуть не передумал изучать))

Не ужасайтесь. Там основную вещь занимает не OpenGL, а подготовка со стороны X. Этот шаблон практически не будет меняться. Добавится код в обработку сообщений. create_window можно практически не трогать. Там только если визуал другой надо или полноэкранным сделать, а так почти не поменяется. Диагностику ошибок можно выкинуть - всё равно дальше не проверяю. Хотя полезно проверить.
Отрисовка кубика сделана в самом просто виде, сейчас такое поведение считается deprecated, точнее его уже убрали в 3.2. Но работает :)
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Софтверный рендеринг

Сообщение Yaros »

NickLion писал(а):
25.12.2009 17:34
Yaros писал(а):
25.12.2009 15:38
А что тогда лучше? Кроссплатформенность - не скажу что особо нужна.

Лучше GLUT или SDL? Или использовать/не использовать их?

И то, и другое. Стоит ли их использовать, и, если да, что именно?
NickLion писал(а):
25.12.2009 17:34
Yaros писал(а):
25.12.2009 15:38
Глядя на него, чуть не передумал изучать))

Не ужасайтесь. Там основную вещь занимает не OpenGL, а подготовка со стороны X. Этот шаблон практически не будет меняться. Добавится код в обработку сообщений. create_window можно практически не трогать. Там только если визуал другой надо или полноэкранным сделать, а так почти не поменяется. Диагностику ошибок можно выкинуть - всё равно дальше не проверяю. Хотя полезно проверить.
Отрисовка кубика сделана в самом просто виде, сейчас такое поведение считается deprecated, точнее его уже убрали в 3.2. Но работает :)

Ок, попробую вкурить...
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Yaros писал(а):
25.12.2009 17:46
NickLion писал(а):
25.12.2009 17:34
Yaros писал(а):
25.12.2009 15:38
А что тогда лучше? Кроссплатформенность - не скажу что особо нужна.

Лучше GLUT или SDL? Или использовать/не использовать их?

И то, и другое. Стоит ли их использовать, и, если да, что именно?

Если сравнивать GLUT и SDL:
GLUT:
1. Ориентировано только под OpenGL и взаимодействие клава/мышь.
2. Оригинальный не поддерживается, есть freeglut, со своими "особенностями".
3. Небольшой размер.
SDL:
1. Достаточно мощная библиотека, ориентирована на работу с графикой, устройствами вв/в и звуком. В частности работает с OpenGL.
2. Продолжает развиваться.
3. Весомая библиотека.

Лично мне не нравится ни то, ни другое :) SDL имеет смысл, если приложению требуется работа с многими вещами, но не хочется заморачиваться. GLUT - если нужна кроссовость малыми затратами (не привлекать тяжелую артиллерию).
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Софтверный рендеринг

Сообщение Yaros »

NickLion писал(а):
25.12.2009 18:04
Yaros писал(а):
25.12.2009 17:46
NickLion писал(а):
25.12.2009 17:34
Yaros писал(а):
25.12.2009 15:38
А что тогда лучше? Кроссплатформенность - не скажу что особо нужна.

Лучше GLUT или SDL? Или использовать/не использовать их?

И то, и другое. Стоит ли их использовать, и, если да, что именно?

Если сравнивать GLUT и SDL:
GLUT:
1. Ориентировано только под OpenGL и взаимодействие клава/мышь.
2. Оригинальный не поддерживается, есть freeglut, со своими "особенностями".
3. Небольшой размер.
SDL:
1. Достаточно мощная библиотека, ориентирована на работу с графикой, устройствами вв/в и звуком. В частности работает с OpenGL.
2. Продолжает развиваться.
3. Весомая библиотека.

Лично мне не нравится ни то, ни другое :) SDL имеет смысл, если приложению требуется работа с многими вещами, но не хочется заморачиваться. GLUT - если нужна кроссовость малыми затратами (не привлекать тяжелую артиллерию).

Т.е. лучше все писать самому с нуля, если охота сделать все под себя?
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Я не скажу лучше. Я скажу мне так больше нравится.
Спасибо сказали:
Аватара пользователя
Yaros
Сообщения: 501
ОС: Debian Wheezy / Gentoo

Re: Софтверный рендеринг

Сообщение Yaros »

NickLion писал(а):
25.12.2009 18:36
Я не скажу лучше. Я скажу мне так больше нравится.

Я имел ввиду продуктивность. И, кстати, оно ведь с QT/GTK никак не завязано?
P.S.: Я Вас в джаббер добавлю, Вы не против?
=========
=Мой блог. =
=========
Gentoo-ниасилятар
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Yaros писал(а):
25.12.2009 18:48
NickLion писал(а):
25.12.2009 18:36
Я не скажу лучше. Я скажу мне так больше нравится.

Я имел ввиду продуктивность. И, кстати, оно ведь с QT/GTK никак не завязано?
P.S.: Я Вас в джаббер добавлю, Вы не против?

Продуктивность кода? Ну, ессно чем меньше оберток, тем быстрее. Продуктивность создания - с этими библиотеками может быть выше - они всё же упрощают.
PS добавляйте :)
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Вернёмся к софтверному рендерингу.
Очень интересный примерчик - трассировка лучей на C# с использованием LINQ.
http://blogs.msdn.com/lukeh/archive/2007/0...r-in-c-3-0.aspx
http://blogs.msdn.com/lukeh/archive/2007/1...-raytracer.aspx

Естественно ни о каком real-time речи не идет. Но впечатляет :)
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Софтверный рендеринг

Сообщение frp »

NickLion писал(а):
23.12.2009 09:00
3) Ray casting - неплохой метод - как раз он и использовался в Wolfenstein 3D. Суть метода - из каждого пиксела пускаем луч до столкновения с объектом. По нормали считаем цвет, если будет считать по билинейно пересчитанной нормали, то можно получить "гладкую" поверхность.

Понравился как наименее громоздкой и, судя по аппаратным требованиям Wolfenstein 3D, очень быстрый :) Только вот непонятно несколько моментов:
1) Где толком почитать на русском?
2) В каком направлении нужно пускать луч?
3) Как правильно считать цвет?
4) Как реализовать освещение?
5) Возможно ли без raytracing сделать отражения и тени? Не особо проблематично сделать очень неглубокий Raytracing, но количество кода и время выполнения увеличится.
6) Какие возможны оптимизации? (гугл сказал, что количество обрабатываемых полигонов для одного луча можно сократить до logN, но как это сделать нигде не нашел).
7) Существует ли опенсурсная реализация raycasting? Открыт ли исходник Wolfenstein 3d?
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

1) Даже и не знаю... На gamedev.ru может что-то есть...
2) От положения камеры в центр каждого спроектированного пикселя и дальше.
3) Попали на треугольник (квад) - считаем цвет по вершинам (билинейная интерполяция).
4) Для каждой вершины задается нормаль, пересчитываем нормаль в точке, куда попали. Затем берем направления на источники света, т.е. вектор нормали, вектор на источник света. И по формуле считаем.
5) Отражения - можно попробовать строить карты, но зачем? Если нет взаимоотражений, то нагрузка будет невелика. С современными то процессорами. Тени - тоже можно. Но опять же - зачем.
6) Оптимизации... Я считаю, что сначала реализуйте метод втупую, а потом начинайте прикручивать оптимизации. Мне кажется это более верным в условиях неглубоких знаний 3D графики. Оптимизации разные можно. Octree к примеру.
7) http://www.btinternet.com/~belowe/ - тут исходники. Но особо ли они помогут? Написано на си и ассемлере. Под ДОС. С различными допущениями и оптимизациями (насколько помню, там луч считается не на каждый пиксель, а на всю колонку, т.к. сцены там достаточно примитивные, левелы 2-мерные).

И ещё - если пункты 3 и 4 звучат неясно, то стоит почитать книги по 3D графике вообще. Знания линейной алгебры и аналитической геометрии приветствуются. Могу подробнее рассказать, конечно, но попозже, буду немного занят в ближайшее время.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Кстати, я вроде уже подосвободился, так что смогу помочь, если есть вопросы по теме.
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Софтверный рендеринг

Сообщение frp »

NickLion писал(а):
26.12.2009 17:18
И ещё - если пункты 3 и 4 звучат неясно, то стоит почитать книги по 3D графике вообще.

Какие именно? Гугл выдал только кучу книг по OpenGL и DirectX.

NickLion писал(а):
26.12.2009 17:18
2) От положения камеры в центр каждого спроектированного пикселя и дальше.

1) Пусть есть плоскость. Как на ней наиболее простым способом найти точку с заданными двумерными координатами если заданы оси координат на этой плоскости? Пока что придумал только сверхизвращенный метод через систему из уравнений плоскости и двух шаров.
2) Как определить точку пресечения луча и треугольника? Пока что использую сверхизвращенный метод через систему уравнений прямой и плоскости. Но кода очень много и выполняется довольно медленно т.к. нужно учесть все случаи с делением на ноль.
NickLion писал(а):
26.12.2009 10:38
Очень интересный примерчик - трассировка лучей на C# с использованием LINQ.

Примерчик интересный (рендерится, правда, под моно 1.9 на Celeron 1.8 Ghz около минуты), но код довольно сложный, длинный и без комментариев.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

frp писал(а):
08.01.2010 11:42
NickLion писал(а):
26.12.2009 17:18
И ещё - если пункты 3 и 4 звучат неясно, то стоит почитать книги по 3D графике вообще.

Какие именно? Гугл выдал только кучу книг по OpenGL и DirectX.

Любые, где описываются основы. Например, тот же Э.Энджел.

frp писал(а):
08.01.2010 11:42
1) Пусть есть плоскость. Как на ней наиболее простым способом найти точку с заданными двумерными координатами если заданы оси координат на этой плоскости? Пока что придумал только сверхизвращенный метод через систему из уравнений плоскости и двух шаров.

Так, давайте подробнее. Есть плоскость - где, в 3-мерном пространстве? Как заданы оси координат?

frp писал(а):
08.01.2010 11:42
2) Как определить точку пресечения луча и треугольника? Пока что использую сверхизвращенный метод через систему уравнений прямой и плоскости. Но кода очень много и выполняется довольно медленно т.к. нужно учесть все случаи с делением на ноль.

Пусть луч задан точкой p и вектором v. Треугольник - своими вершинами t[0], t[1], t[2].
Можно рассмотреть так:
p+αv=t[0]+β(t[1]-t[0])+γ(t[2]-t[0])
αv-β(t[1]-t[0])-γ(t[2]-t[0])=t[0]-p
- получаем систему из 3 уравнений с 3 неизвестными.
Можно так:
n=[ (t[1]-t[0]) x (t[2]-t[0]) ] - нормаль плоскости
α=-( n , v ) - если α <= 0, то дальше можно не рассматривать.
β=( n, p-t[0] )
x=p+(β/α)v - точка пересечения луча с плоскостью
Проверяем находится ли она внутри треугольника (через сумму углов):
arccos( ( norm( t[0]-x ) , norm( t[1]-x ) ) )+arccos( ( norm( t[1]-x ) , norm( t[2]-x ) ) )+arccos( ( norm( t[0]-x ) , norm( t[2]-x ) ) )==2 * pi
Вроде нигде не ошибся :)

frp писал(а):
08.01.2010 11:42
Примерчик интересный (рендерится, правда, под моно 1.9 на Celeron 1.8 Ghz около минуты), но код довольно сложный, длинный и без комментариев.

Естественно сложный, долго работает (ещё и шарп), полноценная трассировка лучей ведь :)
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

Написал, а потом подумал. Вам то это не нужно, практически. Просто делаем перспективное преобразование, после чего получаем пространство, в котором все лучи становятся параллельными оси Z, ведь так? И в дальнейшем работаем уже в этом пространстве. Тогда проверка будет сводиться к проверке X, Y координат луча и треугольников.
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Софтверный рендеринг

Сообщение frp »

NickLion писал(а):
09.01.2010 11:17
Так, давайте подробнее. Есть плоскость - где, в 3-мерном пространстве? Как заданы оси координат?

Уже не надо, решил реализовать как в OpenGL (камера всегда в точке 0,0,0, камера не перемещается).
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

frp писал(а):
16.01.2010 00:04
NickLion писал(а):
09.01.2010 11:17
Так, давайте подробнее. Есть плоскость - где, в 3-мерном пространстве? Как заданы оси координат?

Уже не надо, решил реализовать как в OpenGL (камера всегда в точке 0,0,0, камера не перемещается).

Это не совсем так. В OpenGL камера не находится обязательно в точке 0,0,0. Просто стандартный (OpenGL, Direct3D в частности) подход в том, чтобы построить матрицу преобразования, которая поворачивает весь мир так, чтобы камера оказалась в точке 0,0,0 направленной по оси Z, верх по оси Y. Так же производим перспективное преобразование, чтобы пирамиду вида превратить в куб.
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Софтверный рендеринг

Сообщение frp »

Сделал. Не работает: не рендерится ничего. Что я сделал неправильно?
Старый извращенный вариант работает. Выкладываю архив (7z) с исходником и проектом qtcreator.
Содержимое архива:
1) проект qtcreator и файлы исходников и GUI.
2) собранный бинарник.
3) файл renderer2.cpp - реализация моего первого метода (она рендерит некоторые грани некорректно) - для использования этим файлом нужно заменить файл renderer.cpp
PS. За качество кода, использование Qt для рисования и другую ерунду, не относящуюся к теме, не ругать - черновик.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Софтверный рендеринг

Сообщение NickLion »

1. renderer2.cpp - не знаю, что это, но выглядит страшно :) почти всё красное (радиально от центра есть чёрные промежутки, неровные), и бело-желтый квадрат :)
2. renderer.cpp - всё просто чёрное... буду смотреть сегодня-завтра, может что увижу - скажу.
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Софтверный рендеринг

Сообщение frp »

NickLion писал(а):
16.01.2010 19:21
почти всё красное (радиально от центра есть чёрные промежутки, неровные)

Блин забыл удалить полигон, на котором возникает ошибка. Удалите последний треугольник в конструкторе Renderer.
Спасибо сказали: