3

I want to make a node group that outputs a polygon with a customizable size and side count.

enter image description here

I'm using arctan2 to make a setup that I figured would allow for a customizable side count.

enter image description here

If I add these nodes and mess around with the values I can get something closer, but it ever only results in rounded star shapes.

I can't seem to get a regular polygon.

BiggityBoys
  • 666
  • 4
  • 12

3 Answers3

2

Method result:

Changing side count:

dynamic poly side

Changing outer radius:

dynamic outer radius

Nodes:

material nodes

Explanation:

What we are doing here is verifying the difference between the texture coordinates and a vertical line, but we need to cycle the angle θ of that coordinate when it points past the polygon segment lenght in the line (sometimes i'm bad at explaining so look this):

poly distance math

https://www.desmos.com/calculator/tqy07xvs14

With this method, instead of using a less than 1 node, you can also use ColorRamps:

poly with ColorRamp

Hulifier
  • 6,048
  • 1
  • 8
  • 24
1

Square to pentagon material

enter image description here

Node

You can use this method to do any shape

enter image description here

Run the script, you can get entire scene

import bpy, math

select and del all object

bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.select_all(action = "SELECT") bpy.ops.object.delete(use_global=True, confirm=False)

add plane

bpy.ops.mesh.primitive_plane_add(size=2, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, 1))

oj = bpy.context.object mat = bpy.data.materials.new(name="Material")

oj.data.materials.append(mat) mat.use_nodes = True

tree = mat.node_tree nodes = tree.nodes l = tree.links

coor = nodes.new("ShaderNodeTexCoord") coor.location.x += -300 coor.location.y += -1200

def new_mapp(dx=0, dy=0): node = nodes.new("ShaderNodeMapping") node.location.x += dx node.location.y += dy node.vector_type = "TEXTURE" return node

def new_rang(dx=0, dy=0): node = nodes.new("ShaderNodeMapRange") node.location.x += dx node.location.y += dy node.inputs["From Max"].default_value = 0.001 return node

def new_invert(dx=0, dy=0): node = nodes.new("ShaderNodeInvert") node.location.x += dx node.location.y += dy return node

def new_mix(dx=0, dy=0): node = nodes.new("ShaderNodeMixRGB") node.location.x += dx node.location.y += dy node.blend_type = 'MULTIPLY' node.inputs[0].default_value = 1 return node

mapp1 = new_mapp() mapp1.inputs["Location"].default_value[1] = 0.5 mapp1.inputs["Rotation"].default_value[2] = math.radians(279) rang1 = new_rang(200)

l.new(coor.outputs["UV"], mapp1.inputs["Vector"]) l.new(mapp1.outputs["Vector"], rang1.inputs[0])

mapp2 = new_mapp(0, -600) mapp2.inputs["Location"].default_value[1] = 0.5 mapp2.inputs["Rotation"].default_value[2] = math.radians(-369) rang2 = new_rang(200, -600)

l.new(coor.outputs["UV"], mapp2.inputs["Vector"]) l.new(mapp2.outputs["Vector"], rang2.inputs[0])

mapp3 = new_mapp(0, -1200) mapp3.inputs["Location"].default_value[1] = -0.08778525229247 mapp3.inputs["Rotation"].default_value[2] = math.radians(-297) rang3 = new_rang(200, -1200)

l.new(coor.outputs["UV"], mapp3.inputs["Vector"]) l.new(mapp3.outputs["Vector"], rang3.inputs[0])

mapp4 = new_mapp(0, -1800) mapp4.inputs["Location"].default_value[1] = 1 +0.08778525229247 mapp4.inputs["Rotation"].default_value[2] = math.radians(-153) rang4 = new_rang(200, -1800)

l.new(coor.outputs["UV"], mapp4.inputs["Vector"]) l.new(mapp4.outputs["Vector"], rang4.inputs[0])

mapp5 = new_mapp(0, -2400) mapp5.inputs["Location"].default_value[0] = 1 -0.09549150281253 mapp5.inputs["Rotation"].default_value[2] = math.radians(-225) rang5 = new_rang(200, -2400)

l.new(coor.outputs["UV"], mapp5.inputs["Vector"]) l.new(mapp5.outputs["Vector"], rang5.inputs[0])

mix1 = new_mix(500, -200) mix2 = new_mix(700, -800) mix3 = new_mix(900, -1400) mix4 = new_mix(1100, -2000)

l.new(rang1.outputs["Result"], mix1.inputs["Color1"]) l.new(rang2.outputs["Result"], mix1.inputs["Color2"]) l.new(mix1.outputs["Color"], mix2.inputs["Color1"]) l.new(rang3.outputs["Result"], mix2.inputs["Color2"]) l.new(mix2.outputs["Color"], mix3.inputs["Color1"]) l.new(rang4.outputs["Result"], mix3.inputs["Color2"]) l.new(mix3.outputs["Color"], mix4.inputs["Color1"]) l.new(rang5.outputs["Result"], mix4.inputs["Color2"])

bsdf = nodes["Principled BSDF"] bsdf.location.x += 1300 bsdf.location.y += -1500

outp = nodes["Material Output"] outp.location.x += 1300 outp.location.y += -1500

l.new(mix4.outputs["Color"], bsdf.inputs["Alpha"])

X Y
  • 5,234
  • 1
  • 6
  • 20
0

Here's my take:

Alternative:

The idea is the same as in Hulifier's answer, rather than calculating how distance to edge changes with angle, just rotate the coordinate system so all directions point to the left. Since radial gradient starts in the middle of "the left", either use the first solution to rotate the first half of the 1st side angle to the bottom-left, and the 2nd half of the last side angle to the top-left, or use the second solution to first rotate the coordinate system so the radial gradient actually starts at the beginning of "the left"... (preview the output of the Snap node to see that better).

Markus von Broady
  • 36,563
  • 3
  • 30
  • 99