2
$\begingroup$

I have a bunch eg 5,000 extruded objects (think columns) each of different height. All off these exist as a single object, ie they are grouped together rather than individual layer objects. I want to apply a colour ramp so that each of the individual columns are coloured based on their height value, rather than the entire group.

This doesn't mean that the colour ramp is applied against the z axis resulting in the object having a colour fade as is gets taller, but more like the entire coumn is coloured based on its maximum height, and therefore corresponding colour on the colour ramp.

The columns are "hex bins" of a 2km geographic area. Their individual height represents the urban density. See image attached.

Hope that makes sense. If you are able to post the script / specific setup for this then I would be grateful - I'm very, very new to Blender so please bear with me!enter image description here

$\endgroup$
  • $\begingroup$ I can't see any way of elegantly doing that, shader nodes don't have access to object size information, as far as I can tell. Animation nodes might be able to do it, though I've never tried it myself $\endgroup$ – Duarte Farrajota Ramos Jun 18 '19 at 9:08
  • $\begingroup$ Could be done via vertex colour similarly to blender.stackexchange.com/a/136926/15543 as long as each object has a unique mesh, or is one single joined mesh. $\endgroup$ – batFINGER Jun 18 '19 at 15:19
  • $\begingroup$ Hey thanks so much for your responses, @batFinger I don't think this would solve it as the colour assignment is random and for the entire object, rather than driven by the z value (max height). Essentially I want to colour the object based on this value. Thanks so much for your comments though! $\endgroup$ – LukeS Jun 18 '19 at 17:37
  • $\begingroup$ I understand the question, and can easily modify script to use z values to set colour instead of random, sheesh. Gives this result pasteall.org/pic/show.php?id=45a44b304ba3ea3ee6f198645a1383b7 using blue - green - red colour ramp, similar to weight paint on a random set of cylinders via blender.stackexchange.com/questions/135808/… The main issue is they are not animatable, ie once set remain at that value. $\endgroup$ – batFINGER Jun 18 '19 at 18:14
  • $\begingroup$ That's exactly what I was trying to achieve!! Thank you! Since I'm a complete noob, have you got an example of the modified script you used please? Would be very grateful. Thanks @Batfinger $\endgroup$ – LukeS Jun 19 '19 at 20:49
2
$\begingroup$

Achieving this with material nodes

I thought Generated and Object texture spaces differ and that can be used for this. Thanks to Robin Betts for figuring out the correct math.

Object's texture space goes from 0 to one in every direction on every axis from the origin of the object to the end of its bounding box in that axis, however Generated texture space matches the scale of global world space. If the origins of all objects are at their bottoms, their heights can be calculated by dividing the Z value of the object's texture space by the Z value of Generated texture space. The values can then be compressed to the desired range by dividing them by the height of the highest object. A Color Ramp node then can be used to remap the height values to colors:

enter image description here

$\endgroup$
  • 1
    $\begingroup$ Very good idea! Got a feeling it could be done with a simple division, so long as the origin of the object is at Z=0..or the shader-tree compensates via object info. A shading point's (Object-space Z)/(Generated Space Z) should = h? Since Object Space Z goes linearly from 0-h, and Generated Space Z goes linearly from 0-1. $\endgroup$ – Robin Betts Jul 31 '19 at 16:01
  • 1
    $\begingroup$ Yes, it can.. but I don't want to step on your answer.. I wouldn't have thought of it, myself $\endgroup$ – Robin Betts Jul 31 '19 at 16:51
  • $\begingroup$ Surely a 'so simple' but very nice discovery. Only constraint: origin point have to be at the bottom of the mesh (if not, linearity is broken) and (0,0) gives 0 (using obj.z/gen.z, so left part of the colorramp). Any idea to get rid of that? (@RobinBetts) $\endgroup$ – lemon Jul 31 '19 at 18:09
  • $\begingroup$ @RobinBetts, thank you! It seems so obvious now that you pointed it out. I'll update the answer when I have a few spare minutes. $\endgroup$ – Martynas Žiemys Jul 31 '19 at 18:46
  • $\begingroup$ @lemon ... you're right.. perhaps we can put a shift in to avoid 0/0 $\endgroup$ – Robin Betts Aug 1 '19 at 10:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.