Hi,
I want to query the LOD, that would be used, when I sample a texture at a given location.
I tried to use textureQueryLod directly with the OpenGL backend, however Unity fails to compile the shader.
Shader error in ‘Custom/MySurfaceShader’: undefined variable “textureQueryLod” at line 216 (on d3d9)
A solution working with either OpenGL or DX11 would be fine at this point.
Thanks,
Tom
Adding the following definition in the CG shader code enabled me to query the LOD:
#if defined(SHADER_API_D3D11) || defined(SHADER_API_GLCORE)
#define UNITY_LOD_TEX2D(tex,coord) tex.CalculateLevelOfDetail (sampler##tex,coord)
#else
// Just match the type i.e. define as a float value
#define UNITY_LOD_TEX2D(tex,coord) float(0)
#endif
// ...
float lod = UNITY_LOD_TEX2D(_MainTex, uv);
Note that CalculateLevelOfDetail
is a D3D function, but still works with the OpenGL backend here, while I had no success with the native textureQueryLod
function.
However, if your intent is to use this LOD to sample from a texture again, I suggest that you use the SampleGrad
method instead (a macro can be defined analogously).
This preserves anisotropic filtering of the texture if it is enabled.
The gradient of the uv
coordinates in screen space can be computed using the built-in functions ddx(uv)
and ddy(uv)
, respectively.
#if defined(SHADER_API_D3D11) || defined(SHADER_API_GLCORE)
#define UNITY_SAMPLE_TEX2D_GRAD(tex,coord,dx,dy) tex.SampleGrad (sampler##tex,coord,dx,dy)
#else
// Just match the type i.e. define as a float4 vector
#define UNITY_SAMPLE_TEX2D_GRAD(tex,coord,dx,dy) float4(0,0,0,0)
#endif
// ...
float4 color = UNITY_SAMPLE_TEX2D_GRAD(_MainTex, uv, ddx(uv), ddy(uv));
Thanks, your answer is freaking awesome!
I defined a macro to use the SampleGrad function in my vert/frag shader. It worked as expected. When I switched to surface shader with the same macro, it didn’t compile and gave me an “unexpected (” error even with #pragma target 5.0.
After adding the #if that you suggested, everything is fine now. It seems like when translating surface shader to vert/frag shader, Unity doesn’t check for #pragma target 5.0 but rely on SHADER_API_D3D11 and SHADER_API_GLCORE.