0

I need a step function map values, I'm trying to use float curve (in Geometry Nodes) to do that, but the float curve always has a transition, can't get a vertical straight line. The problem is that I need a sharp vertical jump, the float curve transition ruins it. Then I turn to the color ramp, but the color ramp has a limit of 30 steps at most to create. Any ideas to get a step function? To be clear, what I want is not a stair step, here are examples of my case, when 0<x<0.2, y=0.35; 0.2<x<0.38, y=0.65; 0.38<x<0.47, y=0.29, etc. I have many steps like this, so manually switch them is not an option, the float curve actually is ideal for it but the transition of float curve just kill it. The color ramp is also an option, but it has a limitation of 32 steps, but sometimes I need hundreds of steps.

enter image description here

baby boss
  • 9
  • 3
  • 1
    Use a Math node set to Snap. – Gordon Brinkmann Mar 08 '24 at 21:04
  • After investigation, I don't think the math node snap function fits my problem, my step is not stair step, the y value gaps are different on different x range. – baby boss Mar 08 '24 at 21:55
  • 1
    So, you have 30+ steps and no regularity/repetition on the x spacing or y spacing ? – Lutzi Mar 08 '24 at 22:08
  • You said you need a "step function", and the Snap node is exactly that. So I have to ask similar to @Lutzi if you have no regular spacing or how should I understand your comment? – Gordon Brinkmann Mar 09 '24 at 00:06
  • @babyboss: please edit your question and add it with more information, so that it is crystal clear what you wanna have and we don't have to ask in comments for details. thx. – Chris Mar 09 '24 at 04:47
  • Thank you @Gordon Brinkmann, what I understand is that the snap node only deals with on y=x line, here are examples of my problem, when 0.0<x<0.2, y=0.30; 0.2<x<0.5, y=0.75; 0.5<x<0.68, y=0.33; this is also step function, right? I don't see how the snap node can deal with this situation. – baby boss Mar 09 '24 at 06:11
  • Thank you @Lutzi, I hope I make it clear on the previous comment. – baby boss Mar 09 '24 at 06:12
  • Thank you @Chris, I hope I make it clear on the previous comment. – baby boss Mar 09 '24 at 06:12
  • 1
    since you want different step width for different intervals, there is no "common" solution. You have to use math nodes with switches and compare nodes to do that. Except there is a math formula you have, but you didn't present one, so the answer is: You have to do it on your own. – Chris Mar 09 '24 at 10:18
  • and again: "normally" you should edit your question, so that people won't have to read comments to understand what you mean. – Chris Mar 09 '24 at 10:19
  • 1
    Hello, baby boss, this discussion in the comments has the potential to get very long and tangled.. An edit to your post to include your specific use-case could prevent a lot of shooting in the dark by folks who would like to help. I bet there's a way, but we would have to know exactly where to. – Robin Betts Mar 09 '24 at 10:32

1 Answers1

1

The Color Ramp node is implemented internally by baking the function to a 1D texture. Sampling the texture at x looks up the value of f(x). So one way to do it would be to create your own lookup texture.

This script will generate the texture. Edit the parts above the ##### to what you want.

import bpy

Name of the image

name = 'StepLut'

Stops where the function changes value

X values must be increasing and between 0 and 1

Y values can be anything

stops = [ # X, Y 0.0, 0.35, # if 0.0 <= x < 0.2, then y = 0.35 0.2, 0.65, # if 0.2 <= x < 0.38, then y = 0.65, etc. 0.38, 0.29, 0.47, 1.0, ]

Width of LUT image

Higher values give better accuracy

width = 1000

img = bpy.data.images.new( name=name, width=width, height=1, float_buffer=True, is_data=True, )

Pad stops to simplify sampling

stops = [-1.0, stops[1], *stops, 2.0, stops[-1]]

Sample step function at each texel

pixels = [] stop_i = 0 for i in range(width): x = (i + 0.5) / width # i-th texel center while x >= stops[2*stop_i+2]: stop_i += 1 y = stops[2*stop_i+1] pixels += [y, y, y, 1.0]

img.pixels.foreach_set(pixels) img.pack()

Then to use it in the node editor, just create an Image Texture node with your image and set it to "Closest". Feed the value you want to sample at into the texture node, and the value of the function will come out of the Color socket (in all three color channels).

Note that like for Color Ramps, the input will be rounded to the nearest texel center, which may cause rounding errors, see https://projects.blender.org/blender/blender/issues/74198. You can decrease this effect by increasing the width variable.

scurest
  • 10,349
  • 13
  • 31