What I did today

Fair enough. I think UPS only really tends to be something that may need to be changed in the case of 3D games because the physics may need more updates to stay accurate. That was a big problem we had with We Shall Wake; we were constantly increasing the UPS because our characters were out running the physics systems. I think DEMO 7 ended up being around 276 UPS. Haha

I’ve seen the advice given by SkyAphid before, with a name that was something like a “magic numbers” pattern. The notion is that a number sitting in code is often meaningless for the code reader. Giving the number a name makes it both easier to read and to edit. So as a general practice, why not? (Because coming up with names for everything is bothersome.)


A little while back I decided to take a break from not working on the itch.io site for selling “Tone Circle Drone” and do some coding instead. I managed to make a new synth choice for the theremin: using vocal formants generated by FM. It’s a little tricky to say the least, and using a filter-based approach would have made a lot more sense, but I thought I’d try coding it anyway and see what happened.

Short version: the basic concept works! I can make smooth transitions between ooo to aaah to eee. If I have a chance, I’ll make a quick OBS video. It is pretty hilarious sounding. But it could also probably use some fine tuning–I might wait until I get a chance to experiment with some of the parameters.

Maybe publishing a Theremin would make more sense as a first opus. The ‘blocking’ I’m experiencing on TCD has been significant. There’s a bit more I want to do with the GUI but the application is close to ready. (Maybe add a “vibrato bar” via the spacebar.)

Had some fun with WebGL (actually I wanted to play with Webpack HMR and live-reloading shaders came to be the use-case) today being somewhat more productive at quickly prototyping stuff than with desktop Java. Tracing triangle meshes without any filtering yet:

Yes, it does look kinda crappy. :slight_smile:
Stuff used: WebGL 2.0, Webpack (+ integration with HMR to live-reload shaders without reloading the whole app/site such as with LiveReload), Typescript, gl-matrix, webgl-obj-loader.

Here’s a video of a small project that theagentd and I were commissioned to work on last October:

1yklZAPgamw

It’s a pretty cool application of our game engine outside of making actual games. It’s a shame it didn’t actually pan out for the people who requested it.

@SkyAphid amazing! Is it some kind of holographic effect? Or clever placement of leds?

The sides of the cuboid can just be thought of as separate monitors and then when knowing the position of the viewer, you calculate appropriate perspective projections and view transformations for each monitor.
This can be achieved with this, which I guess they are using :wink: https://github.com/JOML-CI/JOML/blob/master/src/org/joml/Matrix4f.java#L14101
This is also what people do with CAVE systems.

Yep, we used JOML to do the heavy lifting on the math. Thanks Kai!

Hi - Thought I’d show the vowels that are now working on the digital theremin. I’m using FM, not filters. Filters would probably make a lot more sense, but FM is the technology that I know best. I think it was Alan Benson Bill Schottstaedt who mentioned the possibility of using a sort of inverted arrangement, where the carrier is a high harmonic and the modulator is the root pitch. The tricky part, then, becomes, picking the harmonic to the root that is closest to the desired formant pitch. I did this by “bracketing” the formant with the nearest two harmonics, and adjusting their volumes based on how near or distant they were to the desired formant pitch. It seems to work pretty well, and could probably be improved upon.

I am just learning to use OBS, and didn’t want lack of confidence or skill with video presenting or the OBS software to prevent me from posting. So, don’t expect a slick video!

Vowels on PTheremin

Above is a link to the .mp4 file.

@philfrei This is pretty cool stuff, Phil! Would very much like to try this out (I’m an avid fan of Tangerine Dream and the likes, so fiddling with a synth app (as I see it) is always fun). It would also be great if you could make another version for touchscreen, where you have something like different coloured clouds of particles against a black background, that expand/change when you touch them and produce different sounds. Well, that’s just an idea.

Implemented platforms successfully to my game:

Today I wanted to do something with a binary BVH built using Z-order curve (i.e. Morton Code) partitioning and I searched for something that would really fit it: And that would be “minecrafty” terrains with small axis-aligned cubes. So here is a 1024x1024 cubes level completely ray-traced at ~300FPS using a custom BVH traversal with an OpenGL compute shader and with a small 32-bit bitstack to track whether the far or near child was visited, and whether that was the left or right child of the node:

mJHOQ8vIfHA

Code: https://github.com/LWJGL/lwjgl3-demos/blob/master/src/org/lwjgl/demo/opengl/raytracing/CubeTrace.java

EDIT: Okay, heightfields are boring. Density fields are much more interesting. 1024x1024x64 level with cubes generated using Simplex Noise density field:

5BecrNtud0o

Got any ideas for a game? :slight_smile:

EDIT2: Stress Test: 25.893.821 cubes/voxels

X49o5q9zoPw

[/size][quote]Today I wanted to do something with a binary BVH built using Z-order curve (i.e. Morton Code) partitioning
[/quote]
Ah yes I understand exactly what you’re saying. Perfectly.

what does it mean?? :slight_smile:

Really nice videos, thanks for sharing. Can your storage method or world-building formula cope with 4 dimensions? Would be really cool to add time as the fourth dimension and see the big lumps move about. They reminded me of blood cells.

@KaiHH - Wow!

I’ve always wanted to set up something where one could navigate through a noise-generated space like that. Was playing with a very naïve version using JavaFX 3D the other day, a lattice of spheres whose size depended upon the OpenSimplex value. Did nothing (as I know nothing) special, just plunked the spheres into place. It was glacially slow.

Is this BVH the same format used for motion capture devices?

I wonder if you have enough granularity to get some nice structures by adding octaves (a la fractals), or maybe get crevices by using Perlin’s “turbulent” form.

I have a hard time imagining that there would be enough computing power to change these over time, as CommanderKeith asks. Would be cool if it were possible. But it would probably require a couple orders of magnitude more computations?

This should work with OpenSimplex, too, if there’s any worries about lawsuits over unlicensed 3D use of Simplex Noise.

[quote=“cygnus,post:6112,topic:49634”]
It means that we can have path-traced minecrafty worlds. :slight_smile:
This has also been done earlier by: https://raytracedminecraft.wordpress.com/

[quote=“CommanderKeith,post:6113,topic:49634”]
Currently, the noise evaluation and BVH building is done on the CPU. The most expensive part is the noise evaluation, even though I am currently only using one octave and it is already multi-threaded (I probably should not be using ByteBuffer.putFloat()…). But building the BVH is simple and blazingly fast. And using z-order curve partitioning even makes it parallelizable to run on the the GPU, which was my motivation in the first place (but first getting a working CPU implementation).
Next is to port that to compute shaders to sort the voxels and build the BVH bottom-up.

With this, it is quite possible to animate the voxels over time. See for example this: https://www.youtube.com/watch?v=-6jyt192pK0
In this case, you would likely use transform feedback to evaluate animation like usual with vertex weights, write them out to a buffer object and use that data to build a BVH.

[quote=“philfrei,post:6114,topic:49634”]
It is BVH as in “Bounding Volume Hierarchy” and not as in Biovisions BVH file format. So the Bounding Volume Hierarchy is a tree data structure (and in my case a binary tree - meaning each internal node has exactly two children) used to spatially index the scene geometry, so that each ray need not compute intersections with all the millions of cubes in the scene. Instead many cubes can quickly be culled when the ray does not intersect some bounding box encompassing the cubes.

[quote=“philfrei,post:6114,topic:49634”]
The granularity is currently one cube. Of course one could scale them down and simply use more cubes. :slight_smile:

Btw. I’ve experimented with rendering 41 million cubes at under 1ms. per frame using what is known in rasterization as “checkerboard rendering”. With ray tracing and compute shaders we can achieve the same thing by not compute each pixel every frame but one pixel within a 2x2 or 3x3 or 4x4 group. Since we can do scattered writes in a compute shader (which is impossible to do in a fragment shader on the framebuffer, so people generate fragments with clever layouting of triangles), we do not need to downscale the framebuffer but rather “stretch” the distribution of the rays using a fixed stride and a varying offset per frame. This way, we can issue less work items in a compute shader call and have zero thread divergence (no if (pixel-should-be-rendered) … else abort).

Here is a video rendering at over 1000FPS and showing 41 million cubes (the video itself is just 60Hz but the frametime of the presented rendering was just under 1 millisecond): https://www.youtube.com/watch?v=cXKpKrecvhc

EDIT: Improved the sampling pattern of the 2x2, 3x3 and 4x4 “alternating sampling” (I wouldn’t call it checkerboard sampling anymore) to be less apparent in animations. Now, it looks like motion blur, because samples from earlier frames stay visible until rewritten (it’s just not based on actual camera velocity). Also removed the high contrast red, green, blue color scheme. I somewhat got headaches from it after staring too long at it yesterday. So a nice grey. Here are some pictures where the sampling pattern are visible (camera flying forward quickly):

Video: https://www.youtube.com/watch?v=cFmT69ABwvA

Sorry for posting so much :slight_smile: but this is the first time I implemented mipmapped texturing in a ray tracer and it just looks much better with textures… oh and shadows of course

In the last one the camera moves forward quickly and with the alternating pixel sampling pattern it looks like motion blur in animation.
Frametimes in 4K resolution are about 2-3 milliseconds.

Next will be picking to remove and add blocks. I was thinking about how to do that without building the whole BVH tree anew.
The idea is that all voxels that were generated initially with the noise evaluation are linearly in a big SSBO (plus the BVH SSBO for traversal). Then in the Java program, we also keep the BVH structure and the voxels list around. When picking with the mouse we cast a ray in Java through the BVH and detect the hit voxel. This voxel was assigned a position/index into the SSBO originally when sent to the shader. We now only need to use a bitflag as part of a voxel data in the SSBO to “disable” that voxel. So everytime the user destroys a voxel, after the voxel has been identified we issue a 1 byte glBufferSubData() at the correct offset into the voxels SSBO and boom, the voxel is gone.

Now, adding voxels is a bit more difficult. Here, my initial idea is to actually have two BVHs and voxels lists. The first is for the initial voxels added through noise evaluation. The second is for all the additions the user makes to the world.
This means, that in the shader, we need to trace two BVHs. The second BVH structure is always rebuilt whenever the user adds a new voxel. This is no big deal, since the performance is really good up to about hundred thousand voxels.

Then, when fragmentation grows (more and more original voxels deleted and more and more user-added voxels) the two structures need to be rejoined at some point to result in an optimal BVH tree again. But that can be very very later in the process after thousands and thousands of voxels have been added and removed.

EDIT: Destruction with Picking (at t=38): https://www.youtube.com/watch?v=amoXTQP5ANs

EDIT2: I just recently switched from Fraps (which I used occasionally to record videos earlier) to OBS Studio (totally free), and… boy… Fraps is just soooo insanely slow compared to OBS. With OBS even recording in 4K at 60Hz is absolutely no problem. That’s probably why the Twitch streamers use it, but it can of course also stream to a file.

How could you apologize!!! Your work is amazing and I think it’s not only me enjoying all your posts here! Please keep em coming!

Have you considered using your voxelization for cone tracing global illumination (in smaller scenes) somehow? This is what I’m still very interested in, while everyone else talks about raytracing :smiley:

Very interesting idea to use voxel cone tracing. The acceleration structure is already there to hold the lighting and occlusion information and propagate it up. And the scene is already voxelized (since, yeah, they are voxels) :). Correct propagation and cone traversal could be challenging though due to the non-uniformity of the bounding volume hierarchy (splits at arbitrary positions in each dimension). An octree is definitely nicer in that regard. Or just using a 3D texture would also be an option. What I definitely like about VCT is the lack of noise as opposed to any Monte Carlo light transport solutions such as Path Tracing.
Currently I am determined to use MC solutions alone. Let’s see how far this can go, given that we have a nice discretized scene where storing all sorts of information at voxel or BVH node level is possible, such as “most likely” direction of a nearest light source for next-event estimation or storing portals (when people dig caves with a small entry where light comes through). Or just using the voxels for irradiance caching, so accumulating samples on a voxel (instead of screen space with sample reprojection) over time. Definitely lots of possibilities there. :slight_smile:

Ah, yes, I didn’t think about the non-uniformity, of course this is a problem. Irradiance caching would be also very interesting of course - but another idea: What about adding a large uniform grid , that saves per cell n voxel indices that point directly into your bvh. Based on them, one could precompute environment lighting for unpopulated cells in order to be able to light dynamic objects that aren’t voxelized, similar to how precomputed radiance transfer volumes do it, but without precomputation of the lighting, but only the visibility. Advantage of precomputed visibility only is, that materials/color of the voxels can change and nothing has to be recalculated :slight_smile: Also, the precomputation is valid until the bvh changes, and then it could be precomputed as well. Not sure about the sample count/need for screen space filtering afterwards with low sample count.

EDIT: We have light leaking again then, that’s for sure.

Added a second bounce for nice soft shadows, and sample reprojection (also called temporal filtering) to reduce noise.
Basically I just throw all the stuff at it that I already built earlier for other demos: