Jump to content

SpiderPig

Members
  • Posts

    2,348
  • Joined

  • Last visited

Posts posted by SpiderPig

  1. I believe I have found a solution.   If the node's corners are all above OR all below a surface (so a voxel index of 0 or 255) then the corner with the shortest distance is retrieved and it's distance is tested against half the radius of a sphere that encompasses all of the nodes corners (the distance from one of the corners to the centre of the bounds).  This way it ensures that the surface is not within the bounds of the node.  It creates nearly double the amount of nodes, and I dare say 30 to 40% of them don't represent the surface, but it fixes the gaps in the mesh and it's still fast.  Exploring the 4k terrain only uses about 100k nodes so it's not bad at all.  Fingers crossed it holds up!

    NodeBoundsSolution.png.d76dd7bc3331f36de45aab16e0ff1c04.png

    • Like 1
  2. Thanks I reckon they'll come in handy.  I think what I really need to do is ray-march the surface so I can get a point that is on the surface and then I can test that against the node bounds.  For now I have taken a simpler approach which is to average out all the corner distances and then test if the result is less than the radius of a sphere that enclosures the bounds of the node.  It should solve the problem at the cost of creating a few nodes that aren't actually needed.

    TemporaySolution.png.2f2b5681c926be8a3c076f75fd8b5d96.png

  3. 4 hours ago, SpiderPig said:

    But - I'm pretty sure all distances will go through a common point - the sdf's origin.  In this case the circles origin. 🤔

    So maybe if I get a vector from the corner to the SDF origin; multiply it by its distance to the surface and the add it to the corner's position I could then do a simple check to see if that surface point is inside the nodes bounds or not.  If the result is true for any of the 8 corners then that would be problem solved.

    Sounds too easy though. 🤔

    My epic MS Paint skills tell me that the rays would not go through the origin.  They would all meet at different points and even their intersection points would (in this case) say the surface is outside of the bounds.

    RadiusExample.png.359ffc2a23901c6678a7ae97595f0a0a.png

    Episode 4 GIF by The Simpsons

  4. Each corner distance isn't a distance to the same point on the surface either, pretty sure it's just the closest point, whatever that may be.

    But - I'm pretty sure all distances will go through a common point - the sdf's origin.  In this case the circles origin. 🤔

    So maybe if I get a vector from the corner to the SDF origin; multiply it by its distance to the surface and the add it to the corner's position I could then do a simple check to see if that surface point is inside the nodes bounds or not.  If the result is true for any of the 8 corners then that would be problem solved.

    Sounds too easy though. 🤔

  5. I wonder if anyone here has heard of a way to do this?  I'm sure it's possible somehow...

    In voxel terrain the 8 corners of a node are tested against some user function that defines a surface.  A Signed Distance Field is a perfect example of this.

    Each corner tests it's distance to the circle's centre and subtracts the radius to get the distance to the circles surface.  If the corner is above the surface, it returns a positive value.  If it is below, it returns a negative value.  If all corners are above the surface, the node is discarded because it doesn't represent the surface.  It's the same result if all the corners are below the surface.

    Thus to check if a node needs subdividing further or if a mesh should be made inside of it, a bit flag is set in an unsigned char that corresponds to the corners index.  So a node has a voxel_index which ranges between 0 and 255.

    0 means all corners are outside the surface.  255 means all corners are inside.  Anything between and a marching cube table is looked up to see how a triangle mesh should be created inside the node.

    Right now I do not use nodes with a voxel_index of 0 or 255, because both of these cases understandably do not make any triangles.

    However, in the 2D example below there are a few cases where a voxel_idex of 0 still needs to be subdivided (it won't represent a mesh at all, because the surface doesn't intersect an edge) but it does need to be subdivided to a lower node size because chances are high that some of its children will represent the surface.

    Finally I reach my question - the green squares are cases where the node should be subdivided because the circle intersects the edge or is inside the square.  However all corners are outside the surface in all cases so the voxel_index is 0 and is discarded (creating holes in the final mesh).

    The black lines are distances to the surface and are all positive values.  I wonder, knowing the corners positions and the distances to the surface can it be determined if the surface exists within the square?  I was thinking if I get the average distance and it is below some threshold, maybe the radius of the AABB (distance from the centre to any one of the corners)?  I think this could give false positives as it's kinda checking it against a sphere rather than a cube...

    Curious if anyone has any input.  I will be thinking on this for a while.

    NodeIntersectingTests.png.70ccd9ec5cae5c07f0e88aecc6c7cb48.png

  6. I think they were my normals actually.  I realised I was using an old shader I made so I changed it for my newer one with normal calculations in the geometry shader and I haven't noticed the issue yet.  Hopefully that was it.

    • Like 1
  7. 1 hour ago, Josh said:

    In practice I found myself adding a lot of listeners that evaluated ALL events,

    This is what I'm doing at the moment too...

    I do it to set individual custom widget members like; left_pressed = true; mouse_over = true; etc.  I did it because I wanted to know if the mouse was over a panel which was full of buttons or other widgets and I had to setup a recursive function that sent the event_id up the chain to a widgets parent.

    So are you saying the events work in reverse now?  They go down from the root widget down to all the respective children?

  8. 10 hours ago, klepto2 said:

    I like the idea, but i doubt this will be done, as it would be ingame only. The native gui interface relies on the native drawing methods provided by the os. This is why can't use the texture block when you add an interface to a window. 

    Ah of course.  I didn't think about that.  I was toying with the idea of making my own widget system using sprites so that I could do this because all of my widgets are going to have textures anyway.

  9. I'm just going to throw this out there - I wonder if we should be able to change a widgets material?

    For example if I assign the below image to a large panel the image would stretch.  However the corners of the image (red dots) should maintain their aspect ratio as defined by the green grid.  The other 5 regions of the image can be stretched to fill in the regions between the corners.  I've been experimenting with custom widgets and can separate the regions into their individual pixmap's and assign them to their own block to get the desired effect, some effects may need lots of blocks though.  But a custom shader that does this would be better I think.  Thoughts?

    TestBorderImage.png.d322b27a6d1215bd205df45eae7f2ebb.png

    I can think of a few others cases where this might be useful.  Glow effects, animated textures, etc.

  10. Through brief trial and error I got this example to work.  I want to be able to get the materials index so I can retrieve multiple materials in the shader for my voxel terrain.  I can find a way to send the materials indexes I need to the shader, that shouldn't be a problem.  (I'll probably use a small texture to hold the index)  It's just actually getting the material index.  Something like this perhaps?

    material->GetIndex()

    My C++ Code:

    auto material1 = CreateMaterial();
    material1->SetColor(0, 1, 0);
    auto material2 = CreateMaterial();
    material2->SetColor(1, 0, 0);
    
    ...
      
    terrain->SetMaterial("VoxelObject.mat");

    My Shader Code:

    Material m1 = materials[3];
    Material m2 = materials[4];
    
    float slope = getSlope(normal);
    color = mix(m1.diffuseColor, m2.diffuseColor, slope);

    The Result:

    MultipleMaterials.thumb.png.a44b9e6e435d0829a9be277b25fc0665.png

×
×
  • Create New...