KD-lab-Open-Source / Perimeter

GNU General Public License v3.0
522 stars 62 forks source link

Add OpenGL or Vulkan renderer #14

Open caiiiycuk opened 3 years ago

caiiiycuk commented 3 years ago

Create separate to direct3d renderer based on modern api (vulkan or opengl)

caiiiycuk commented 3 years ago

@DileSoft - linux

DeltaDesignRus commented 3 years ago

Если ещё получится прикрутить PBR и PBM, я подготовлю новые текстуры, с картами нормалей и т.д. (под это придется модели заново развернуть и переэкспортировать в игру).

caiiiycuk commented 3 years ago

Может пригодиться https://github.com/ValveSoftware/ToGL

caiiiycuk commented 3 years ago

Проверил dxvk-native на примере приложения directx9, работает отлично. Требует для работы толко SDL2, таким образом связка SDL2 + Dx9 + dxvk должна работать на линуксе нативно. Может позже прикреплю пример.

DeltaDesignRus commented 3 years ago

Если ещё получится прикрутить PBR и PBM, я подготовлю новые текстуры, с картами нормалей и т.д. (под это придется модели заново развернуть и переэкспортировать в игру).

Что хотелось бы получить в будущем:

  1. Physically based rendering (+physically based materials including roughness, metallic, emissive, and normal maps)
  2. Ray tracing или ещё круче Path tracing.
  3. Для RT или PT требуется шумоподавление, наработки есть в Quake 2 RTX.
  4. High-quality screenshot mode. В режиме паузы появляется кнопка High-quality screenshot, при нажатии на которою активируется свободная камера с управлением WASD и мышью, как в шутерах или леталках. Летаем, выбираем ракурс и жмем Take, включается рендеринг с накоплением семплов, благодаря чему качество скриншотов получается гораздо лучше (более подробная проработка освещения, отражений, преломлений). Такое есть в Quake2 RTX. Он тоже на вулкане, а исходники есть на гитхабе.
nrader95 commented 2 years ago

Although there is dxvk used for rendering under linux now, it would be nice to have native OpenGL or Vulkan render, or at least use wine opengl based implementation for dx9. DXVK currently can be CPU-bound on old CPUs, especially if particle rate is high.

IonAgorria commented 2 years ago

+1 also it would be interesting to take a look into graphics API agnostic wrapper like bgfx as @q4a suggested or look similar wrappers like wgpu that is available in Rust.

On side note it seems that Render module should have a abstract interface between D3D specific code and game code (cInterfaceRenderDevice), but some D3D stuff has leaked into abstract API probably due to not needing actual abstraction and limited time. This should be taken into account when adding new renderer or replacing D3D renderer.

kvark commented 2 years ago

Came here from Vangers Developers telegram. bgfx is more polished and widely used, it's also closer to dx9, so porting will be easier. I.e. I see it as an old-ish API that's ported to modern backends, so you wouldn't get the most out of modern APIs this way. That's probably the only downside of this path.

wgpu has a modern API and runs over DX12, Vulkan, Metal, GLES-3, and potentially DX11. It also works on the Web, both via WebGL and WebGPU (which is still not stable). The fact it's written in Rust shouldn't affect you, since you can use it via wgpu-native, which is a C API being standardized by us and Google. This also means you could swap wgpu-native with dawn with minimal effort, if needed.

Note that neither bgfx or wgpu have raytracing support. In wgpu we'd definitely want that, but nobody is working on it now, and it's a huge piece of work. So if that's your requirement, then going for Vulkan/DX12 straight would be a must.

Rusty Vangers do raytracing in pixel shaders on wgpu. If Perimeter terrain representation format is similar, we could collaborate on that approach between communities.

IonAgorria commented 2 years ago

Thanks for detailed information and differences between both wrappers, then for now it seems that integrating bgfx is a more reasonable choice in order to make game more compatible with non Win32 platforms with less amount of time and required changes in process. Plus seems to support more old-ish platforms/backends such as GLES2.0 and DX9.

wgpu looks like a good option as alternate renderer in future after bgfx when we want more goodies like some mentioned in this issue and more advanced graphics pipeline like PBR, for now raytracing isn't a must have and actual implementation might pose some challenges.

I haven't taken a deep dive in rendering of game but seems to use the standard dx9 features, shaders don't seem to do anything unusual/exotic, terrain seems to be rendered in tileset way composed by small rectangular tiles that act as vertex planes (each tile vertexes seem to be updated when height changes are noticeable, otherwise just texture is updated), this can be observed when enabling some debug rendering modes like wireframe on Debug builds: Screenshot_20220128_182044 Screenshot_20220128_182054

For the terrain part it seems that most terrain related code is at https://github.com/KD-lab-Open-Source/Perimeter/tree/cmake/Source/Terra which some parts seem to come from previous games from the studio (Vangers and Samogonki) but I'm not sure the degree of similarities and what game specific changes has been done to data representation/storage, other game links: https://github.com/KranX/Vangers/tree/master/src/terra https://github.com/KD-lab-Open-Source/Samogonki/tree/master/MechoSoma/Terra

Maybe @caiiiycuk has more experience with surmap related stuff?

kvark commented 2 years ago

The ideal place to be is have a plugin rendering architecture like Vangers recently got in https://github.com/KranX/Vangers/pull/517. This way you could have bgfx, wgpu, and a pure Vulkan raytracing renderers to play with interchangeably. But this of course requires more time/energy, and not necessarily the best thing for you right now.

IonAgorria commented 2 years ago

Mmm seems like we may have some starting point at https://github.com/IonAgorria/Perimeter/blob/cmake/Source/Render/inc/IRenderDevice.h if we isolate the D3D specifics and remove some unnecessary stuff from render API, that interface is inherited in https://github.com/KD-lab-Open-Source/Perimeter/blob/cmake/Source/Render/D3D/RenderDevice.h which is then finally implemented in https://github.com/KD-lab-Open-Source/Perimeter/blob/cmake/Source/Render/D3D/D3DRender.h