Implement map range node

Map range node should now be fully supported
This commit is contained in:
Alexander Kleemann 2021-03-23 21:52:21 +01:00
parent 362fffa408
commit 07741abc55
2 changed files with 93 additions and 0 deletions

View file

@ -402,4 +402,67 @@ vec3 blackbody(const float temperature){
return rgb;
}
"""
# Adapted from https://github.com/blender/blender/blob/594f47ecd2d5367ca936cf6fc6ec8168c2b360d0/source/blender/gpu/shaders/material/gpu_shader_material_map_range.glsl
str_map_range_linear = """
float map_range_linear(const float value, const float fromMin, const float fromMax, const float toMin, const float toMax) {
if (fromMax != fromMin) {
return float(toMin + ((value - fromMin) / (fromMax - fromMin)) * (toMax - toMin));
}
else {
return float(0.0);
}
}
"""
str_map_range_stepped = """
float map_range_stepped(const float value, const float fromMin, const float fromMax, const float toMin, const float toMax, const float steps) {
if (fromMax != fromMin) {
float factor = (value - fromMin) / (fromMax - fromMin);
factor = (steps > 0.0) ? floor(factor * (steps + 1.0)) / steps : 0.0;
return float(toMin + factor * (toMax - toMin));
}
else {
return float(0.0);
}
}
"""
str_map_range_smoothstep = """
float map_range_smoothstep(const float value, const float fromMin, const float fromMax, const float toMin, const float toMax)
{
if (fromMax != fromMin) {
float factor = (fromMin > fromMax) ? 1.0 - smoothstep(fromMax, fromMin, value) :
smoothstep(fromMin, fromMax, value);
return float(toMin + factor * (toMax - toMin));
}
else {
return float(0.0);
}
}
"""
str_map_range_smootherstep = """
float safe_divide(float a, float b)
{
return (b != 0.0) ? a / b : 0.0;
}
float smootherstep(float edge0, float edge1, float x)
{
x = clamp(safe_divide((x - edge0), (edge1 - edge0)), 0.0, 1.0);
return x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
}
float map_range_smootherstep(const float value, const float fromMin, const float fromMax, const float toMin, const float toMax) {
if (fromMax != fromMin) {
float factor = (fromMin > fromMax) ? 1.0 - smootherstep(fromMax, fromMin, value) :
smootherstep(fromMin, fromMax, value);
return float(toMin + factor * (toMax - toMin));
}
else {
return float(0.0);
}
}
"""

View file

@ -8,6 +8,36 @@ import arm.material.cycles_functions as c_functions
from arm.material.parser_state import ParserState
from arm.material.shader import floatstr, vec3str
def parse_maprange(node: bpy.types.ShaderNodeMapRange, out_socket: bpy.types.NodeSocket, state: ParserState) -> floatstr:
interp = node.interpolation_type
value: str = c.parse_value_input(node.inputs[0]) if node.inputs[0].is_linked else c.to_vec1(node.inputs[0].default_value)
fromMin = float(c.parse_value_input(node.inputs[1]))
fromMax = float(c.parse_value_input(node.inputs[2]))
toMin = float(c.parse_value_input(node.inputs[3]))
toMax = float(c.parse_value_input(node.inputs[4]))
if interp == "LINEAR":
state.curshader.add_function(c_functions.str_map_range_linear)
return f'map_range_linear({value}, {fromMin}, {fromMax}, {toMin}, {toMax})'
elif interp == "STEPPED":
steps = float(c.parse_value_input(node.inputs[5]))
state.curshader.add_function(c_functions.str_map_range_stepped)
return f'map_range_stepped({value}, {fromMin}, {fromMax}, {toMin}, {toMax}, {steps})'
elif interp == "SMOOTHSTEP":
state.curshader.add_function(c_functions.str_map_range_smoothstep)
return f'map_range_smoothstep({value}, {fromMin}, {fromMax}, {toMin}, {toMax})'
elif interp == "SMOOTHERSTEP":
state.curshader.add_function(c_functions.str_map_range_smootherstep)
return f'map_range_smootherstep({value}, {fromMin}, {fromMax}, {toMin}, {toMax})'
def parse_blackbody(node: bpy.types.ShaderNodeBlackbody, out_socket: bpy.types.NodeSocket, state: ParserState) -> vec3str: