4

I'm drawing a dot-pattern, based on a vector grid (a) onto a plane. Based on the position of two empties, that can move on the plane, there are masks (b) generated.

I then combine both of them (c), however I'd like to ignore (or complete) those dots, that are partially obstructed by the mask, so that only whole dots are being drawn (d).

Is there a way to achieve only whole dots, either by completing or deleting "partial-dots" within my mask?


different stages of my texture

node-setup

I currently use these nodes to blend them together.

Timaroberts
  • 12,395
  • 6
  • 39
  • 73
Quacksilber
  • 588
  • 6
  • 20
  • feel free to change the title of this question, if you find a better description for my problem ^^ – Quacksilber Oct 26 '20 at 14:43
  • 2
    Yes, but... Can you give an idea of the use-case? e.g Are the masks always 1-unit squares? Would you like arbitrary images encoded as dot-patterns? All possible, but some things need bigger trees than others.... and you can probably simplify your existing tree considerably – Robin Betts Oct 26 '20 at 16:01
  • Do you want to fix it keeping existing node groups, or would you accept to change at least one of them? – lemon Oct 26 '20 at 17:08
  • 1
    I want to use this as a face for a robot. Think of it like a display, which shows the eyes. By scaling the empties you can change the size and rotation of the masks. In the end I would connect this to a rig (where is the character looking) and add shape keys for different emotions. – Quacksilber Oct 26 '20 at 17:12
  • @lemon I'm happy to change up the whole thing, as long as I'm able to achieve above described behaviour :D (using it for the eye rig and implementing some emotions via shape keys) – Quacksilber Oct 26 '20 at 17:14
  • The current node-setup was just the only way I could think of it, my knowledge of procedural textures with vectors, etc. is somewhat limited – Quacksilber Oct 26 '20 at 17:15

1 Answers1

3

Rather than trying to make the dots behave to fully hide/show based on whether there are wholly or part within the masked regions, it is far simpler to control the masks so that they only ever cover whole dot regions. This can be done using the Modulo function to calculate the distance to the nearest boundary and adjust the edge to that boundary. In this way the mask edge will 'jump' to a suitable position where it will not cut any of the dots.

Consider the following material nodes :

full material

The Object coordinates from the Empty (Texture Coordinate node near the top) are used to produce the mask by applying an Absolute operation followed by a Less Than on each of the channels. The result is combined using Minimum to produce the mask. Note that the Vector Math node is used for Absolute to perform the same operation on each channel of the vector. In this way, moving the Empty moves the mask and changing the values in the Less Than nodes will affect the Width and Height of the mask around that point of the Empty. Note that for this to work the Empty must have the same Rotation and Scale as the main mesh (otherwise the coordinate systems won’t work).

In addition, a modulo (*see below) operation is applied to the Object coordinates. This will return the remainder of dividing the coordinates by the desired 'pitch' (size) of the grid. By Subtracting this from the coordinates used for the mask we effectively offset the boundary of the mask to the edge of the grid defined by the 'dot pitch'. The result of the Modulo is also used to indicate the position within each grid cell and this is used (by scaling (Divide), offsetting (Subtract 0.5) and getting the Length to determine the distance from the centre of a circle to generate each 'dot' (controlled by the other Less Than node).

The result of the mask and the 'dot' is combined via a Multiply node to produce only complete dots within the mask.

Note : The standard Modulo function handles negative values by outputting a negative result. This is not suited to generating a grid in this way but the Modulo, Add, Modulo operations correct for this (see https://blender.stackexchange.com/a/122489/29586 for an explanation of this).

Here's the result of moving the Empty.

moving empty

The Value node can be adjusted to set the 'dot pitch', the X and Y Less Than nodes to adjust the mask Width and Height respectively, and the Length Less Than node to adjust the 'dot size'. The empty can then be used to position the mask and only complete dots will be shown.

In order to support multiple masks, simply replicate the 'top row' of nodes (from the Texture Coordinate of the Empty to the Multiply used to merge with the dots) for each 'Empty' in use - and combine each row with a Maximum node.

multiple masks

Rich Sedman
  • 44,721
  • 2
  • 105
  • 222