Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (769)
Games in Android Showcase (230)
games submitted by our members
Games in WIP (856)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 ... 204 205 [206]
  ignore  |  Print  
  What I did today  (Read 2906563 times)
0 Members and 2 Guests are viewing this topic.
Offline Sickan
« Reply #6150 - Posted 2018-10-10 18:55:44 »

Today I finished the 3D camera, now on to adding height to the map terrain.

Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6151 - Posted 2018-10-12 18:06:01 »

On my way to do hierarchical occlusion culling on the GPU using compute shaders, guided by the scene's kd-tree.
Here is a video showing only hierarchical frustum culling:
<a href="http://www.youtube.com/v/FNuqvgHlrz8?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/FNuqvgHlrz8?version=3&amp;hl=en_US&amp;start=</a>
(notice how the culled areas become larger the farther away the camera is from a particular node)
Also, the frustum the culling uses is smaller than the camera's frustum to show the effect.
So, how does it work:
- The CPU (Java, that is) initially assembles a list of kd-tree nodes at level N (where N is really small) very quickly and submits that to the compute shader via a SSBO
- At every pass, the compute shader reads in that list, performs culling, and writes the visible nodes into an output SSBO
- Those two buffer bindings ping-pong between each other
- An atomic counter buffer is used to record the actual number of written nodes in each step, which will be the input for the next step (stream compaction with parallel prefix sums is absolute overkill for these very small amount of nodes) (I've also implemented warp-aggregated atomics in GLSL only to see that the GLSL compiler seemingly does this automatically already (as is mentioned in the article for nvcc))
- The last pass is used to write MultiDrawArraysIndirect structs for the voxels in the visible nodes to a separate SSBO (the voxels SSBO containing all voxels is built in such a way that all voxels within any kd-tree node are contiguous, so that it is easy to generate a MultiDrawArraysIndirect when only having a kd-tree node, which contains the index of the first voxel it or its descendends contain along with the number of voxels)
- This last SSBO is then used as the draw indirect buffer for a glMultiDrawArraysIndirectCount() call together with the number of draw call structs stored in the atomic counter buffer, which becomes the indirect parameter buffer

Here is the compute shader doing the culling:
https://gist.github.com/httpdigest/15399efe2b60a2b31d1c2cbe414ce5cf
and here is some portion of the host code driving the culling:

Next will be what will bring the most benefit for this highly fragment shader and ROP bound rendering: Combining Hi-Z occlusion culling with the hierarchical frustum culling. This means that Hi-Z occlusion culling will also be done hierarchically, starting with a coarse kd-tree node level and refining the nodes when they are visible. The reason why I am doing frustum culling on the GPU is: Hi-Z culling has* to be done on the GPU and doing it hierarchically through the kd-tree will benefit from fewer nodes to be tested.

*that's not entirely true, since there are games out there using a software rasterizer to cull on the CPU
Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6152 - Posted 2018-10-13 21:45:42 »

Today was an interesting day, as I had witnessed how two parts of the rendering pipeline competed for being the major bottleneck when applying two slightly different techniques of voxel rendering.
The first technique was rendering point sprite quads covering the screen-space projection of the voxel, as presented by: http://www.jcgt.org/published/0007/03/04/
The second technique I came up with was to use the geometry shader to compute and generate the convex hull of the projected voxel with the help of this nice paper: https://pdfs.semanticscholar.org/1f59/8266e387cf367702d16acf5a4e02cc72cb99.pdf
While the first technique produces a very low load on vertex transform/primitive assembly, it suffers from many additional fragments being generated for close voxels, where the quad enclosing the screen-space projected voxel contains a large margin/oversize to a) still make it a quad and b) cover the voxel entirely. This produces a higher load on fragment operations (fragment shader doing the final ray/AABB intersection and likely more importantly the ROPs reading/comparing/writing depth and writing color).
Now my idea was to reduce fragment operation costs by reducing the amount of excess fragments the quad produces, by not making it a quad anymore but a perfectly fit convex hull comprising either 4 or 6 vertices.
Having heard many bad stories about how geometry shaders perform, I still gave it a try and I was positively surprised at an increase of roughly 21% in total frame time when generating the fragments with the convex hull for close voxels.
Here, the cost of fragment operations was reduced to a point where this wasn't the bottleneck anymore, but: vertex operations (passing the GL_POINTS to the geometry shader and there emitting a single triangle strip of either 4 or 6 vertices) now were. One could literally see how for moderately far away voxels where the screen-space quad had little oversize/margin, the quad rendering solution overtook the convex hull geometry shader solution.
The latter however was ideal for close voxels. So, it's going to be a hybrid solution in the end.
Here are some images and a video showing the overlap/margin of the point sprite quad rendering and the (missing) overlap of the convex hull rendering:

<a href="http://www.youtube.com/v/7TFKwAUZ0qE?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/7TFKwAUZ0qE?version=3&amp;hl=en_US&amp;start=</a>

Convex hull generation geometry shader: https://gist.github.com/httpdigest/fa7e071b87ca24b0a54fe0821e3c1a60
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline NuclearPixels
« Reply #6153 - Posted 2018-10-16 14:35:53 »

Not much to show, but have been modifying the core of the game to integrate YAML configuration instead of hardcoded classes, managed to reduce the code base by ~1.8k LoC (the solution looks much cleaner now), at cost of ~500 YAML lines. YAML configuration is used as a base when something is being setup, for example a unit is initialized from the following configuration:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
name: "archer"
attackDamageMax: 25.0
attackDamageMin: 15.0
attackRangeMax: 30.0
attackRangeMin: 10.0
attackRangeStdDev: 2.0
attackSpeed: 4.0
collidables:
  - !circle { x: 0, y: 0.725, radius: 0.75 }
defense: 0.0
fireableProjectiles:
  - ARROW
lifePoints: 100.0
movementSpeed: 2.0
operators: []
plunderCapacity: 20
price: 50
recruitable: true
recruitmentCooldown: 15.0
stamina: 100.0


Besides being cleaner, I have prepared the ground to be able to reaload the configuration once the game in debug mode, which is super useful in my opinion when for example it is required to tune object hitboxes and balance the game. I plan to make available both YAML examples and console-like widget I have built for the debug mode of my application.

Learning and having fun developing games. Twitter: https://twitter.com/NuclearPixels
Offline ral0r2
« Reply #6154 - Posted 2018-10-16 16:08:35 »

Created a dynamic door / key event system, which basically allows me to alter tiledmaps during runtime.
For instance I can change blocked values from true to false when the player contains a certain item.

The class responsible contains methods such as:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
public static void setDoorPropertyToBlocked(GameMap map, String id) {

      int max = map.getTiledMap().getTileSetCount();

      for (int i = 0; i < max; i++) {

         int firstgid = map.getTiledMap().getTileSet(i).firstGID;
         int lastgid = map.getTiledMap().getTileSet(i).lastGID;

         for (int a = firstgid; a < lastgid; a++) {
            Properties properties = map.getTiledMap().getTileSet(i).getProperties(a);

            if (properties != null && properties.getProperty("door") != null && properties.getProperty("door").equals(id)) {
               properties.setProperty("blocked", "true");
            }
         }

      }

      reloadDoorEvents(map);
   }


This method basically changes the blocked value of a certain door event (matched by an id) from unblocked to blocked.
The reload door event method then parses the map again and adapts changes:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
private static void reloadDoorEvents(GameMap map) {
      for (int xAxis = 0; xAxis < map.getTiledMap().getWidth(); xAxis++) {
         for (int yAxis = 0; yAxis < map.getTiledMap().getHeight(); yAxis++) {

            int tileID = map.getTiledMap().getTileId(xAxis, yAxis, 0);
            String doorBlocked = map.getTiledMap().getTileProperty(tileID, "blocked", "false");
            String door = map.getTiledMap().getTileProperty(tileID, "door", "false");

            if (!door.equals("false")) {
               map.getBlocked()[xAxis][yAxis] = Boolean.valueOf(doorBlocked);

               if (map.getBlocked()[xAxis][yAxis] == true) {
                  Rectangle temp = new Rectangle(xAxis * 32, yAxis * 32, 32, 32);
                  temp.setLocation(xAxis * 32, yAxis * 32);
                  map.getBlockedList().add(temp);
               } else {
                  Iterator<Shape> iterator = map.getBlockedList().iterator();
                  while (iterator.hasNext()) {
                     Shape shape = iterator.next();
                     if (shape.getX() / 32 == xAxis && shape.getY() / 32 == yAxis) {
                        iterator.remove();
                     }
                  }
               }
            }
   }


This methhod gets invoked by something I a call keyevent, which activates as soon as the player hitbox touches it:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
@Override
   public void onActivate() {
      if (InventoryController.getInventory().checkIfItemWithNameInInventory("Dungeon Key")) {
         Item toRemove = InventoryController.getInventory().getItemByNameInInventory("Dungeon Key");
         InventoryController.getInventory().removeFromInventory(toRemove);
         TiledMapModificator.setDoorPropertyToUnblocked(getCurrentMap(), doorID);
         onActionSound.play();
         PopupMessageController.activatePopupMessage("You used a key.", this);
         this.setActive(false);
      }
      else {
         PopupMessageController.activatePopupMessage("I need a key for that.", this);
      }

      return;
   }


In the editor it then looks like this:



The blue one is represtenting the door and the purple one the key event.
Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6155 - Posted 2018-10-16 20:17:36 »

Got an idea today for how to efficiently determine the set of actual visible voxels for gathering/caching irradiance only for those visible voxels. Will write a detailed description later. Here is a video highlighting the visible voxels captured at certain points:
<a href="http://www.youtube.com/v/0xMQYkvWGJc?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/0xMQYkvWGJc?version=3&amp;hl=en_US&amp;start=</a>
Offline h.pernpeintner

JGO Ninja


Medals: 100



« Reply #6156 - Posted 2018-10-18 09:29:03 »

Super nice debugging tool Kai Cheesy That's something I always skip because of time pressure. Of course I pay the price of this later most times.
Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6157 - Posted 2018-10-18 12:11:21 »

Thanks. Visual debugging is definitely important, and I was just tired of trying to analyze glGetBufferSubData() numbers.
As for time to do it: Up till now this is not becoming a strong factor for me. I don't have any abstractions in the code, neither do I factor out common code or parameterize those in any way. Always copy/pasting from a previous demo and applying slight modifications is just so much faster. Also, I try to keep the programs single-file and as small as anyhow possible to quickly iterate different ideas. Only shader sources need additional files. This is why I am really looking forward to Java 12 becoming a thing with (multiline) raw string literals, so that a whole demo/example can indeed be one file (without having to resort to multiple concatenated "blabla\n" strings of course).
Offline h.pernpeintner

JGO Ninja


Medals: 100



« Reply #6158 - Posted 2018-10-18 13:00:06 »

Thanks. Visual debugging is definitely important, and I was just tired of trying to analyze glGetBufferSubData() numbers.
As for time to do it: Up till now this is not becoming a strong factor for me. I don't have any abstractions in the code, neither do I factor out common code or parameterize those in any way. Always copy/pasting from a previous demo and applying slight modifications is just so much faster.
There are only very few cases where the right abstraction doesn't give you more development speed. Finding the right abstraction that doesn't make small changes harder is a different topic though. I was thinking just like you, some time ago in my own engine, before I took the discipline to do some "proper programming" and not another bunch of hacks. It was so worth it. The more often one does it, the better one gets at it and the more one realizes how much it is worth Smiley

Also, I try to keep the programs single-file and as small as anyhow possible to quickly iterate different ideas. Only shader sources need additional files. This is why I am really looking forward to Java 12 becoming a thing with (multiline) raw string literals, so that a whole demo/example can indeed be one file (without having to resort to multiple concatenated "blabla\n" strings of course).
I have a system that uses a file listening mode for auto reloading and runtime compiling shader code - how would you get this when you have all your shaders as static strings somewhere in your classes? Or don't you need runtime recompilation on change?
Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6159 - Posted 2018-10-18 13:12:08 »

Yes, when you arrive at some point where you know which parts will change and which parts won't, then it is benefitial to do abstractions. But I certainly haven't reached this point yet. Any new technique I might discover might make me throw away most of the code anyways. It is only after you decide on a certain "architecture" (rendering pipeline, capabilities, flexibility/pluggability, etc.) of your engine, that you can start organizing your code in such a way that changes to moving parts become easy while changes to static parts (which you anticipate to not change often) become harder.
I've just recently used a very hacky Java Preferences way of storing and loading presets of window size/position and camera position and orientation to allow for performance comparisons between code changes.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline h.pernpeintner

JGO Ninja


Medals: 100



« Reply #6160 - Posted 2018-10-18 15:48:32 »

What about my question regarding the hot reloading of shader files? Smiley
Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6161 - Posted 2018-10-18 15:56:29 »

Reloading of shaders at runtime sounds nice, definitely. With static (constant pool) strings this will of course not work. Most changes I had to do in the shaders also involved host/shader interface changes, especially when trying to find an optimal SSBO memory layout for BVH and kd trees. I had to play around with that a lot. So runtime reloading of shaders was simply not something I needed to look into in the past.
Offline philfrei
« Reply #6162 - Posted 2018-10-18 20:36:15 »

I got a "Power Chord" patch working as an option for the PTheremin yesterday.

Basically two sines, a perfect fifth apart [hmm, guitars generally use equal temperament instead? maybe, maybe not if they tune by using harmonics], with simple clipping, with a parameter available for real time interpolatione between the clip and the sine. It sounds decent, not ideal.

I tried a couple other nonlinear equations given by DspRelated and CCRMA, but neither were radical enough.

Not finished, though, as the aliasing is over the top. Am going to work on implementing a low-pass filter. My audio engineering friend points out I made need to over-sample to get enough filtering that doesn't also compromise the basic tone.

music and music apps: http://adonax.com
Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6163 - Posted 2018-10-19 12:14:34 »

Having seen that on Nvidia drivers glGetProgramBinary also outputs the ARB_vertex_program/ARB_fragment_program/NV_gpu_program4/5 assembly text, I begun learning the NV_gpu_program4 assembly language and reading about low-level shader optimizations (MAD instead of MUL and ADD, using negation on instructions operands instead of negating the result, etc.) to squeeze the most performance out of it.
EDIT: Hit exactly this GLSL compiler bug now: https://devtalk.nvidia.com/default/topic/952840/bug-report-linker-error-when-indexing-dvec-in-an-unbounded-loop/
Plus, whenever I use bounded loops the time the compiler takes to compile the GLSL code is directly proportional to the upper bound of the loop..... So if I have for (int i = 0; i < 1024; i++) ... glCompileShader() actually does not end in foreseeable time... This makes me want assembly even more...
Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6164 - Posted 2018-10-21 19:30:09 »

Wrote a simple MagicaVoxel importer (so far only taking diffuse color into account) using this: https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox.txt
I think I am going to add imports of user-generated content for various kinds of props (with smaller scale than the world cubes). This way, authoring can be done in that wonderful MagicaVoxel tool and placing can be done in-game. Here are some 4K videos and still images of "in-game" rendering showing some of these MagicaVoxel models with ray-traced and irradiance-cached ambient occlusion:
<a href="http://www.youtube.com/v/aDsbeHF4C7w?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/aDsbeHF4C7w?version=3&amp;hl=en_US&amp;start=</a><a href="http://www.youtube.com/v/ah5BPomcNj4?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/ah5BPomcNj4?version=3&amp;hl=en_US&amp;start=</a><a href="http://www.youtube.com/v/ReagZ75sG2E?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/ReagZ75sG2E?version=3&amp;hl=en_US&amp;start=</a>
Offline mudlee

Junior Devvie


Medals: 6
Exp: 5 years



« Reply #6165 - Posted 2018-10-22 02:14:00 »

This one looks really promising. Is it done via opengl? Is it for your engine or just for fun?
Offline KaiHH

JGO Kernel


Medals: 629



« Reply #6166 - Posted 2018-10-22 09:50:51 »

Just a bunch of OpenGL/GLSL demos/experiments, no engine, just for fun.
Offline h.pernpeintner

JGO Ninja


Medals: 100



« Reply #6167 - Posted 2018-10-22 13:53:27 »

You f**king genius - looks really nice.
Pages: 1 ... 204 205 [206]
  ignore  |  Print  
 
 

 
EgonOlsen (1672 views)
2018-06-10 19:43:48

EgonOlsen (1709 views)
2018-06-10 19:43:44

EgonOlsen (1159 views)
2018-06-10 19:43:20

DesertCoockie (1585 views)
2018-05-13 18:23:11

nelsongames (1186 views)
2018-04-24 18:15:36

nelsongames (1709 views)
2018-04-24 18:14:32

ivj94 (2533 views)
2018-03-24 14:47:39

ivj94 (1758 views)
2018-03-24 14:46:31

ivj94 (2836 views)
2018-03-24 14:43:53

Solater (971 views)
2018-03-17 05:04:08
Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45

Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!