Задание:
Задание на работу. Используя материалы из папки materials реализовать с помощью Direct3D следующие спецэффекты: зеркальное отражение, тени, туман. Результат работы должен быть подобен результату лабораторной работы № 4.
Выполнение:
Вершины и нормали для рисования усечённой четырёхугольной пирамиды были взяты из предыдущей лабораторной работы.
Тень рисуется с помощью матрицы тени, полученной из функции D3DXMatrixShadow. Для достижения наиболее реалистичной тени используется смешивание цветов. При этом возникает такой недостаток: при наложении двух теней происходит ещё большее затенение, чего не должно быть. Эта проблема решается с помощью буфера трафарета. Буфер трафарета настраивается таким образом, что рисуются только те пиксели, которые прорисовываются впервые.
1 2 3 4 5 6 7 8 |
pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, true); pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); pd3dDevice->SetRenderState(D3DRS_STENCILREF, 0x0); pd3dDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); pd3dDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); |
Отражение рисуется с помощью функции D3DXMatrixReflect.. При этом изображение должно прорисовываться только в зеркале. чтобы устранить прорисовку на других поверхностях используется буфер трафарета.
Сначала на буфере трафарета рисуется зеркало. Для этого буфер трафарета настраивается так:
1 2 3 4 5 6 7 8 |
pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, true); pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); pd3dDevice->SetRenderState(D3DRS_STENCILREF, 0x1); pd3dDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); pd3dDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); |
То есть в точки, входящие в прорисованное изображение заменяются в буфере трафарета на 0x1.
После этого отключается прорисовка в ZBUFFER.
Затем буфер трафарета настраивается таким образом, что прорисовка происходит только в той области, где расположено зеркало:
1 2 |
pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL); pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); |
Потом очищается ZBUFFER. Меняется обход вершин на противоположный и происхзодит прорисовка отражения.
После этого включается режим смешивание цветов и прорисовывается прозрачное зеркало.
Вывод:
Использование буфера трафарета даёт возможность получать достаточно реалистичные эффекты.