5
$\begingroup$

Can I use the vertices of a mesh as an input for site points of the voronoi cells (voronoi sites) to create a voronoi procedural texture with the Node Editor for the very same mesh?

I need something simpler (no extra features, no real time update necessary), but kinda similar like in this video, between 0:30 and 0:45.
https://youtu.be/Aljbw9PQlck?t=31

EDIT: The video is a bit misleading, cos it shows real time update, thought it would be nice (for easier edit) if possible but it isn't necessary. Main goal is a full control over the position of the cells.

The input mesh is suppose to be kinda a Delaunay-triangulation, except the 'triangulation' part, how the edges connect the vertices is not important only the vertices as site points for cells.

$\endgroup$
  • 2
    $\begingroup$ Unless you resort to do the computation manually for each point, then no, there no way to do that in Cycles. You can, however, do it in Animation Nodes using Vertex Colors, Screen Space Rasterization or UV Space Textures. I can show you how to do that, but it is not easy or convenient. $\endgroup$ – Omar Emara Mar 13 '18 at 19:21
  • 1
    $\begingroup$ Since your linked example uses GLSL (OpenGL Shading language) a language designed to write shaders for real-time rendering, you should use OSL (Open Shading Language) which is very similar to GLSL, but it is designed for non-real-time rendering. You can write OSL into a script node. $\endgroup$ – atevm Mar 13 '18 at 21:45
  • $\begingroup$ @atevm How are you going to pass the points locations to OSL? $\endgroup$ – Omar Emara Mar 14 '18 at 18:30
  • $\begingroup$ @atevm Thanks for the comment it was really helpful. Sorry for the misleading video. Non-real-time is okay for now, all I want is full control over the placement of the cells by adding vertices for a mesh, kinda as it shown in the video. The mesh should be the same one that get the generated texture or shader. I will check what I am able do with OSL. So, yes, Omar question is on the spot, but it sounds to me as a difficult topic. $\endgroup$ – kca Mar 15 '18 at 14:05
  • 1
    $\begingroup$ Yes, Animation Nodes (AN) is an addon. Last year, I created something like this: i.imgur.com/7arUMVe.gifv It is a combination between manual points locations and random points location, so I can write an answer about the manual points location if you want. $\endgroup$ – Omar Emara Mar 15 '18 at 16:50
4
$\begingroup$

Animation Nodes can be used to dynamically generate voronoi diagrams. Storing the color information of the diagram and accessing it from the render engine is a problem and our options are limited, one option is to use vertex colors, where the quality depends on the number of loops in the target mesh.

Vertex Color

First, you should study how vertex colors works in blender and how to assign it using Animation Nodes and Python. For this, you should see my answer here. I will be using the Vertex Sample and Vertex Colors subprograms defined there in my node trees, so make sure you implement them first.

A simple F1 vornoi diagram based on random points can be generated using a KD tree as follows:

Simple F1 Vorinoi Diagram

If one wants to use custom points locations, then one should replace the random locations with the custom locations:

Custom Voronoi Diagram

If you want to have a solid color for each voronoi cell, then the indices output can be used or a random number based on it:

Solid Cells

You might notice that the quality starts to become rather low, and that is the downside of using vertex colors, they are dependent of the loop count.


The other options we have are not any nicer, but they might be suitable for some cased.

Screen Space Tracing

What we can do is make a small render engine of our own that renders the vornoi as a fragment shader and use the output in the more advanced render engine. The render engine will cast a number of rays on the mesh defined by a BVH Tree, get the location on the surface point they hit, use it in the KD Tree, and then write the output colors to an image. To write an image given the greyscale value of each pixel, its width, height and name, a script like this can be used:

if imageName in bpy.data.images:
    image = bpy.data.images[imageName]
    image.generated_width = width
    image.generated_height = height
else:
    image = bpy.data.images.new(imageName, width, height)

image.pixels = [v for color in colors for v in [color]*4]

The ray casting part is simple, align a grid with the camera orientation and location, scale it based on the orthographic scale (3 in my case), we will perform an extra 90 degree rotation around the local z axis because the grid node returns the locations in the vertically first order while blender expects a horizontally first order, the node tree is as follows:

Render Engine Node Tree

You may see the rendered image in near realtime in the UV image editor

Render Engine Result

Now, if I used the Windows texture coordinates (Screen Space Coordinates) with a material like this:

Screen Space

We will get the render projected on our object, which we can then use to do what ever we want:

Screen Space Result

I created this to work in orthographic view, I will let you create the perspective version on your own.


Other methods include UV space projection, it can be done as following. BVH ray cast is used to get the index of the polygon the ray intersect, we get the barycentric coordinates of the surface point through a barycentric interpolation, we get the UV space locations of the polygon's corresponding UV polygon, perform a convex combination using the barycentric coordinates we computed before, get the pixel nearest to the result of the convex combination or use some kind of interpolation like bilinear or bicubic, write the color to it. The resulted image can be used in the UV objects space as a normal texture. I shall not explain this method, because it doesn't really have any advantages and is hard and slow to implement.

$\endgroup$
  • $\begingroup$ Thanks! I managed to reproduce the "Vertex Color" version. Still have questions. 1. I checked the link of your answer about vertex colors. I still miss the part how to convert the distance floats to color vectors in the loop graph part of the graph. I made a simple one (LoopInput-GetListElement-mathMultiply-CombineVec-VecList), but I would like to know, how you did it. 2. Looks like, based on your gifs, when you move around the 'spherical empties', it happens in object mode. Why can I only see the cells when the interactionMode is VertexPaint and displayMode is Texture or Solid? $\endgroup$ – kca Mar 25 '18 at 1:28
  • $\begingroup$ Ok, for the 2nd question I find a very short video: link $\endgroup$ – kca Mar 25 '18 at 1:57
  • $\begingroup$ @kca The Vertex Sampler Loop is exactly as you described, however, since the color a greyscale one, that is, all the vector components are the same, we can use the node Vector From Value to create the vectors. I guess you know the answer for the second question. $\endgroup$ – Omar Emara Mar 25 '18 at 14:01

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.