Nova Shader의 ParticlesUberLit이 VR모드에서 정상적으로 렌더링 되지 않던 이슈
발생한 이슈
VR모드에서 Nova Shader의 ParticlesUberLit가 제대로 렌더링하지 않는 이슈가 발생했다
참고로 VR모드란 유니티 에디터의 재생 모드를 Oculus Link에서도 실행시키는 것을 말한다 빌드를 하지 않고 바로 VR기기에서 바로 확인할 수 있고, 유니티 에디터도 조작할 수 있어서 편리하다
이슈 상세
ParticlesUberLit의 파티클의 렌더링이 조건에 따라 달라졌다
- 실행 파일(APK, EXE): 파티클이 VR기기의 왼쪽 스크린에만 렌더링(확인 필요)
- 유니티 에디터(기본) : 파티클이 문제 없이 렌더링
- VR모드의 VR기기 : VR기기에서는 파티클이 아예 렌더링 안 됨
- VR모드의 유니티 에디터 : 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 대응 코드를 지우면 끝!
마무리
의외로 스무스하게 해결되서 다행이다
우리 쪽(?) 대응 문제라서 쉽게 해결할 수 있었던 것 같다
참고 자료
이번엔 딱히 없다