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);
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 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 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 at 18:38

0

Your Answer

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.