It is currently Tue Dec 10, 2019 4:44 pm


All times are UTC




Post new topic Reply to topic  [ 13 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Cubiquity and Ambient Occlusion problem
PostPosted: Thu Sep 29, 2016 3:55 pm 

Joined: Thu Sep 29, 2016 3:21 pm
Posts: 5
Hello everyone,
I'm trying to prototype a game using Voxel based maps with cubiquity and I'm trying to add an Ambient occlusion shader to give it a more stylish look.
The problem is that it kinda mess up with Cubiquity's mesh..

Image

On the left there is a Cubiquity mesh, on the right a standard imported .obj file with default material.
I'm using a shader/script applied on the main camera (this one to be precise https://github.com/keijiro/KinoObscurance , but i also tried different ones including the Unity one and the problem is the same)...

It looks like the occlusion is inverted...
I'd really like to have AO in this project so please help :(

(Also sorry for poor english, it's not my main language)


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Sat Oct 01, 2016 8:18 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Hi, I can guess what is going on here but I don't have a good idea of how to fix it. Cubiquity does not have any per-vertex normals for the generated cubic meshes, and these are usually used for lighting. What Cubiquity does instead is to compute normals on-the-fly in a fragment program. This is an unusual approach, but makes sense in our case because we want flat-shading not smooth-shading of cubes.

However, it is quite common for these generated normals to be incorrect and to face in the opposite direction. In the shader there is a property called 'normalMultiplier' and we sometimes set this to -1.0 (depending on platform, renderer, etc) in order to flip all the normals. This is a bit of a hack but I didn't get around to implementing a better approach.

You can try forcing 'normalMultiplier' to either 1.0 or -1.0 (you will have to find where this is set in the C# code) to flip the normals and this *might* fix your ambient occlusion. However, it will probably break your lighting (which may then be inverted)! Unfortunately I don't see an easy way of getting both working at the same time.

Edit: Actually I now realise I removed the normalMultiplier hack in the develop branch, but I don't think I ever shipped this change in a release. I'm a bit hazy as it was a while ago. The relevant change is here: https://bitbucket.org/volumesoffun/cubi ... 45b794f1f7

So are you using Cubiquity from the asset store or from BitBucket? If BitBucket, are you on the master or develop branch?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Sat Oct 01, 2016 9:00 am 

Joined: Thu Sep 29, 2016 3:21 pm
Posts: 5
Thanks for the reply.

I'm currently using cubiquity from the Asset Store, I found the normalMultiplier thing, but sadly it didn't changed anything...

But I found out that, if this can help to solve the problem, using the click to destroy script this happens:

Image

The fake cubes are showed properly and react just fine with the AO shader :?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Sun Oct 02, 2016 10:13 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
elkiwy wrote:
I'm currently using cubiquity from the Asset Store, I found the normalMultiplier thing, but sadly it didn't changed anything.


It had no effect at all, or it just didn't fix the AO problem? Because changing the value between -1.0 vs. 1.0 should completely change (invert?) the Cubiquity lighting, and setting it to zero should make Cubiquity meshes go dark. Did you change it though the shader (might get overridden?) or through the C# (probably better).

elkiwy wrote:
The fake cubes are showed properly and react just fine with the AO shader :?


Yes, this does not surprise me. The spawned cubes just have a much simpler shader applied and don't use the normal trick.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Mon Oct 03, 2016 7:13 am 

Joined: Thu Sep 29, 2016 3:21 pm
Posts: 5
Ok now it changed, but these are the results:

NormalMultiplier = 1;
Image

NormalMultiplier = -1;
Image

Both are not the "right" results... The -1 one looks blurry and still dark... The 1 one looks sharper with the correct blurry shadows but the lighting is inverted...


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Mon Oct 03, 2016 10:13 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Yes, it's really hard to say what is wrong here. Flipping the normal is making a difference to the directional light (you can see it gets inverted) but it's not clear that it fixes the AO problem. You can see that the AO is being applied but it appears inverted in both images (the edges of the blocks are dark).

Unfortunately I don't have any further ideas without diving into the code, which I don't have time to do at the moment :-(


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Tue Oct 04, 2016 6:43 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
See this short Twitter conversation: https://twitter.com/CalebHelbling/statu ... 8747096064

Apparently calling RecalculateNormals() may help, but it will also have an effect on the lighting of your mesh.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Wed Oct 05, 2016 1:19 am 
User avatar

Joined: Tue Feb 05, 2013 5:44 pm
Posts: 33
How to fix:

Insert the following method in place of BuildMeshFromNodeHandleForColoredCubesVolume in MeshConversion.cs
Code:
#if CUBIQUITY_USE_UNSAFE
            unsafe public static void BuildMeshFromNodeHandleForColoredCubesVolume(Mesh mesh, uint nodeHandle, bool onlyPositions) {
                // Get the data from Cubiquity.
                ushort noOfVertices; ColoredCubesVertex* vertices; uint noOfIndices; ushort* indices;
                CubiquityDLL.GetColoredCubesMesh(nodeHandle, &noOfVertices, &vertices, &noOfIndices, &indices);
#else
            public static void BuildMeshFromNodeHandleForColoredCubesVolume(Mesh mesh, uint nodeHandle, bool onlyPositions)
            {
                // Get the data from Cubiquity.
                ColoredCubesVertex[] vertices;
                ushort[] indices;
                CubiquityDLL.GetMesh<ColoredCubesVertex>(nodeHandle, out vertices, out indices);
                int noOfVertices = vertices.Length;
                int noOfIndices = indices.Length;
#endif
                // Clear any previous mesh data.
                mesh.Clear(true);

                // Cubiquity uses 16-bit index arrays to save space, and it appears Unity does the same (at least, there is
                // a limit of 65535 vertices per mesh). However, the Mesh.triangles property is of the signed 32-bit int[]
                // type rather than the unsigned 16-bit ushort[] type. Perhaps this is so they can switch to 32-bit index
                // buffers in the future? At any rate, it means we have to perform a conversion.
                /*int[] indicesAsInt = new int[noOfIndices];
                for (int ct = 0; ct < noOfIndices; ct++)
                {
                    indicesAsInt[ct] = indices[ct];
                }*/

                // Each vertex of every triangle should have its own vertex instead
                // of sharing vertices
                int[] indicesAsInt = new int[noOfIndices];
                Vector3[] positions = new Vector3[noOfIndices];
                Color32[] colors32 = new Color32[noOfIndices];

                // Required for the CubicVertex decoding process.
                Vector3 offset = new Vector3(0.5f, 0.5f, 0.5f);

                for (int i = 0; i < noOfIndices; i++) {
                    indicesAsInt[i] = i;
                    ColoredCubesVertex vertice = vertices[indices[i]];
                    positions[i].Set(vertice.x, vertice.y, vertice.z);
                    positions[i] -= offset;

                    if (!onlyPositions) {
                        colors32[i] = (Color32)vertice.color;
                    }
                }

                // Assign vertex data to the mesh.
                mesh.vertices = positions;

                if (!onlyPositions) {
                    mesh.colors32 = colors32;
                }

                /*
                // Required for the CubicVertex decoding process.
                Vector3 offset = new Vector3(0.5f, 0.5f, 0.5f);

                // Copy the vertex positions from Cubiquity into the Unity mesh.
                Vector3[] positions = new Vector3[noOfVertices];
                for (int ct = 0; ct < noOfVertices; ct++)
                {
                    // Get and decode the position
                    positions[ct].Set(vertices[ct].x, vertices[ct].y, vertices[ct].z);
                    positions[ct] -= offset;
                }
                */

                // For collision meshes the vertex positions are enough, but
                // for meshes which are rendered we want all vertex attributes.
                /*
                if(!onlyPositions)
                {
                    Color32[] colors32 = new Color32[noOfVertices];
                    for (int ct = 0; ct < noOfVertices; ct++)
                    {
                        // Get and decode the color
                        colors32[ct] = (Color32)vertices[ct].color;
                    }
                    // Assign vertex data to the mesh.
                    mesh.colors32 = colors32;
                }
                */

                // Assign index data to the mesh.
                mesh.triangles = indicesAsInt;
                mesh.RecalculateNormals();
            }


and in ColoredCubes.shader comment out the following line:
Code:
v.normal = float3 (0.0f, 0.0f, 1.0f);


It seems that the normal from the surface shader isn't actually being drawn to the normal buffer (or it isn't being drawn correctly??)

In any case the behavior from Unity here seems very bizarre. Could it be a bug in Unity itself?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Wed Oct 05, 2016 9:49 am 

Joined: Thu Sep 29, 2016 3:21 pm
Posts: 5
Holy cow thanks!

This totally fixed the problem :o


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Cubiquity and Ambient Occlusion problem
PostPosted: Thu Oct 06, 2016 10:38 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Thanks for the fix! Actually I had thought about RecalculateNormals() but I assumed it would break the flat-shading of the cubes due to corner normals being calculated as the average of their faces. Is this not the case, or is it just not noticeable? Perhaps Unity splits up the mesh in this case?

Dynasty wrote:
It seems that the normal from the surface shader isn't actually being drawn to the normal buffer (or it isn't being drawn correctly??)

In any case the behavior from Unity here seems very bizarre. Could it be a bug in Unity itself?


It could be, I certainly struggled to get this working in the first place and found that small changes could have unexpected effects. I think what I'm dong here is quite unusual so perhaps it breaks some off their assumptions.


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 0 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net