0

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

Node Setup

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:

Blender's result

My 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);
jonrsharpe
123k31 gold badges278 silver badges489 bronze badges
asked Aug 7, 2025 at 12:25
3
  • let factor = (x - from_min) / (from_max - from_min); // potential error, when (from_max - from_min) = 0, thats why they use safe divide Commented 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 position Commented 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? Commented Sep 1, 2025 at 18:38

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.