• Advertisement

Vilem Otte

GDNet+ Basic
  • Content count

    772
  • Joined

  • Last visited

  • Days Won

    2

Vilem Otte last won the day on March 23

Vilem Otte had the most liked content!

Community Reputation

3001 Excellent

4 Followers

About Vilem Otte

  • Rank
    Crossbones+

Personal Information

  • Interests
    Art

Social

  • Twitter
    VilemOtte
  • Github
    Zgragselus
  • Steam
    Zgragselus

Recent Profile Visitors

23825 profile views
  1. Images time! Yes. Although the quality impact will be huge (I intentionally let reflective sphere in view). Samples have 4x MSAA for deferred shading and 1x MSAA for cone tracing. Fig. 1 - 64^3 volume Fig. 2 - 128^3 volume Fig. 3 - 256^3 volume Fig. 4 - 512^3 volume Note, see how much Voxelization phase took. I intentionally re-voxelized whole scene (no progressive static/dynamic optimization is turned on). The computation is done on Radeon Rx 480 (with Ryzen 7 1700 and 16 GB of DDR4@3GHz if I'm not mistaken). Next image shows for comparison cone tracing with 8 random cones that have angle close to 0 (e.g. they're technically rays). Fig. 5 - Cones with small angle This is pretty unacceptable for realtime rendering, and I assume most GPU path tracers could beat the times for similar quality GI. As you noted, the time grows a lot. The only way how to trace these rays efficiently is to use sparse voxel octree (as octree can be used as acceleration structure for actual ray casting - yet the traversal even for rays is quite complex, and I haven't figured out any optimal way to perform cone tracing in octree - aside from sampling and stepping based on max. reached octree level). Here are some results, with highest resolution (512^3), no MSAA. Fig. 6 - 1 cone Fig. 7 - 5 cones Fig. 8 - 9 cones Note, you're now interested in GlobalIllumination in profiler. Which shows how much time was spent in actual cone tracing. The angles for cones were adjusted to cover the hemisphere. Which brings me to... So this won't make much sense in lighting result - as I intentionally used 9 cones (to have the same amount), but changed the angle - so I could demonstrate how angle can impact performance. Now you're again interested in GlobalIllumination in profiler: Fig. 9 - 9 cones, angle factor 0.3 Fig. 10 - 9 cones, angle factor 0.6 Fig. 11 - 9 cones, angle factor 0.9 Now here is something important - angle factor for me is cosine of half of the apex angle (ratio between radius and height of the cone). You can clearly see that the higher angle factor we have, the higher performance there is (as less steps in cone tracing loop are performed). So, this will be a bit complex. I don't render at half resolution, I do always render at full - but I do have MSAA support for my deferred pipeline, and let me show you example: Fig. 12 - 1x MSAA cone tracing, 4x MSAA rendering Fig. 13 - 4x MSAA cone tracing, 4x MSAA rendering You will probably need to take those images and zoom on them (and subtract in GIMP or other editor of your choice). There is some small difference on few edges (where object in the middle intersects with floor F.e.). There are multiple ways how to do this: Using a simple filter that looks at X neighboring pixels and finds most compatible depth/normal - and selecting according GI sample is a good way to go. Bilateral upsampling etc. Notes I tried to simulate some real-world scenario (with brute-force recomputed voxels), it uses 1 point light and 1 spotlight - both with PCF filtered shadow maps (in first 4 samples I've used PCSS for spotlight). Shadows is computed dynamically (I have virtual shadow maps implementation). All the surfaces are PBR-based materials, reflective surface is using same material as all the others visible. Some objects have alpha masks, transparency is handled using sample-alpha-to-coverage There is some post-processing (filmic tone mapping and bloom) Rendering is done using deferred renderer (in some cases with 4x MSAA enabled, buffer resolve is done AFTER tone mapping step, at the end of the pipeline) Renderer is custom Direct3D 12 based, whole engine runs on Windows 10 Hardware, as metnioned before: Ryzen 7 1700, 16 GB of DDR4 RAM and Radeon Rx 480 - if you want full exact specs I can provide There is some additional overhead due to this being an editor, and not a runtime (teh Imgui!), which is why I intentionally showed profiler - which measures time GPU spent on specific part of the application I'm quite sure I forgot some details! EDIT: And yes 1st thing I forgot, probably one of the most important ones. The actual reflection (specular contribution) is calculated in completely separate pass. That is named Reflection. It always uses just a single additional cone per pixel (and yes all objects do calculate it!). This shows the reflection buffer.
  2. I see, so Photoshop does just replace alpha layer by 255 - are your normal maps normalized right after you replace your alpha by 255, or do they require normalization?
  3. First. I apologize - especially to the moderators - for sending post with large images (yet it's necessary to explain what is going on). Hearing about you using image editor - I know where the devil is, I'm using actually Gimp, and there is one problem -> Alpha channel contains height. This is what image looks like in Gimp (I'm using Ceiling as example): De-composing this into channels gives you these 4 images (Red, Green, Blue and Alpha): You need to decompose to RGBA, and then compose just from RGB (e.g. set alpha to 255) to obtain a normal map. Look at 2 examples, in the first one I set alpha to 255 and re-composed image. In the second one I just removed alpha: I assume you recognize the second one. Now to explain what is going on - you need to look at how software removes alpha channel from the image. Now I will quote here directly from GIMP source code (had to dig there a bit). The callback to remove alpha is this: void layers_alpha_remove_cmd_callback (GtkAction *action, gpointer data) { GimpImage *image; GimpLayer *layer; return_if_no_layer (image, layer, data); if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer))) { gimp_layer_remove_alpha (layer, action_data_get_context (data)); gimp_image_flush (image); } } So what you're interested in is - gimp_layer_remove_alpha - procedure. Which is: void gimp_layer_remove_alpha (GimpLayer *layer, GimpContext *context) { GeglBuffer *new_buffer; GimpRGB background; g_return_if_fail (GIMP_IS_LAYER (layer)); g_return_if_fail (GIMP_IS_CONTEXT (context)); if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer))) return; new_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0, gimp_item_get_width (GIMP_ITEM (layer)), gimp_item_get_height (GIMP_ITEM (layer))), gimp_drawable_get_format_without_alpha (GIMP_DRAWABLE (layer))); gimp_context_get_background (context, &background); gimp_pickable_srgb_to_image_color (GIMP_PICKABLE (layer), &background, &background); gimp_gegl_apply_flatten (gimp_drawable_get_buffer (GIMP_DRAWABLE (layer)), NULL, NULL, new_buffer, &background, gimp_layer_get_real_composite_space (layer)); gimp_drawable_set_buffer (GIMP_DRAWABLE (layer), gimp_item_is_attached (GIMP_ITEM (layer)), C_("undo-type", "Remove Alpha Channel"), new_buffer); g_object_unref (new_buffer); } No need to go any further in the code base. As you see, image background is obtained in RGB format from RGBA, the: gimp_context_get_background gimp_pickable_srgb_to_image_color If you would dig in these functions a bit (and you would need to also dig a bit in GEGL), you would find out that the operation actually done when removing alpha is: R_out = R_in * A_in G_out = G_in * A_in B_out = B_in * A_in Such image is then set as output instead of previous image (rest of the functions). Now, I can't tell for Photoshop (I've worked with Gimp quite a lot so far) - but I'd assume they do similar, if not the same transformation. So you're out of luck using it for conversion. What you actually need as an operation is: R = R_in; G = G_in; B = B_in; l = sqrt(R * R + G * G + B * B); R_out = R / l; G_out = G / l; B_out = B / l; Something as simple as this. This can be done in python for Gimp as plugin F.e.
  4. I have implemented basic first-order temporal filtering. It is as simple as: next_value = prev_value * alpha + curr_value * (1.0 - alpha) Here is a video showing different alpha parameters (0.5, 0.9 and 0.99) - I just went ahead, recorded it and uploaded it (I intentionally left just bottom plane of sponza with collider - so boxes can intersect with sides of the scene): This requires additional input though - parameter which has high impact on flickering reduction, but also impact on how outdated the other information for filtering is. This is especially visible with 0.99, as the GI just doesn't seem accurate for given frame! See the reflecting sphere, it works to some extent - but ray tracing reflection is vastly superior (with additional huge problem - acceleration structures for dynamic scenes, even though I have high performance GPU ray tracer - it's good only for static scenes). The problem with cone tracing and sharp reflections is resolution of your voxel buffer. Using sparse octree helps a lot there (but the construction and actual cone tracing are quite heavy on performance - yet compared to ray tracer, doable for dynamic scenes). I don't, although for a while I consider adding it - especially as I use Direct3D 12, and you have Tiled resources there (which is a possible huge advantage).
  5. I'd personally advise against doing DCC (Dynamic character controller) unless you have very good game design reasons for it. Implementing KCC (Kinematic character controller) is just better at representing characters in general. Generally - a character, like animal or human - shouldn't be handled as physics body (by applying friction & forces). EDIT: To answer questions: 1. I'm using KCC for generic characters (e.g. human or animals) - always pushing the body around 2. I've used physics only in case of special physics characters (like using a rolling ball attempting not to fall down from obstacles you're rolling on - this is one case of the games where using DCC is viable and part of game design 3. Tricky question - this may depend on actual implementation. When was the time I had no physics engine available - I used simple ray casting and sliding along the walls (like in Quake/Half Life). So you couldn't lag in the wall... Same approach can actually be used with any current engine - ODE, Bullet, PhysX, etc. In short - if your character movement doesn't feel natural - you're doing something wrong here. 4. F.e. for car I actually use a car-like physics (as dynamic physics object) - there are 2 models used - either raycasts for wheels + rigid body (simple vehicle) or more complex simulation involving actual motor, wheels (as 'cylinders' F.e.), and rigid body jointed to them. Why would character change up vector orientation on terrain (unless it's spherical, where it always points away from center of the planet)? 5. Set vertical velocity.
  6. Stuff

  7. But wait, these don't seem like normal maps at all?! Are you sure you picked correct PBR images for Sponza and used them correctly - check my curtain normal map: For the sake of completness, another one:
  8. @JoeJ My feelings about VXGI are somewhat mixed (and you may remember me implementing it here on DX12, and it's actually one of the features in my engine now). First, shameless self-promotion: And I recommend looking carefully to the video, as it may show a lot of flaws for VXGI (and why my feelings about it are mixed) - and yes it also uses reflections from cone tracing: Noise - clearly visible, this can be solved (to some extent) with temporal filter Resolution - in this case it is quite high (note sharp reflection in the sphere), although it's important to note that this is a limiting factor Scale - hand in hand with resolution, your scale for voxel volume is going to have significant impact on quality of GI, obtaining lightmap-like results is possible, but requires careful handling Octrees (SVO) - significantly reducing amount of memory used, yet significantly increasing traversal cost. Not worth it, 3D texture outperforms it literally every time and large-scale scenes are performance heavy to build SVO from Generation - changing lighting or moving around objects will result in re-generation (or at least some amount of computation) among voxels. This may be costly, depends on the scene complexity (that intersects voxel volume of course). Anisotropic voxels - not worth it. Increasing resolution is easier way around, with better results which doesn't increase computational complexity. Static vs. Dynamic - generally pre-computing static data and then inserting dynamic is worth it. Requires additional 1 bit flag though. Compared to other GI solutions I've tried (that have to be mentioned - and were somewhat successful on my side): Reflective Shadow Maps (RSM) - no secondary shadows, somewhat good performance, but it doesn't look nearly as good, VXGI is superior Imperfect Shadow Maps - extension of RSM with secondary shadows, insane fillrate; beats VXGI in some cases Light probes - very good looking when mixed with light maps; the downside are lightmaps (precomputing!), beats VXGI for static scenes (when with lightmaps) Path Tracing/BDPT (realtime) - ground truth for me (I did multiple GPU implementations - mega-kernels and batched), getting this run in realtime is real challenge (requires good GPU ray tracers) Realtime Radiosity - a sort of lightmap solution that is updated progressively each frame (e.g. you update part of your lightmap), it works to somewhat semi-dynamic scenes with low resolution maps The downside of any lightmap or radiosity solution is that you need to somehow unwrap your scene into actual lightmap - which I always found to be somewhat problematic. I'm often deciding like this (when picking GI solution for project): Is your scene static - then use lightmaps (or sort of lightmaps) Is your scene mixed of static and dynamic - light probes and lightmaps, if possible Is your scene dynamic and small - VXGI/ISM Is your scene dynamic and big - Impossibru ... you either think off a good way to fake it, or avoid GI (although note that for big dynamic scenes and performance - GI will most likely be your last problem) This depends on what your goal is. If it is to actually research GI - then it's definitely not wasted time. If you just want to implement them to compare, then well... unless you implement other techniques as a hobby (in which sense - you voluntarily pick to waste your time this way) or from professional point of view (i.e. to have something else to compare your research against for exactly same given conditions) they yes - you will most likely waste your time.
  9. CPU Raytracer

    How do you calculate GI and AO (it seems quite smooth to what I'm used with unbiased rendering)? Can you give us some bigger screenshot (full res - like FullHD)?
  10. Problems with starting out on linux

    This is terribly wrong statement. Whenever you work on your own bigger engine, one of the core features towards releasing a game is often an editor (unless game content is generated in runtime)!
  11. As I have experience in more - Unity (and other game engines) and custom game engines - I can clearly state that any non-custom engine is restrictive at some point. You can clearly figure it out by attempting to add some specific feature in Unity (Such examples being as small as adding Voxel Global Illumination - and I know there is an implementation around, but it is extremely limited ... compared to custom engine implementation). Yes there is a way to work around, but it often takes multiple headaches with Unity ... or as big as large terrain rendering). In the end it all gets down to: Do you have resources to produce and maintain custom game engine? This often means spending hours and hours weekly on engine. Including (for some people) very annoying parts where you work with internals - which isn't really visually rewarding in any way. What advantages will custom game engine give to you? This is not necessarily saving money (because it will most likely get far more expensive than using already built engine). But do you require specific features and high performance? Then custom engine may be something for you. What are your time options? If you're in a hurry (doing a game jam, or such), custom engine can provide large disadvantages due to missing features. While Unity or others might already have those ready made. Simply because they are far bigger projects. An example can be F.e. this: This is my engine in action - PBR rendering, Voxel Global Illumination re-calculated every frame (therefore noise), MSAA and deferred shading (multiple lights), Virtual shadow mapping, Physics, Dynamic cone-traced reflections, Instancing, etc. etc. (A very long and exhausting list of features). All this is recorded in editor (UI is fairly simple through ImGui but it is enough for the purpose I need). Average framerate is over 60 fps (with recording on ... and 4x MSAA for every single buffer up to resolve AFTER tone mapping - hence huge bandwidth usage). Average CPU usage with the physics is well under 5% (whole engine is multi-threaded, and uses all 8 cores of Ryzen CPU on which I've ran this). So why am I describing all this? Compare with this - https://ldjam.com/events/ludum-dare/38/run-u-fool - and I recommend, try both - WebGL and Desktop builds. Shattering objects can't be activated at once (due to performance reasons), there is far less graphics effects and far less actual logic for CPU (it runs as a runtime, not as an editor). It is not just the performance difference, but also GI and other features which are hard (if not impossible) to achieve with Unity. Yet can be well optimized in your custom game engine.
  12. DX12 DirectX12 adds a Ray Tracing API

    @NikiTo A real mirror test (might have some params wrong in traversal - so no guarantees I don't lose energy somewhere! Some hard coded exposure value has been used too!). As for noise/removal - you can't. You won't be unbiased anymore. Also this will damage texturing, details of indirect illumination, etc. What OptiX does for noise removal is a lot more complex, and it still is visible and introduces more problems. This is due to nature of such noise and how the noise data is created. EDIT: OptiX denoiser - http://research.nvidia.com/publication/interactive-reconstruction-monte-carlo-image-sequences-using-recurrent-denoising
  13. DX12 DirectX12 adds a Ray Tracing API

    This happens simply due to 1 thing - perfect mirror does NOT exist. And if your parameters for materials in unbiased renderer of your choice are correct, you will be able to see exactly the same phenomena after certain number of samples per pixel. Note. that in unbiased path tracing - you will terminate your ray eventually (Russian Roulette). Infinite mirror (analytical) isn't really possible due to infinite number of iterations in your path that would be needed to resolve.
  14. DX12 DirectX12 adds a Ray Tracing API

    Path tracing can be interactive (even real time) to some extent. The biggest problem is noise though (you will be able to do just few samples per pixel). In directly lit areas you're quite okay, but once you're in indirectly lit part - there is a lot of noise. Let me just shoot random example here:
  15. Voxel grid traversal algorithm

    Looks good! You need to use higher precision in render targets (low precision results in banding which can be clearly visible in part which is in shadow). Generally GI means you definitely need to use HDR render targets - with tone mapping and eye adaptation. Also I don't see any light bleeding from curtains - shouldn't there be some? (I know I have it a bit overdone in mine) I assume you're using texture now, and not octree - correct?
  • Advertisement