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);


