Download

Shading surface based on colors of objects

Imagine a sphere containing smaller spheres of different color which are dynamically being translated within. I would like to shade the surface of the containing sphere based on the proximity of each surface primitive (vertex or fragment) to each of the contained spheres. The closer the proximity, the more the underlying color contributes to the resulting color. The specific use case constrains the number of contained spheres to be no more than 16. How do I go about this in Unreal?

Ideally, I would have liked to simply pass the contained sphere positions and colors into the shading procedure of the larger sphere and calculate the resulting color therein. My current understanding is, however, that array parameters cannot be passed into materials.

Alternatively, I thought about assigning the vertex colors of the containing sphere at run-time, which sadly, also seems to currently be impossible in Unreal.

I also have been looking into material parameter collections. Having 16 distinct sphere positions and 16 distinct sphere colors at first seemed like a possible, although cumbersome and unwieldy solution considering the simplicity of the task. I don’t, however, understand how to dynamically update these variables. Would each of my contained spheres have to have its own, unique material, writing to the appropriate fields in the parameter collection?

Any input would be greatly appreciated.

I would suggest using an actual sphere mesh for your big outer shell and then use “SphereGradient-3D” for the spheres within it.

You will have to make a slight modification to the function to get it to work like you want. How much depends on your UE4 version.

When you open the function “SphereGradient-3D” do you see this comment box called “WorldPos ray Enter”?

sphere3d.JPG

If so, add an output node and attach the “Add” node output to it. If not I can tell you the changes to make since this was updated a few months ago and I’m not sure which Ue4 version it went into.

Then basically inside of your large sphere material, for each inside sphere you place “SphereGradient-3D” and then give it a location. To blend between the outer surface and inner surfaces we need to find the distance between the outer shell and the inner spheres. If our outer sphere is an actual sphere mesh this means the position is simply “World Position” which simplifies things.

The world location of the nearest surface for each each interior sphere at each pixel will be given by the Function output you added above for “WorldPos Ray ENTER”.

By doing distance(worldPos, WorldPosRayEnter) you get the distance between the two. Then you can do exponential gradients or whataver to that value to make it look a bit more realistic.

You need to do that distance for each sphere. To combine them, you use the “min” operation which would accumulate all the nearest spheres at each point which handles intersection of the spheres nicely.

Apologies for the delayed reply. My Hotmail account sadly classified the reply notification as ‘junk’.

You solution seems very elegant. I do not, however, understand how to supply my outer sphere material with the positions of the inner spheres dynamically.

I believe my problem statement was imprecise. The outer sphere is a transparent object and the inner spheres are actual game actors visible to the player. The outer sphere hull indicates that the contained spheres belong together in terms of game logic. Therefore the locations supplied to the SphereGradient3D node need to coincide with the positions of my inner sphere game actors. My understanding is, that for these positions to be visible to the outer sphere material, I need to use a MaterialParameterCollection. As they do not support array parameters, I need to have <number of inner spheres> vector parameter entries in my parameter collection to represent my inner sphere positions. These parameters are then set within the level blueprint each frame by using references to all my inner sphere actors and the SetVectorParameter node. Is this the correct way to go about this?

My level blueprint would therefore have the construct depicted by the figure below <number of inner spheres> times.

ec718050fe6eb649d339a0c3360d345f28331af5.jpeg

Yup, you have the right idea. Does not have to be an MPC, you could simply make an MID and pass all the params, but a collection will certainly make it cheaper to reuse the variables in other materials.