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.. 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 (https://answers.unity.com/questions/1308110/how-to-make-a-tovel-like-cube-edge-smooth.html) 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
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 ) 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.
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.
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.
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.
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: I hope this option will suit many.
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.
This post process is brightening or darkening edges based on if they’re convex or concave (or there’s a depth break). To get the look of the second image, which is from my normal mapping article, you need to soften the normals prior to lighting. To do that you either need to actually have softened normal maps on your meshes, or you would have to write a post process that affects a deferred renderer’s normal gbuffer by blurring slightly, limited by depth breaks. That’s not what this post process is doing though.
@MalyaWka So, after appliying the solution the the black screen problem, I can finnally see the cavities. However using blit mode reduces significantly the quality and the overall look of the effect. Can you elaborate further on why using draw mesh gives a black screen? or how to fix it? PD: Somehow in your sample scene it works in every way. Do I have to use any specific pipeline settings? Final edit: It is PostProcessing who causes the weird black screen behaviour if the renderer pass events are set before it, otherwise it just removes the effect from the screen. Hope this helps to find a solution Btw, Im using Unity 2021.1.7f1 and URP 11.0.0
man , you're my life saver. I just create a simple scene with your package, it works very well and the cavity just looks right as in blender! thanks a lot. this packager is much better than any other solutions. I even export successfully export a webgl version and it works well even in mobile! ! just for those who want export : include 2 shaders in project / graphics otherwise the shader won't show
@SharpC_ So adding the shader to the Always Include list solved all the black screen issues and other artifacts it had for you?? Please, he'd be my life saver too!
Hello everyone! I planned to initially release the full version of my Cavity effect only after completing my game. But since the end and the edge of the completion of the project is not yet visible, I'm spreading it now. GitHub - https://github.com/malyawka/URP-ScreenSpaceCavity I hope this option suits everyone
I love this. I'd be willing to pay for it too if you wanted to put it up on the Unity Asset store. Honestly, I bet you'd create a new wave of visual design for Indie games off of this since so many people love the Cavity effect in Unity. I haven't tried to figure it out yet, but I'm wondering if I can change the color of the white lines per-object. I was thinking of combining this with the design for the outlines of enemies and objects in Halo: ODST. If you're not familiar with it, there's a mode you can activate like a night vision that draws outlines around objects based on if they're simple terrain, interactable objects such as doors and weapons, or hostile creatures. I was hoping to implement something similar. Is that possible with this shader, maybe after some modification? (I'm completely new to shaders)
What you want, I think is quite possible. it's just that in the example we use intensity, you can use this parameter to overlay your color.
Someone finally did it! Haha. Congrats man this is fantastic, I always wanted to bring the blender effect into unity.
Just downloaded the package, and loaded the sample scene. Didn't see any change. Am I missing something? @MalyaWka
Tried to update to a slightly newer unity version to take advantage of soem new rendering settings, 2021.2.4f1 from 2021.1.11f1 and recieved this error _CameraColorTexture not found
Looks liek your newer version might not make use of that call , so maybe i shoudl just grab it from teh github...
The effect has potential. I recommend giving an option to scale the curvature scale by the inverse distance, because at the moment the scale is basically uniform and not distance dependent (far distance --> smaller scale, small distance --> bigger scale).
Hi guys! Sorry, I'm very busy with work right now and don't have time to see what's wrong with the asset. Maybe a little later.
I got passed that i had to give eveyrthing the toonylit shader and it worked, I added the cavity shader and the toonylit shader to always incldued shaders but when I build it it isnt working in the build now. Looks fine editor. So basiclaly I'm having the same issue except in the built one now
Nevermind was thinking of something else. Anything with toonylit shader now shows through fog. Any ideas?