Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Unity 2020 LTS & Unity 2021.1 have been released.
    Dismiss Notice
  3. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Resolved LWRP Custom Function with tex2dlod

Discussion in 'Shader Graph' started by Vyzier, May 8, 2019.

  1. Vyzier

    Vyzier

    Joined:
    Feb 22, 2015
    Posts:
    21
    Hello! I made this custom function in the shader graph but I seem to keep getting the following error:
    upload_2019-5-8_13-15-6.png

    I've tried both float4(uv, 0, 0) and float4(uv.x, uv.y, 0, 0) but I still keep getting the same error. I'm not quite sure what the problem is. Any help will be greatly appreciated!
     
  2. alexandral_unity

    alexandral_unity

    Unity Technologies

    Joined:
    Jun 18, 2018
    Posts:
    162
    Vyzier likes this.
  3. Vyzier

    Vyzier

    Joined:
    Feb 22, 2015
    Posts:
    21
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    10,096
    @alexandral_unity 's comment and link is misleading here, unless you actually read the entire page all the way to the bottom.

    SamplerState
    and sampler2D are different things. A SamplerState is a Direct3D 11 thing and is the sampler state alone (i.e.: filtering & wrapping settings), and you need a separate Texture2D (which is the texture object by itself) to sample from. Where as sampler2D is a Direct3D 9 thing and is the sampler state and texture combined. When you use a sampler2D, you need to call tex2D(sampler2D, uv). When you use SamplerState, you need to call Texture2D.Sample(SampleState, uv). You cannot use tex2D() with a SamplerState or Texture2D, and you cannot use .Sample() without a Texture2D and SamplerState.

    Shader Graph is written with D3D11 in mind, so it uses Texture2D and SamplerState objects and not sampler2D objects, so you cannot call tex2D() and have it work.*

    * BIG ASTERIKS HERE, because it can work if you were compiling directly to OpenGL ES 2.0. And, in fact, if you were to use .Sample() and try to build to an OpenGL ES 2.0 target it would fail because that API does not support separate SamplerState and Texture2D objects, so it needs to use sampler2D and tex2D().

    So the real answer is you shouldn't use either. Instead you should be using the macros Unity provides for the SRPs which handles all of that weirdness for you.

    fixed4 color = SAMPLE_TEXTURE2D(Texture2D, SamplerState, uv);

    Or in your case instead of tex2Dlod or .SampleLevel use SAMPLE_TEXTURE2D_LOD.

    Here's a full list of all of these kinds of macros that the SRPs use:
    https://github.com/Unity-Technologi...r-pipelines.core/ShaderLibrary/API/D3D11.hlsl

    Here's what a working Custom Function node looks like:
    upload_2019-5-8_13-51-16.png

    One oddity to be aware of, notice it is working even without a sampler state defined. In this case the sampler state used is not the one defined by the texture asset, but a new unique "bilinear repeat" sampler state. The shader does actually define a SamplerState for each texture property, and that is what gets used by their Sample Texture 2D nodes when no override is supplied, but currently there is no way to access that sampler state in a generic way using a Custom Function node. This doesn't really cause any issues, it's just something to be aware of. Plus, if you use multiples of the "same" Custom Function node in your Shader Graph without a connected Sampler State node, each one will use a unique SamplerState, each using up one of the max of 16 total allowed per shader.
     
    fherbst, csims314, Alex-CG and 5 others like this.
  5. Pancar

    Pancar

    Joined:
    Mar 11, 2013
    Posts:
    24
    I'm want to use SAMPLE_TEXTURE2D_LOD with URP-mobile , have you any advice?
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    10,096
    Either use the existing Sample Texture 2D LOD Node, or use the above Shader Graph Custom Function example as is. Unity should hopefully translate that to the appropriate SamplerState-less version needed for mobile. If you're aiming for OpenGLES 2.0, you can't use it, period. Otherwise report it as a bug.
     
  7. Pancar

    Pancar

    Joined:
    Mar 11, 2013
    Posts:
    24
    upload_2020-1-28_10-44-4.png upload_2020-1-28_10-44-4.png

    I'm using with Custom Function,it's working on Editor but when i'm testing on android , i can't see the object.
    My graphic api is OpenGLES3.
     
  8. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    10,096
    Yep, no idea. As far as I know that should work, but I've never played with mobile Shader Graph / SRP stuff.
     
  9. imaewyn

    imaewyn

    Joined:
    Apr 23, 2016
    Posts:
    179
    Hello. What if I use 2dArrays? There is only two macros
    UNITY_SAMPLE_TEX2DARRAY(name,uv)
    UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod)
    Both of them don't use samplers state..
     
  10. DMGregory

    DMGregory

    Joined:
    Jul 31, 2013
    Posts:
    2
    Looking at the file here, we can find the following macros for you to use:

    Code (CSharp):
    1. #define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index)                  textureName.Sample(samplerName, float3(coord2, index))
    2. #define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod)         textureName.SampleLevel(samplerName, float3(coord2, index), lod)
    3. #define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias)       textureName.SampleBias(samplerName, float3(coord2, index), bias)
    4. #define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
     
unityunity