Voxel Edge Smooth Effect

Hi there, in advance I’d like to share that I’m pretty new to shaders but have a gist of the basic concepts, so bear with me as I try to sound like I know what I’m talking about here… :stuck_out_tongue:

I’d like to create an effect similar to the one seen in the picture below. The picture is of an “edge smoothing” effect that makes the voxels look like they are slightly rounded. Another set of examples are some of the pictures in this thread (How to make a Tovel like cube (edge smooth?) - Questions & Answers - Unity Discussions) from Trove.

Being new to shaders and image effects, I only have tidbits of information that others have shared on how this effect might be achieved, but I don’t think I know enough to write the shader/image effects needed to make those things happen. This part is my knowledge so far (which may be wrong): The lightening effect (green arrow) on the outer edges appears to be an effect on the entire screen and not a specific material because it will lessen as the camera gets closer to the edges. The darkening effect on the inner edges (blue arrow) would normally make me think SSAO or some other ambient occlusion, but the fact that it looks so similar to the outer edges but in a darker tone makes me think it is also part of this effect. I believe this also involves using a normal map of the camera’s view to detect the edges?

I really just need guidance on all of the terms and concepts that are all involved in this specific effect and how they are used so that I can begin to make progress. Code is also greatly appreciated! Thanks a bunch.

Trove is very clearly using normal maps (as seen from the blocky artifacts in the shading). Could be a second atlas, or more likely a single box face normal map with careful UV mapping.

The example image above doesn’t look like normal maps, but rather just a bright edge. Again, likely just done with a texture and careful UV mapping.

Real time shaders alone lack the ability to create rounded edges without custom encoding of a lot of information into your mesh and/or textures and complicated shaders… at which point just using a normal map is way, way cheaper and easier to implement.

Thanks for the response,

I would opt for a normal map under normal (pun intended) circumstances, but the meshes I am working with to achieve this effect are all procedurally generated with data like “there is a voxel at x,y,z with color a.” My current setup also includes a texture that is generated that has a pixel for each color contained in the set of voxels, and each face UV maps to that pixel on the texture. That setup doesn’t need to stay the same, but the procedural generation part will.

That being said, I can’t quite think of a way to use a normal map texture to achieve the effect - I imagine I would need a normal map for each possible face of a cube, similar to the pic below but with more cases than the 9 shown. Even then, I will run into an issue of my UV mapping for handling colors conflicting with what my UV mapping for handling normals. I might be missing something though. Did you have in mind a way to go about this? (I am not tied down to my current setup for mesh/texture generation, just that it all needs to come from data instead of an obj and texture files)

On the comment about the first pic just using a brighter edge, that’s actually my desired effect. For my purposes (and opinion haha), it looks good enough to convey roundedness. Would the way to go about this be different if the goal is just to brighten the edges that face outwards?

Thanks

1 Like

For normal maps or bright edges the implementation is basically the same. Either have an atlas like you have above, or add in edge splits in your geometry so you only need a single full face normal and an internal corner, and scale the UVs anywhere you need a flat face / long single edge.

So for that implementation, I would lose a lot of control over what color each voxel is because I currently use UV mapping to map to a texture atlas used for colors, not normals. This is because my mesh is procedurally generated and could have a different color for each voxel. To my knowledge there isn’t a way to UV the albedo and normal maps differently

If possible, I’d like to step back the question to “how can this be achieved with shaders/image effects,” because I am growing more confident that the game I am referencing using this effect does not use normal maps, and possibly not even a texture with brighter edges. In the video attached, I am moving the camera close and then far away again to show how the effect changes intensity/size. This is really the biggest reason I think there is an image effect at play here (that may be the wrong terminology, I am referring to the effects that manipulate pixels after Unity has rendered out the screen :p)

weepyfatherlycuttlefish

Thanks again

You can have more than one UV set, up to 8. In fact each UV set is a Vector4 / float4 that you can pack two 2D UVs into, so you can have up to 16 completely unique UVs. Unity’s built in RecalculateTangents function assumes the normal maps are no the first UV’s xy components, but as long as the UVs used by the normal maps have the same orientation as that first UV they’ll still work properly.

That particular effect, yes, that could be done as a post process. It appears to be doing an inverse SSAO on convex edges. You’ll notice the dark interior edges also scale with distance. Most SSAO implementations go to great lengths to make sure the effect stays consistent in world space, but that one is purely screen space.

Much torment and I did it !!!

3 Likes

Man Tell me how? with AO? or Shadergraph with scene depth? or atlas with normal maps?

This is a screen space effect using normal texture and depth. If you look at the Blender code, then they have two concepts “curvature” (darkens the far edges and brightens the near edges) and “cavity” (this is an AO effect that makes the edges smoother).

I am still finishing this effect right now as there are some difficulties with distance and mode (perspective / orthographic). When I finish, I plan to publish it in the asset store.

1 Like

Hey!

I decided to show part of the “Curvature” effect. It also does not work with an orthographic camera yet, but maybe that will be enough for you.

I just don’t want to deal with this effect now, while there is a lot of other work.

This is all written and tested on Unity 2019 LTS and URP 7.5.3.

Basic settings:
Filter Mode - allows you to make a smoother transition from the thickness.
Scale, Ridge and Valley - thickness and saturation of light and dark edges.

I hope you figure it out and it suits you.

7014547–829933–ScreenSpaceCavity.unitypackage (6.73 KB)

2 Likes

How do i apply it?

Edit got it working! Thanks!~

1 Like

Nah I dont know how to start work this, I have black screen, only debug works

This shader is exactly what I was looking for. However it works great in the game but in scene view I got a totally black view. Any ideas on how to fix this?
Thanks!

Sorry, this is because I wanted to reduce draw calls.

I don’t have access to a computer right now and won’t be able to rewrite the code. You can do it yourself using the Blit Pass that Unity has for the example.

You need the Execute method. In my version, it renders everything in one draw call, in this example a temporary texture and two draw calls are used.

Alternatively, you can see the implementation here.

Hope this helps you.

1 Like

@MalyaWka how’s the package going?

Hey!

A lot of work and to do. Here in the attachment file, everything should work with it as it should.
Sorry, there is no way to check on Windows, if there are problems - then write.

Added a scene with an example to the package. Also, if there are problems or artifacts, I added a quick implementation of Blit in the settings:
7181065--861061--upload_2021-5-27_13-19-53.png

I hope this option will suit many.

7181065–861058–ScreenSpaceCavity_v2.unitypackage (11.6 KB)

5 Likes

Guys,

Post screenshots of your results here. I just did all this and tested it only on Simple models from Synty Studio.

There are lines missing when items are in front one another, and shadows don’t work.
I’m on Unity 2020.3.7f1, the same happens on 2020.3.10f1.

@MalyaWka I can’t make the effect smoother

I’m trying to make it look like this:


7357280--895745--upload_2021-7-24_0-39-20.png