Saturday, April 27, 2013

Voxelizer Part 1

Here follows the first results of my voxelizer (the process to take a regular mesh and create a voxel representation). For the tests I'm using an old SpiderMan model that I created in 2005 (damn, I dunno how I found it on my HD) and Sponza Palace that Crytek donated to public domain (download link). I'm glad with the results, but I still have to take in account the model's texture to colorize the voxels. This is a small part of my Global Illumination studies. hehe

Just a few million of voxels. That's I call density. :D


In the next posts I will share the Unity webplayer demo and project source.
If you are interested to understand how it's made, I recomend you to start studing the "Separating Axis Theorem" (SAT). Here is some very usefull links about it:

Sunday, April 21, 2013

Unity Multi Pass Surface Shader

As you guys know, in Unity we can write shaders in some different ways. We can have Fixed Pipeline Shaders, Surface Shaders and CGPrograms (vertex and fragment shaders).
Surface Shaders are great to write lightning models, but I always believed that it limit the shader to just one pass. Well, yesterday I discovered that I was WRONG. I found a very interesting topic in Unity forum about this and I started to play around with it.

Here follows a very simple shader that illustrate how is possible to combine those languages and have a multi pass shader. Just uncomment the pass blocks to see the effect.


Shader "ZGreaterTest" 
{
 Properties 
 {
     _Color ("Main Color", Color) = (1,1,1,1)
     _MainTex ("Base (RGB)", 2D) = "white" {}
     _Indicator ("Indicator Color", Color) = (1,1,1,1)
     _Cutoff ("Alpha cutoff", Range (0,1)) = 0.0
 }
 
 SubShader 
 {
  Tags { "Queue" = "Geometry+1" "RenderType" = "Opaque" }
 
  CGPROGRAM
  #pragma surface surf BlinnPhong alphatest:_Cutoff
  uniform float4 _Color;
  uniform float4 _Indicator;
  uniform sampler2D _MainTex;
   
  struct Input 
  {
      float2 uv_MainTex;
      float3 viewDir;
  };
  
  void surf (Input IN, inout SurfaceOutput o) 
  {
      o.Albedo = tex2D ( _MainTex, IN.uv_MainTex).rgb * _Color;
  }
  ENDCG

// Pass: Surface SHADER
//     ZWrite Off
//     ZTest Greater
//     Blend DstColor Zero
//     
//  CGPROGRAM
//  #pragma surface surf BlinnPhong
//  uniform float4 _Color;
//  uniform float4 _Indicator;
//  uniform sampler2D _MainTex;
//
//  struct Input 
//  {
//      float2 uv_MainTex;
//      float3 viewDir;
//  };
//  
//  void surf (Input IN, inout SurfaceOutput o) 
//  {
//   //o.Albedo =_Indicator;
//      o.Albedo = tex2D ( _MainTex, IN.uv_MainTex).rgb * _Indicator;
//  }
//  ENDCG 

// Pass: CG SHADER
//  Pass
//        {
//         Tags { "LightMode" = "Always" }
//         AlphaTest Greater [_Cutoff]
//         ZWrite Off
//         ZTest Greater
//         
//            CGPROGRAM
//            #pragma vertex vert
//            #pragma fragment frag
//            #pragma fragmentoption ARB_precision_hint_fastest
//            #include "UnityCG.cginc"
//
//   sampler2D _MainTex;
//   float4 _MainTex_ST;
//   uniform float4 _Indicator;
//   
//            struct v2f 
//            {
//                float4 pos          : POSITION;
//                float2 uv           : TEXCOORD1;
//            };
//
//            v2f vert (appdata_full v)
//            {
//                v2f o;
//                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);    
//                o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
//                return o;
//            }
//            
//            half4 frag( v2f i ) : COLOR
//            {
//             half4 texcol = tex2D (_MainTex, i.uv);
//               return texcol * _Indicator;
//            }
//          ENDCG           
//        }
        
// Pass: Fixed pipeline
//        Pass 
//  {          
//         Tags { "LightMode" = "Always" }
//         AlphaTest Greater [_Cutoff]
//         ZWrite Off
//         ZTest Greater
// 
//         SetTexture [_MainTex] 
//         {
//             constantColor [_Indicator]
//             //combine constant, texture
//             combine constant* texture
//         }
//  }
  
 }

 Fallback " Glossy", 0
}
 
I would like to thank Sycle and Farfarer to share this tip. :)

I think that the next post will be about a voxelizer that I'm writing. Stay tuned!

Saturday, March 9, 2013

Voxel Engine Part 3 (Final)

As promised, here is the Voxel Engine Unity Project:
Unity Package (1.36mb)
Alternative download link

The webplayer demo is available in my previous post.

There is a "Read-me" file inside the package pointing out some directions for those who are trying to understand the project.

I would like to thanks Paul of the BlockStory project that wrote some very useful articles that helped me a lot to get started in the Voxel World. Some classes are heavily based on his samples.

Thanks as well to the Unity community that have this great topic about voxels and to Jeff Standen that wrote the Simplex3D Noise that I'm using.

This demo works on iOS, Android, Mac, Windows and Webplayer. It was tested on my Android Galaxy S2 and Apple iPad4.

The main bottleneck is the CPU while the player is creating and destroying blocks. In the code I left some hints of things that I would have done differently now, or links to articles that offers a better solution for what I did. Remember, this is just a prototype that emerged from a study. There is a lot of stuff to change if you are planning to use this in a real project.

The textures and sounds came from Minecraft ( https://minecraft.net/ ), and the pickaxe is a model that I did trying to reproduce the Minecraft pickaxe. So those assets are not my property and should not be used in any commercial way.

Fell free to use all the other assets and scripts in the way you like.
If you did something cool using this project, please let me know. :)


Thread

Friday, March 8, 2013

Voxel Engine Part 2

This video show the voxel world generation. It doesn't take this long. The video is that slow to we be able to see what is happening.


The first pass generate the heightmap and the second is responsible to create the mesh and perform the lightning calculation.

And here follows the webplayer to you guys give a try to the engine. In the case that the previous link didn't work, you can download the demo here.

There is a lot of things to enhance, and many parts to optimize but I'm done with this project. In the next days I will post the project with all sources and assets so it may help someone that is thinking to study voxels.

Thread

Saturday, March 2, 2013

Voxel Engine Part 1

In the last weeks Unity announced the winners of the DirectX11 Competition.  It was submited many amazing projects, but this one in particular caught attention: "Voxel Cone Tracing created by Kurt Loeffer".
For those who do not know me, I'm addicted to computer graphics and Global Illumination has always been one of my favorite lightning technics. 
So I decided to learn more and try to implement my own version based on the following Nvidia paper: Voxel-Cone-Tracing-Octree-Real-Time-Illumination

There is also some interesting stuff on the book GPU Gems3, that thanks to Nvidia can be found here for free.

As the name implies, this technique is based on voxelization then I thought it would be interesting to study some voxel engines first. I dunno exactly how or when, but a few moments after I started my studies I found myself trying to recreate some of Minecraft features using Unity.

Here follows some results:

 This world can be "infinity" in all directions. As you can see, even the Y-Axis is split into Chunks.
This map was generated using the Simplex3D Noise 

Fake Ambient Occlusion and Fog
 Cave Generation and diffrent block types
Hard Light & Soft Light
Ambient Occlusion, Soft Light
Hard Light flood
Soft Light flood


The engine is pretty basic, but I think that covers some of main features. It deals with world/cave generation, only render the faces that can be seen, player can create/destroy blocks, dynamic soft light flood (and all other types as well), different block types... In terms of CPU/Memory it's not so optimized right now, but still runs well on my iPad4 and Samsung Galaxy S2. 
I have to clean up the code and soon I will post the entire project here.

Meanwhile, here is the material that I used to learn more about voxels (the main articles are highlighted):

Thread