Cannot sample texture2d in custom shader node

I have written a custom node that accepts a UnityTexture2D, and the Position (Object Space) represented as a float3 position. I want to sample the texture at the current position’s x&y, but keep getting an error:

Shader error in 'Master': cannot map expression to vs_5_0 instruction set at ../PackageCache/com.unity.render-pipelines.core@13.1.6/ShaderLibrary/Texture.hlsl(45) (on d3d11)```

When I inspect the linked file it appears my structure is correct, why is this not working?

```csharp
void MyFunction_float(
        float3 position,
        UnityTexture2D resistances,
        UnitySamplerState sampler_resistances,
        out float3 Out)
{
    float2 textureCoord = float2(position.x, position.z);
    float4 resistanceColor = resistances.Sample(sampler_resistances, textureCoord);
    float coordResistance = resistanceColor.r;

    Out = position;
    Out.y = position.y + coordResistance;
}

I appear to have gotten this working with Tex2Dlod, but still curious as to why it wouldnt work with Sample.

    float4 resistanceColor = tex2Dlod(resistances, float4(textureCoord, 0, 0));

I think the issue is that .Sample is not a thing in URP.
Check how they do it in these docs:
https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@13.1/manual/writing-shaders-urp-unlit-texture.html

Hi,

AFAIK, you need to use the function wrapper, which handles multi-platforms and cross-pipeline functionality:

float4 resistanceColor = SAMPLE_TEXTURE2D(resistances, resistances.samplerstate, uv);

I got this working. A generic example of how to run a texture2d into a custom function node.
Hope this is helpful to anyone else that stumbles on this.

void TextureInputExample_float(
        float2 uv,
        UnityTexture2D tex,
        UnitySamplerState sampler_tex,
        out float4 outColor)
{
    float2 textureCoord = float2(uv.x, uv.y);
    float4 calcColor = tex.Sample(sampler_tex, textureCoord);
    calcColor *= 0.1;

    outColor = calcColor;
    
}

Hi @Mindtoast451,

thanks for sharing.
Please allow me to ask why you multiply the result by 0.1? You shouldn’t have to.

I’d also like to add a few suggestions:

  • You don’t need to create a new float2 from the float2 input.
  • You don’t need to reference a SamplerState unless you want to optimize the number of sample states in you shader, you can just use tex.samplerstate.
  • It’s preferable to use the macro SAMPLE_TEXTURE2D than tex.Sample(), so that it works on all platforms the same.

This works:

void SampleTex2d_float(
        float2 uv,
        UnityTexture2D tex,
        out float4 outColor)
{
    outColor = SAMPLE_TEXTURE2D(tex, tex.samplerstate, uv);
}