I am trying to port a Blender shader to WGSL. My plan is to port over every node I need as a WGSL function (unless the node already has an equivalent in WGSL). Currently, I am trying to create an equivalent function for Blender's Map Range node.
Unfortunately, there doesn't seem to be a smooth transition in my implementation when compared to Blender's.
After browsing Blender's source, I found how the node is implemented on the Linear setting:
const float factor = safe_divide(value - from_min, from_max - from_min);
float result = to_min + factor * (to_max - to_min);
if constexpr (Clamp) {
result = clamp_range(result, to_min, to_max);
}
return result;
The image below is my node setup. The Map Range's Result is fed into the surface input of the Material Output node (so it can be visualized):
Below is how I implemented the Map Range node by referencing the code snippet above.
fn map_range(x: f32, from_min: f32, from_max: f32, to_min: f32, to_max: f32, clmp: bool) -> f32
{
let factor = (x - from_min) / (from_max - from_min);
var result = to_min + factor * (to_max - to_min);
if (clmp)
{
result = clamp(result, to_min, to_max);
}
return result;
}
Below is how I implement the function (note that this is ThreeJS TSL, and center_size is set to 10):
const wood_center = TSL.Fn(([p]) =>
{
const pxy_center = p.mul(TSL.vec3(1, 1, 0)).length();
const center = map_range(pxy_center, 0, 1, 0, center_size, true);
return center;
});
export const better_wood_material = new THREE.MeshStandardMaterial();
better_wood_material.colorNode = wood_center(TSL.positionWorld);
Blender's result:
My result:
I suspect the issue may be with my scene's lighting:
const point_light = new THREE.PointLight(new THREE.Color("#ffffff"), 20, 100);
point_light.position.set(1, 3, 3);
scene.add(point_light);
const ambient_light = new THREE.AmbientLight(new THREE.Color("#ffffff"), 0.1);
scene.add(ambient_light);
-
let factor = (x - from_min) / (from_max - from_min); // potential error, when (from_max - from_min) = 0, thats why they use safe divideMitro Juryev– Mitro Juryev2025年09月01日 18:34:08 +00:00Commented Sep 1, 2025 at 18:34
-
why you do vector multiplication by the way? Seems like you just want to measure distance from center, which you can achieve with subtraction center coordinates from positionMitro Juryev– Mitro Juryev2025年09月01日 18:35:16 +00:00Commented Sep 1, 2025 at 18:35
-
a quick fix will be just raise result to some power, and then with some values it will look more smooth. blender's screenshot, does not look like a linear function. However its still not clear what you are trying to achieve with this multiplication (seems like its cross product isnt it?). Also is center_size 10?Mitro Juryev– Mitro Juryev2025年09月01日 18:38:17 +00:00Commented Sep 1, 2025 at 18:38