Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Bug "Clip" function fails on raytracing passes with "Opcode Discard not valid in shader model lib_6_3"

Discussion in 'HDRP Ray Tracing' started by merpheus, Oct 13, 2021.

  1. merpheus

    merpheus

    Joined:
    Mar 5, 2013
    Posts:
    202
    I am trying to use the clip function in raytracing passes (not via shadergraph but with regular code) but I get "Opcode Discard not valid in shader model lib_6_3(anyhint)" message(there are variants for closehit too, the discard code works with regular raster passes. It gives this error on raytracing.

    If clipping/discard is not supported on raytracing shaders, is there a way to do clip other than using this?
     
  2. INedelcu

    INedelcu

    Unity Technologies

    Joined:
    Jul 14, 2015
    Posts:
    173
    clip and discard are rasterization instruction available in pixel shaders only.
    https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-clip

    You can get a similar functionality in ray tracing using anyhit shaders where alpha can come from a texture. Anyhit shaders are usually used for alpha tested / cutout Materials. If you use RayTracingAccelerationStructure.AddInstance functions you'll need to specify just RayTracingSubMeshFlags.Enable - this will enable anyhit shaders.

    Some example:

    _Cutoff and _MainTex are shader properties.

    [shader("anyhit")]
    void AnyHitMain(inout RayPayload payload : SV_RayPayload, AttributeData attribs : SV_IntersectionAttributes)
    {
    uint3 triangleIndices = UnityRayTracingFetchTriangleIndices(PrimitiveIndex());
    Vertex v0, v1, v2;
    v0 = FetchVertex(triangleIndices.x);
    v1 = FetchVertex(triangleIndices.y);
    v2 = FetchVertex(triangleIndices.z);
    float3 barycentricCoords = float3(1.0 - attribs.barycentrics.x - attribs.barycentrics.y, attribs.barycentrics.x, attribs.barycentrics.y);
    Vertex v = InterpolateVertices(v0, v1, v2, barycentricCoords);
    float alpha = _MainTex.SampleLevel(sampler__MainTex, _MainTex_ST.xy * v.uv + _MainTex_ST.zw, 0).w;
    if (alpha < _Cutoff)
    IgnoreHit();
    }