3
$\begingroup$

I want to be able to detect the collision of two objects, via the shader editor. Till now I got a white spot exactly there where the object hits the other but I dont know how I can use this little white spot as a trigger for other changes. For example when I would like to change the color of the complete material. How can I say the material: When a little part gets white then change this or this.

I can get it more accruate but for demonstration purposes I made it that there is a circle already on non collision. The detection doesnt need to be that accurate. The end goal is to have a energy shield that is changing when an asteroid hits it. The question is now: Can I somehow check if the material got white at a certain point and then get a complete white or black map if false or true? The problem is when I have accurate collision detection the white spot is the size of the collision object and you would see nothing. So I need to either make it bigger or be able to get True False on little change. Again Thanks in Advance.

enter image description here

Greetings and thanks in forward

$\endgroup$
1

3 Answers 3

4
$\begingroup$

Using Geometry nodes, you can spread the maximum value of any attribute over the entire surface.

In this example, Suzanne's Shield is set up as a Dynamic Paint Canvas...

enter image description here

.. set to record interaction with brushes in the default vertex-color layer: 'dp_paintmap'. Dissolve is checked, and set to a short time, so the paint does not persist. You could extend that, to slow the shield's recovery.

A Cube is set up as a Brush, with all settings at default:

enter image description here

.. although, looking at the result, 'Volume and Proximity' might be a better setting for the brush?

Below the DP modifier, a Geometry Nodes modifier is added with this tree:

enter image description here

The GN tree takes in the dp_paintmap vertex-colors (via its modifier interface), finds the colour's maximum Blue value, and floods dp_paintmap with that value in all channels, via the output. This means that when any part of the shield is touched, the whole shield acquires the 'touched' blue-strength in all channels.

(I could have been more persnickety about the types of attributes being passed, but that would have just ave been more nodes. You can adjust to your needs).

The 'dp_paintmap' attribute can be picked up in a shader:

enter image description here

Here, 'dp_paintmap' is used as a mix factor between inactive and active 'Base' and 'Emission' colours in the shield's material:

enter image description here

(Blender 3.0b)

$\endgroup$
3
  • $\begingroup$ Very nice!!! +1 $\endgroup$
    – Chris
    Commented Nov 20, 2021 at 16:53
  • $\begingroup$ @Chris Thank you! I'm assuming the problem is to get the whole object to respond to a collision. I could be wrong.. I had my usual nightmare with DP. It doesn't seem to agree with me. Also, I would rather have used vertex weights, but you can't pick those up in a shader the way you could a couple of builds ago ??? Plus, I've just noticed it's switching off when the brush is entirely inside the canvas ..:( I wonder how to fix that? $\endgroup$
    – Robin Betts
    Commented Nov 20, 2021 at 17:03
  • $\begingroup$ My dynamic paint knowledge is very basic…😬 but yes, I would agree you can use vertex weights… $\endgroup$
    – Chris
    Commented Nov 20, 2021 at 17:08
4
$\begingroup$

You can colorize the distance between the origin and another objects UV coordinate like this:

[Material to use a color ramp based on distance.1

result:

enter image description here

Be aware: this has nothing to do with "collision", it just measures the distance between points of the objects. So although this is Suzanne, you cannot see any Suzanne shape on the sphere. That's what I meant with "it's not a collision, just for simple objects like spheres...)

With a simple math compare and a mix-rgb node you can "cut off" the colorramp and give e.g. another color (gray in this example) if the distance is higher than a specific limit (greater than node). Analog you could combine it with a less than node.

setup:

enter image description here

result:

enter image description here

$\endgroup$
1
  • $\begingroup$ I think you think your bottom material solves the problem, but I don't think it does. However, I admit that this time there's room for interpretation and what you wrote might be sufficient. So I've removed my downvote. $\endgroup$ Commented Nov 20, 2021 at 17:23
3
$\begingroup$

One way to do this by "collision detection", is to use the Object Coordinates of each object.

Here's an outline of a material that will do what you want:

Material that changes color on 'impact'

There are three main components to this:

  1. Calculating the distance between the two empties.
  2. Determining the distance at impact.
  3. Switching.

Since you already know how to do the first two, I'll describe the switching in detail. It is done using the Less Than Math node and the Mix RGB node.

The Less Than node's threshold is set to the point of impact. Since I'm using a standard sphere of radius 1, in my example that's 1.0. This results in an output value of 0 when the two empties are farther apart than the the threshold (contact point) and 1 when they are closer.

The Mix RGB node implements the switch. You can do the same thing with a mix shader node if you want to switch between two materials. It works as a switch. If the two empties are farther away than the contact point, then my sphere will be Red, the top input of the node. If they're closer, my sphere will be Blue, the bottom input.

Instead of simple colors, you can plug the output of whatever color building node tree you have into the two inputs. As a result, The sphere will change color at the point of impact.

Note: This isn't real collision detection, just using object proximity, which is why if you use my example, the cube will be approximately half way into the sphere before the color changes, since I didn't account for the cube's size.

$\endgroup$
7
  • $\begingroup$ I am pretty sure your empties is an overkill. You would have exactly the same result just taking the object coordinates itself. And this "If you try this technique with the objects themselves the comparison will depend on the relative positions of vertices on each object" is wrong as well - i think. The object coordinates are just the origins of the objects. So it is just a comparison of two points. But i might be wrong...but i don't think so. $\endgroup$
    – Chris
    Commented Nov 20, 2021 at 17:35
  • 1
    $\begingroup$ You're right that I don't need the empties. I just need to use the object coordinates of each object, rather than the UV coordinate of the target. $\endgroup$ Commented Nov 20, 2021 at 18:11
  • $\begingroup$ Wow…your first „you are right“ you said to me. Now I will open a bottle of champagne and drink all night….🥂🍩 $\endgroup$
    – Chris
    Commented Nov 20, 2021 at 18:18
  • 1
    $\begingroup$ Now that your answer is correct you got a +1 from me $\endgroup$
    – Chris
    Commented Nov 20, 2021 at 18:26
  • 1
    $\begingroup$ Mo just wrote an email to me in which he said, that I should say „thank you“ for your answer - he cannot comment the answer and it looks like he doesn’t know the „answer check button“…. $\endgroup$
    – Chris
    Commented Nov 20, 2021 at 21:07

Not the answer you're looking for? Browse other questions tagged .