With Visual Studio 2012 Microsoft dumped the DirectX SDK, and the effects library with it( along other things), which I needed for my engine.
To compensate for that, I wrote some code to load an xml file that describes the outputs and inputs of the shaders, just like the .fx files used to do.
Having that working, I realized xml is a bit too cumbersome for that use, and coming up with some small language will speed up development time, plus, I've always wanted to write a parser/compiler/vm.
Before starting with it, I decided to try to do something smaller first, something to parse/execute a kind of assembly code meant to run embedded in an application.
So after a lot of coding, and messing with regular expressions, I finally managed to get it working. 
The parser can load code like this:
and produce a memory representation that the vm can execute. The example above adds in parallel two arrays of floats, and stores the result in another array. 
The vm code runs from 10 % to 20 % slower, which isn't that bad for a simple implementation. Ok, so now some code! I won't put the VM, as it is a lot of code, but I'll put the parser.

Parser:

So I finally got to work again in the particles simulation, and I made some advances. Mainly, fixing the displacement of the particles and adding a "pseudo z culling" step. Actually, what I'm doing is compare the distance of the sample to the camera with the distance of the scene to the camera, and only add the sample to the final color if the distance is smaller.
Oh, I forgot. I also optimized part of the voxel update code, so I'm now using 80.000 particles at 90 - 110 fps. Quite nice!
There are things to do though. First of all, add some shading, maybe even shadows. I have other thing in mind, that I mentioned earlier, regarding compression of the voxels ( particles are sparse after all right? ) but it still needs some more work.
For now, here are some screens:





Working on a parser the other day, I decided to use the new <regex> library in C++ 11.
It's awesome, once you get to know the regex sintax. To make development faster, I coded a couple functions. They are nothing fancy, but they speed up my workflow.

Well, after a lot of fighting, I managed to get the volumetric render working. I'm using a 128*128*128 3D texture, and then I raymarch it in a compute shader.
The results are quite good actually. I'm getting around 140 - 170 FPS with 40.000 particles (!).
There are things to fix though. Mainly, the voxel appears to be displaced from the real center, and the rendering against the scene ( can't do Z-Buffering just like that ) leaves a lot of room for improvement.
Next things to do, fix that, add proper lighting, and then I'll pass to one idea of mine, which involves hash-maps and voxel compression...

Some screens:




So, the other day I decided I wanted to try to add particles to my engine. I already have PhysX ( 3.3 beta ) working, so I grabbed the documentation and started from there. The documentation includes a guide that it's really complete, so it just took me a couple hours to get it working.
For rendering I'm using the most naive implementation possible : draw a cube for each particle, with one batch per particle. Really slow, but still, I manage to get 80 fps with a GTX 480 and a i3 @ 3.65 GHz in a simple scene (5000 triangles + 36*4000 of the particles)  with 4000 particles, simulated in the GPU, courtesy of nVIDIA.




Next stop, volumetric rendering using voxels.
Another of the great things added in C++11 was the random library. It provides a bunch of facilities to create random numbers, way better than the C rand().
As it happens a lot of time, its use is cumbersome, compared to the good old rand(). As I use a lot of random numbers in my code, I came up with a couple templates that make life easier, and which I'm sharing today:
As a side note, the min and max limit are inclusive. 

Random integer from 1 to 9:
randNatural<int>(1,9);

Random double from 0 to 1:
randReal<double>(0,1);

Here I present what I like to call a "Dynamic Struct".
The idea is to have a struct that you can define at run-time, and get the elements by a string.
What's the use, you might ask? Well, my reason to do this is to have a way to define a constant buffer in a text file, load and update it in the C++ side, and pass it to the GPU.
So, with that in mind, here's a partial implementation( partial in that it has just a couple types, but it's easy to extend ), and how to use it.

Code:


And to use it:


Or:


It should be noted that I'm using this in production code, with just a few changes, like clean-ups, proper ctors, etc.
Speed-wise, it shouldn't be that bad. I use a std::map instead of a std::hash_map, as constant buffer and structures in general tend to have few items, and a hash map suffers in that conditions. Also is O(1) in the creation of each element, so you can add all the elements TYPES you want( C++ 11 and lambda functions make it possible to throw the old switch() case away in a clearer and might even faster way. Functional programming to the rescue!)

PS: uint is just a typedef for unsigned int. Also XMFLOAT4X4 and XMFLOAT3 are from the DirectX Math Library ( DirectX 11).
Branches, while faster every day, can be slow in some systems, especially in GPUs. By slow I mean slower than some arithmetic operations. If the branch is operating with numeric values, and assuming that boolean operations are convertible to 0 and 1, then it can be written as:
            a * Cond + b * (1-Cond) .
With a,b numbers and Cond a 1 or 0 representing true or false

I implemented two C++ versions of it, one that takes a boolean, and other that takes a function(can be a lambda, praised be C++11!)

Also, in HLSL or similar it can be
Take into account that that implementation is intended to mimic the logic of the C ternary operator : (cond)? a : b
The speed gain is really system-dependent, I have seen gains from 2 % to over 60 %, so see for yourself!
Tiling is a common technique to texture terrains, but suffer from repetition, as it IS the same texture repeated a lot of times. How can this be improved? You could add multiple textures, but that doesn't scale well when the number of textures increase. So what's the other option? Use the same texture, but make it LOOK different.

I accomplished that by creating a small 3D Noise texture ( 16 x 16 x 16 ) which I then sample in the pixel shader with the pixel world space position and a wrap sampler. By using multiples octaves, you get a nice noise. That noise is used as a mask to blend the same texture sampled at different sizes.
And there you go! Repetition is broken.
It could be improved a lot though. Some really good techniques are shown in GPU Gems 3, in a chapter about voxel-based terrains. Also that mask can be used to blend to different textures to achieve even more detail.

Here's a screenshot of the mask and of the final texture in my engine ( Fusion Engine ). Consider that there´s just one texture bound in the pixel shader.
Perlin, is that you?

Imagine this with some more textures...
I plan to add multiple textures in the near future ( next few days )
Here are some concept models ( and some not so concepts ) of guns for the Nanoattack demo.

"...modern guns work by either electromagnetic propulsion ( aka Gauss Rifle ) or plasma acceleration. To provide that amount of energy, miniaturized Casimir Reactors are used. The Casimir Reactors are devices that harvest the force generated by quantum fluctuations in the vacuum ( the so called Casimir Effect ) which is in fact tapping into the point-zero energy, providing an infinite amount of energy. While in theory this guns could shoot forever, the radiation generated by the harvesting of point-zero energy needs to be filtered, thus limiting the safety of the gun to the saturation time of the filter ( this can, however, be bypassed at the expense of high radiation doses ). Another big improvement is the use of Unified Bilateral Image Projectors (uBIP) to emulate the main parts of the gun with a holographic representation. This reduces the size of the guns, while allowing greater customization options..." Introduction to modern firearms, Stalkers Information Database, 2351



I allways try to prove that Blender is as least as powerful as the other software arround. Shadow Box, a nice feature of ZBrush, that allows you to create a mesh from 3 projections ( x, y, z ) can be easly done by combining some modifiers. In a nutshell.
    > Create 3 planes and paint the textures
    > Add a subdivision and displace modifier
    > Add some intersect boolean modifiers
    > *optional* Add a remesh and laplacian smooth to clean things up
Here's a screen of that:

and here's the above .blend file

The next step? Merge all this into a script, so it's more useful
Here's a model I found in the depths of my hard drive. Is a high-poly sculpt before of the times of Dynamic Topology in Blender, so there are a lot of polys. A lot. 
Rendered in Cycles at 200 samples. No normal maps where used, every detail is sculpted. In short, old model new render. 

Screen:

In HDR rendering ( and LDR too ) is common to add bloom to the scene. To create it, you need to mask the bright parts of the scene, blur it ( NVIDIA has a nice constant-time Gaussian blur ) and combine it with the scene, normally by adding them.
A lot of Brightpass filters exist, so I'm just gonna post mine here

   float4 bright = saturate((-color + pow(color,Power) * Scale) / Bias);

Screenshots:

Below is a plot of the function, with adjustable parameters. I use 2.58 for Power, 1.58 for Scale and 1.13 for Bias, but feel free to experiment. One of the graphs is the saturated function and the other is un-saturated

A while back, when working on my first engine, Atom Engine (DirectX 9), I played a bit with shaders for reflections. A fast but extremely hacky method to get them is to grab the pixel coordinates  (in screen space), and negate them in the y or x axis. Then just add them up with the color.
In practice, it works quite good.
You can extend it by adding a lot of blur, and also by using the surface normal to select the axist to negate. For example, negating both the x and y axis and using the reflection vector to mix both.

Below there are a couple screens, that just negate the y axis, and add too little some blur.
Works best for planar surfaces
The black regions are caused by the addressing mode. Should be set to wrap

Shader Snippet (HLSL) for the simple case
    // sspixel = coordinates in screen space (normalized 0 to 1)
    float2 newPixel = sspixel;
    newPixel.y = 1 - newPixel.y;
    
    // DX 9 Style
    float3 reflection = tex2D(texSampler,newPixel);
    // DX >10 Style
    //float3 reflection = colTexture.SampleLevel(texSampler,newPixel,0);

Pages

Powered by Blogger.