Added smoothstep
This commit is contained in:
parent
9ce0ded22e
commit
f73e566535
@ -706,6 +706,7 @@ void VoxelGeneratorGraph::_bind_methods() {
|
||||
BIND_ENUM_CONSTANT(NODE_CLAMP);
|
||||
BIND_ENUM_CONSTANT(NODE_MIX);
|
||||
BIND_ENUM_CONSTANT(NODE_REMAP);
|
||||
BIND_ENUM_CONSTANT(NODE_SMOOTHSTEP);
|
||||
BIND_ENUM_CONSTANT(NODE_CURVE);
|
||||
BIND_ENUM_CONSTANT(NODE_NOISE_2D);
|
||||
BIND_ENUM_CONSTANT(NODE_NOISE_3D);
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
NODE_CLAMP,
|
||||
NODE_MIX,
|
||||
NODE_REMAP,
|
||||
NODE_SMOOTHSTEP,
|
||||
NODE_CURVE,
|
||||
NODE_NOISE_2D,
|
||||
NODE_NOISE_3D,
|
||||
|
@ -181,6 +181,14 @@ VoxelGraphNodeDB::VoxelGraphNodeDB() {
|
||||
t.params.push_back(Param("min1", Variant::REAL, -1.f));
|
||||
t.params.push_back(Param("max1", Variant::REAL, 1.f));
|
||||
}
|
||||
{
|
||||
NodeType &t = types[VoxelGeneratorGraph::NODE_SMOOTHSTEP];
|
||||
t.name = "Smoothstep";
|
||||
t.inputs.push_back(Port("x"));
|
||||
t.outputs.push_back(Port("out"));
|
||||
t.params.push_back(Param("edge0", Variant::REAL, 0.f));
|
||||
t.params.push_back(Param("edge1", Variant::REAL, 1.f));
|
||||
}
|
||||
{
|
||||
NodeType &t = types[VoxelGeneratorGraph::NODE_CURVE];
|
||||
t.name = "Curve";
|
||||
|
@ -267,6 +267,13 @@ void VoxelGraphRuntime::compile(const ProgramGraph &graph) {
|
||||
append(program, max1 - min1);
|
||||
} break;
|
||||
|
||||
case VoxelGeneratorGraph::NODE_SMOOTHSTEP: {
|
||||
float edge0 = node->params[0].operator float();
|
||||
float edge1 = node->params[1].operator float();
|
||||
append(program, edge0);
|
||||
append(program, edge1);
|
||||
} break;
|
||||
|
||||
} // switch special params
|
||||
|
||||
#ifdef VOXEL_DEBUG_GRAPH_PROG_SENTINEL
|
||||
@ -355,6 +362,13 @@ struct PNodeRemap {
|
||||
float p_m1;
|
||||
};
|
||||
|
||||
struct PNodeSmoothstep {
|
||||
uint16_t a_x;
|
||||
uint16_t a_out;
|
||||
float p_edge0;
|
||||
float p_edge1;
|
||||
};
|
||||
|
||||
struct PNodeCurve {
|
||||
uint16_t a_in;
|
||||
uint16_t a_out;
|
||||
@ -586,6 +600,11 @@ float VoxelGraphRuntime::generate_single(const Vector3i &position) {
|
||||
memory[n.a_out] = ((memory[n.a_x] - n.p_c0) * n.p_m0) * n.p_m1 + n.p_c1;
|
||||
} break;
|
||||
|
||||
case VoxelGeneratorGraph::NODE_SMOOTHSTEP: {
|
||||
const PNodeSmoothstep &n = read<PNodeSmoothstep>(_program, pc);
|
||||
memory[n.a_out] = smoothstep(n.p_edge0, n.p_edge1, memory[n.a_x]);
|
||||
} break;
|
||||
|
||||
case VoxelGeneratorGraph::NODE_CURVE: {
|
||||
const PNodeCurve &n = read<PNodeCurve>(_program, pc);
|
||||
memory[n.a_out] = n.p_curve->interpolate_baked(memory[n.a_in]);
|
||||
@ -831,6 +850,14 @@ Interval VoxelGraphRuntime::analyze_range(Vector3i min_pos, Vector3i max_pos) {
|
||||
max_memory[n.a_out] = r.max;
|
||||
} break;
|
||||
|
||||
case VoxelGeneratorGraph::NODE_SMOOTHSTEP: {
|
||||
const PNodeSmoothstep &n = read<PNodeSmoothstep>(_program, pc);
|
||||
Interval x(min_memory[n.a_x], max_memory[n.a_x]);
|
||||
Interval r = smoothstep(n.p_edge0, n.p_edge1, x);
|
||||
min_memory[n.a_out] = r.min;
|
||||
max_memory[n.a_out] = r.max;
|
||||
} break;
|
||||
|
||||
case VoxelGeneratorGraph::NODE_CURVE: {
|
||||
const PNodeCurve &n = read<PNodeCurve>(_program, pc);
|
||||
if (min_memory[n.a_in] == max_memory[n.a_in]) {
|
||||
|
@ -205,4 +205,18 @@ inline Interval wrapf(const Interval &x, const Interval &d) {
|
||||
return x - (d * floor(x / d));
|
||||
}
|
||||
|
||||
inline Interval smoothstep(float p_from, float p_to, Interval p_weight) {
|
||||
if (Math::is_equal_approx(p_from, p_to)) {
|
||||
return Interval::from_single_value(p_from);
|
||||
}
|
||||
// Smoothstep is monotonic
|
||||
float v0 = smoothstep(p_from, p_to, p_weight.min);
|
||||
float v1 = smoothstep(p_from, p_to, p_weight.max);
|
||||
if (v0 <= v1) {
|
||||
return Interval(v0, v1);
|
||||
} else {
|
||||
return Interval(v1, v0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // INTERVAL_H
|
||||
|
@ -203,6 +203,15 @@ inline float wrapf(float x, float d) {
|
||||
return Math::is_zero_approx(d) ? 0.f : x - (d * Math::floor(x / d));
|
||||
}
|
||||
|
||||
// Similar to Math::smoothstep but doesn't use macro to clamp
|
||||
inline float smoothstep(float p_from, float p_to, float p_weight) {
|
||||
if (Math::is_equal_approx(p_from, p_to)) {
|
||||
return p_from;
|
||||
}
|
||||
float x = clamp((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f);
|
||||
return x * x * (3.0f - 2.0f * x);
|
||||
}
|
||||
|
||||
#if TOOLS_ENABLED
|
||||
namespace VoxelDebug {
|
||||
void create_debug_box_mesh();
|
||||
|
Loading…
x
Reference in New Issue
Block a user