WinCNT

Nova Shader의 ParticlesUberLit이 VR모드에서 정상적으로 렌더링 되지 않던 이슈 본문

Unity/Unity 개발 중 발생한 이슈 정리

Nova Shader의 ParticlesUberLit이 VR모드에서 정상적으로 렌더링 되지 않던 이슈

WinCNT_SSS 2024. 4. 2. 12:51

발생한 이슈

VR모드에서 Nova Shader의 ParticlesUberLit가 제대로 렌더링하지 않는 이슈가 발생했다

참고로 VR모드란 유니티 에디터의 재생 모드를 Oculus Link에서도 실행시키는 것을 말한다 빌드를 하지 않고 바로 VR기기에서 바로 확인할 수 있고, 유니티 에디터도 조작할 수 있어서 편리하다


이슈 상세

ParticlesUberLit의 파티클의 렌더링이 조건에 따라 달라졌다

  • 실행 파일(APK, EXE): 파티클이 VR기기의 왼쪽 스크린에만 렌더링(확인 필요)
  • 유니티 에디터(기본) : 파티클이 문제 없이 렌더링
  • VR모드의 VR기기 : VR기기에서는 파티클이 아예 렌더링 안 됨
  • VR모드의 유니티 에디터 : Scene View에서만 파티클이 렌더링

Scene View에서만 파티클이 렌더링된다


발생 원인

나쁜 건 Nova Shader가 아니었다

Single-pass Instanced Rendering에 대응하기 위해 Nova Shader를 조금 커스텀마이징했는데 그것이 미흡했던 것…

변명하자면 필자가 한 건 아니다

Unity - Manual: Single-pass instanced rendering and custom shaders

 

Unity - Manual: Single-pass instanced rendering and custom shaders

Single-pass instanced rendering and custom shaders URP, HDRP, ShaderGraph, Surface shadersA program that runs on the GPU. More infoSee in Glossary, and built-in shaders already support single-pass stereo instanced rendering. However, shaders from the Asset

docs.unity3d.com

 

ParticlesUberLit를 Complie and show code를 하니, 에러가 발생하고 있었다

 

중복 선언했다는 컴파일 에러가 발생한 부분을 봐도 딱히 문제되는 건 없어보였으나…

위쪽에 이상한 게 있다는 것을 깨달았다!

 

아니나 다를까 Attributes와 Varyings를 확인해보니 ParticlesUberUnlit.hlsl에 이미 Single-pass Instanced Rendering 대응 코드가 있었다!!

 

버텍스 셰이더, 픽셀 셰이더도 조금 살펴보니, ParticlesUberLit은 우선 ParticlesUberUnlit의 처리를 하고 난 뒤, 이어서 Lighting 처리를 하는 구조인 것 같았다

// ParticlesUberUnlit.hlsl
VaryingsLit vertLit(AttributesLit input)
{
    VaryingsLit output = (VaryingsLit)0;
    
    // Single-pass Instanced Rendering 대응 코드
    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_TRANSFER_INSTANCE_ID(input, output);
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
    
    // vertUnlit를 호출하고 있다!!!
    output.varyingsUnlit = vertUnlit(input.attributesUnlit, output.positionWS, true, true);

    // ...생략...

    return output;
}

/**
 * \\brief Fragment shader entry point. 
 */
half4 fragLit(VaryingsLit input) : SV_Target
{
    // Single-pass Instanced Rendering 대응 코드
    UNITY_SETUP_INSTANCE_ID(input);
    UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
    
    // fragUnlit를 호출하고 있다!!!
    half4 albedoColor = fragUnlit(input.varyingsUnlit, true);

    // ...생략...

    return color;
}

 

이쪽도 당연히 vertUnlit와 fragUnlit 안에도 이미 Single-pass Instanced Rendering 대응 코드가 있기 때문에 컴파일 에러의 원인이 되고 있었다


해결법

원인을 확실히 찾았으니 해결책은 간단!

ParticlesUberLit.hlsl와 ParticlesUberLitForward.hlsl에 있던 Single-pass Instanced Rendering 대응 코드를 지우면 끝!

이제 Scene View, Game View 모두에서 파티클이 제대로 렌더링 된다


마무리

의외로 스무스하게 해결되서 다행이다

우리 쪽(?) 대응 문제라서 쉽게 해결할 수 있었던 것 같다


참고 자료

이번엔 딱히 없다