- Home /
Unity overlapping transparent spheres
Hi guys, first I am sorry for my bad English, I hope you can understand what i want to say :D
I have a problem with the shields of my space shooter prototype. One shield consists out of two basic spheres. One of them is normal, one of them is reversed by code (to make the shield visible from the inside). Both are rendered with the unity Standard Transperent shader, in blue. To make some nice graphic effects I set Metallic to 0 and Smoothness to 1 in the shader. The shields have a variable size, if they get damaged or load, they decrease or increase their scale by code. I am planning to have maybe 1-100 shields in a normal game, which could change their size more than one time per second each.
Now my Problem: I want two shields to connect to each other and not to overlap. All shield surfaces, which is under another shield should be removed, to enable players under the shield to shoot through a neighbor shield, which stands very close to the other one.
I figured out two solutions:
First: Calculate a new Mesh everytime the shields change, which has the shape of the old spheres, without the inner parts. (disadvantage, the shield size can change very often -> massive calculations!)
Second: Use some kind of shader or trick to not render the inner parts of the shield and check for all bulletcollisions if they are inside of a shield (then ignoring them). With this approach I would need n (number of shields) comparisons if a shield get hit, for all just check if the distance between hit and center of the shields are smaller than their radius.
I hope you understood what I want, as an attachment I got 2 screenshots, one from the outside of both shields and one from the inside of one of them. In both I have to remove the part inside of the other shield.
Is there an easy way to make such a shader, which could render just parts of the mesh and even the faces based on conditions (I am a totally beginner in shaders), or do you know another solution for my problem? If I explained something inaccurate feel free to ask me, I am happy with all the answers ;-). If you know some keywords to google for, I would appreciate it, because I found nothing with the same problem and a solution.
$$anonymous$$y guess would be using a simple transparent shader with the blending set to achieve what you want:
have a look at http://docs.unity3d.com/$$anonymous$$anual/SL-Blend.html
PS: You should have no problem using a Sphere Collider for rendered mesh, because the collider uses the Unity Sphere primitive, and even if you use a cut sphere mesh to render,(generated mesh, etc) the collider still is a sphere and there is no way a laser can shoot between two sphere colliders that are intersecting, if it is a raycast that happens within the physics timestep.
Ok nice approach, too. As I understood this will only help from outside. From outside I would see just the outer parts of a the shields, but as soon as i go inside, in one I will see the part of the other (which is inside too), what I not should
I overlooked the fact that you have two meshes, but you can just use the culling toi draw both sides of a mesh with different (or the same) colors:
http://docs.unity3d.com/$$anonymous$$anual/SL-CullAndDepth.html
Take a look in the "Pass" category where my two links are located, you will find many valuable information for playing with graphics.
I use my test shader to draw backfaces in a different color than front, so I can spot tiny mistakes in my imported models for example.
I found a shader (http://answers.unity3d.com/questions/1013821/simple-shader-deter$$anonymous$$e-if-fragment-is-inside-anot.html) ,that could cut a hole in the spheres. With code I save the position of one Shield. All Spheres, which cross this shield will be cut how they should. $$anonymous$$y problem is, I have to save all shield positions in the shader, so I need an array and loops inside the shader code. I tested the approach with 2 shields and it would work for me. But I have a dynamic amount of shields, so I need a dynamic solution like a List or a big array, which I could fill. Do you have any idea how I could make these dynamic? The Script:
public class Cull$$anonymous$$e : $$anonymous$$onoBehaviour
{
public Transform culler;
void Update()
{
var renderer = GetComponent<Renderer> ();
var material = renderer.shared$$anonymous$$aterial;
if (culler.name == "1") {
material.Set$$anonymous$$atrix ("_CullerSpace1", culler.worldToLocal$$anonymous$$atrix);
} else {
material.Set$$anonymous$$atrix ("_CullerSpace2", culler.worldToLocal$$anonymous$$atrix);
material.set
}
}
}
The shader
Shader "CGShader5"
{
SubShader
{
Pass
{
/*Cull Off*/
CGPROGRA$$anonymous$$
#pragma vertex vert
#pragma fragment frag
uniform float4x4 _CullerSpace1;
uniform float4x4 _CullerSpace2;
struct vout
{
float4 pos : SV_POSITION;
float4 worldpos : TEXCOORD0;
float4 localpos : TEXCOORD1;
float4 cullerpos1 : TEXCOORD2;
float4 cullerpos2 : TEXCOORD3;
};
vout vert(float4 vertex : POSITION)
{
vout _out;
_out.pos = mul(UNITY_$$anonymous$$ATRIX_$$anonymous$$VP, vertex);
_out.localpos = vertex;
_out.worldpos = mul(_Object2World, vertex);
_out.cullerpos1 = mul(_CullerSpace1, _out.worldpos);
_out.cullerpos2 = mul(_CullerSpace2, _out.worldpos);
return _out;
}
float4 frag(vout _in) : COLOR
{
/*return float4(_in.cullerpos.x, _in.cullerpos.y, 0, 1);*/
if (length(_in.cullerpos1.xyz) < 0.49)
discard;
if (length(_in.cullerpos2.xyz) < 0.49)
discard;
return float4(0, 1, 0, 1);
}
ENDCG
}
}
}
I have to make it dynamic for a large amount of positions. Some kind of float Array where the 0.49 stands, to save and use the radius of the matching shields.
Big thanks in advance ;-)
If you need to change values in a shader, access the material's shader in code.
Just use a container variable for the 0.49 and you can adjust it via code. Just like you would change the color or specular value in the Inspector in other shaders.
If you are unsure on how to access shader values, google it. There are enough answers for that. ;)
I'm not sure why you need the positions of every other intersecting mesh actively passed into the shader. It should do that for every material that isn't itself.
I believe this could be much easier, but it's been 6 months since I last wrote a shader..
But how could I add "Arrays" of values? And loops which will calculate through all these values?
The problem on your approach is, that it works just as long as I am outside of all shields. As soon as I come into one it will not work anymore :-(
I don't understand what the difference is. The rendering is view-based, so regardless on which "side" the mesh is viewed, the shader should do the same, if not coded otherwise.
Answer by Naphier · May 13, 2016 at 07:37 PM
It'll likely be much easier (and look better) with a custom shader. The best way I can think of to do this would be with a metablob (or metaball) shader.
Ok realy nice thing, I am googling for it, but it is hard to find good 3D solutions. You maybe know one I could use or learn from?
https://www.assetstore.unity3d.com/en/#!/content/26804
Appears to be 3D. Not sure if it supports transparency and looks like it might take some customizing. I'd like it better if he had a web demo.
https://www.assetstore.unity3d.com/en/#!/content/21518
Looks like this one is actually doing it with the meshs. $$anonymous$$ight ultimately be nicer. Definitely a better price.
For a simple introduction and example project, try: http://codeartist.mx/tutorials/liquids/
Thank you very much, normely I try keep all my assets free, but i will looking for this one i think ;)
It looks like this asset is just for use in the editor and not at runtime. :( You got an idea how I could programm such a thing myself?
Sorry, completely didn't notice that (by the reviews looks like I'm not the only one). @tanoshimi linked a good tutorial. I'm not certain it will work with 3D, but I also don't see why not.
EDIT: Other than it being quite expensive on the GPU.
The problem I see in the shader solution is that this denie me to calculate collisions on base of the shield radius because the meatballs are no circles. As result I would have to calculate the mesh on all shieldupdates, which is to CPU heavy I guess. How do you think about this?
Not sure if that's a problem. You'd have 2 sphere colliders. You might want to make them slightly larger than the meshes. I guess there's a chance of something falling through the middle, but not sure if that's much of an issue. Calculating meshes to act like metaballs is likely very CPU intensive. So I'm not sure if there is really another viable solution.
I think this thing in the middle would be a issue, because the shield should stop exactly aimed laser projectiles in a pvp game. Bugs that could be abused and give a very big average i have to avoid. Colliders that are larger than the actual shield are bad too, because they would stop projectiles flying tangential nearly over the shield for example.
Your answer
Follow this Question
Related Questions
Geomorphing terrain with a vertex shader (custom vertex data maybe?+ 0 Answers
Combining meshes with correct tiling 0 Answers
Dymanic Mesh Hiding 2 Answers
2D Sprite Shader Acting like Light 0 Answers