Graphics API 학습 프로젝트(29): 셰이더 파일에 포함 사용 문제 해결

엔지니어링 GIT 주소: https://gitee.com/yaksue/yaksue-graphics

쓸데없는 서문

제출 기록을 보면 이 프로젝트의 마지막 업데이트가 1년 전입니다. 최근에 생각해보면 돌아와서 계속 공부해야지 일에 도움이 되든 안되든 이 프로젝트에서 얻는 즐거움은 다른 것을 배우는 것보다 더 큽니다.

그래서 오늘 프로젝트가 다시 중단되었습니다. 최근 시스템 재설치로 인해 환경을 재구성해야 합니다 . 그러나 구성은 실제로 매우 간단합니다. 최신 시스템이 설치되어 있어서 추가 작업 없이 D3D11과 D3D12를 실행할 수 있기 때문일 수 있습니다. OpenGL은 원래 Glad를 기반으로 하며 구성이 필요하지 않습니다. VulkanSDK를 설치하기만 하면 됩니다(설치 중에 환경 변수가 추가되며 VulkanSDK 라이브러리는 환경 변수를 통해 프로젝트에서 찾을 수 있습니다).

구덩이로 돌아오자마자 비교적 간단한 질문부터 시작하겠습니다(끝낸 후 꽤 많은 함정이 있음을 발견했습니다...)

표적

나중에 몇 가지 일반적인 셰이더 함수를 정의해야 할 수도 있으므로 자연스럽게 별도의 셰이더 파일에 넣고 다른 셰이더 파일에 포함하고 싶습니다.
이것은 hlsl에서 쉬울 것이지만 glsl은 기본적으로 지원하지 않습니다. 이 기사의 목표는 이 문제를 해결하는 방법을 배우고 최종적으로 프로젝트의 D3D11, D3D12, OpenGL 및 Vulkan이 셰이더에서 include를 사용하도록 허용하는 것입니다 .

1. D3D11

hlsl에서 직접 지원하므로 바로 사용할 수 있습니다.

현재 공통 기능을 같은 디렉토리의 파일에 넣은 후 "Utils.hlsl"사용할 때 직접 포함합니다.

#include "Utils.hlsl"

2. D3D12

D3D12도 직접 지원하는 줄 알았는데 작은 오류가 발생했습니다.
셰이더를 컴파일할 때 표시되는 오류는 다음과 같습니다.
여기에 이미지 설명 삽입

여기에서 해결책을 찾았습니다.
DX11 개발 오류 오류 X1505: 지정된 포함 핸들러 없음, #include를 수행할 수 없습니다._MaloFleur's Blog-CSDN Blog

즉, shader를 컴파일할 때 지정하면 D3D_COMPILE_STANDARD_FILE_INCLUDE정상적으로
여기에 이미지 설명 삽입
사용할 수 있습니다.

3. OpenGL

상대적으로 glsl은 기본적으로 지원되지 않습니다.
여기에서 이 문제에 대한 토론이 있습니다 .
여기에 이미지 설명 삽입
따라서 문제가 조금 더 복잡해집니다. 포함을 사용하려면 다음을 수행해야 합니다.


먼저 GL_ARB_shading_language_include이 확장이 필요합니다. 이것은 당시에 glad를 사용하여 얻은 파일에 포함되어 있지 않았으므로 다시 glad를 사용하여 생성된 파일을 프로젝트에 대체해야 합니다. (extensions extension ) - Various pits_Jave.Lin's blog-CSDN blog )
여기에 이미지 설명 삽입
그런 다음 C++에서 포함하려는 파일을 미리 추가해야 합니다.초기화 단계에서 다음 코드를 추가
했습니다 .

//include时的文件名:
const char* glslName = "/Utils.glsl";
//文件的内容:
const GLchar* glslContent = ReadShader("shaders/glsl/Utils.glsl");
//将文件名和文件内容对应起来:
glNamedStringARB(GL_SHADER_INCLUDE_ARB, strlen(glslName), glslName, strlen(glslContent), glslContent);

이 코드를 통해 Utils.glsl파일의 내용이 "/Utils.glsl"이 이름에 해당하고 glsl 파일에 다음을 포함할 수 있습니다 GL_ARB_shading_language_include .

#extension GL_ARB_shading_language_include : require

#include "/Utils.glsl"

그렇게 할 때의 단점 도 여기에서 설명합니다 .
여기에 이미지 설명 삽입

4. 불칸

Vulkan도 수고가 필요할 거라 생각했는데 사실 조작은 필요 없습니다. here 토론을 참조하면 glslc로 컴파일할 때 포함 기능이 이미 사용 가능합니다!

5. Vulkan과 OpenGL이 동일한 glsl 파일을 사용하도록 합니다.

Vulkan은 문제를 해결하지만 OpenGL과 동일한 glsl 파일을 사용하기 때문에 문제가 발생합니다.GL_ARB_shading_language_include가 지원되지 않는다는 메시지가 표시됩니다. :
지원되지 않는 확장자: GL_ARB_shading_language_include 그래서 결국 OpenGL이 셰이더를 컴파일할 때 C++에서 문자열 편집을 통해 이것을 추가하기
여기에 이미지 설명 삽입
로 하여 Vulkan에 영향을 미치지 않도록 했습니다.GL_ARB_shading_language_include

그러나 여기에는 여전히 문제가 있습니다. #version첫 번째 줄에 있어야 하며 두 번 선언할 수 없습니다:
오류 C0204: 버전 지시문은 첫 번째 문이어야 하며 반복될 수 없습니다.
여기에 이미지 설명 삽입

그래서 this를 직접 추가하는 대신에 GL_ARB_shading_language_include찾아서 #version추가합니다. 특정 코드는 다음과 같이 구현됩니다.

// 这里在C++中加上OpenGL自己需要的拓展(由于Vulkan不需要且不支持,所以不能直接在glsl文件中写上)
// 另外要注意,#version必须永远是第一行,所以要找到他并且在其后面添加内容
std::string str_source = source;            //原始shader文件
std::string str_version = "#version 450";   
str_source.replace(str_source.find(str_version), str_version.length(), "#version 450\n#extension GL_ARB_shading_language_include : require\n");

요약하다

hlsl이 직접 지원됩니다. D3D12를 직접 사용할 때 문제가 발생했지만 셰이더를 컴파일할 때 지정하여 해결할 수도 있습니다 D3D_COMPILE_STANDARD_FILE_INCLUDE.

Vulkan은 glslc를 사용하여 셰이더를 컴파일하기 때문에 include도 지원합니다.

OpenGL은 함수를 사용하여 가장 노동 집약적입니다 GL_ARB_shading_language_include. 포함된 셰이더 파일을 미리 읽어야 합니다. 또한 Vulkan과 OpenGL이 동일한 glsl 파일을 사용할 수 있도록 OpenGL이 셰이더를 C++로 컴파일하도록 선택했습니다 GL_ARB_shading_language_include.

지금까지 4개의 그래픽 API는 include를 사용할 수 있습니다.

기타: D3D가 셰이더 파일을 컴파일할 때 발생하는 오류 메시지 표시

이전에 셰이더를 컴파일할 때 오류 메시지가 표시되지 않았으나 오늘은 발생한 D3D12 문제를 찾기 위해 코드도 변경되었습니다. 즉, 컴파일 중에 오류를 수용하라는 메시지가 전달되어 표시됩니다 ID3DBlob. 오류가 발생하는 경우:
여기에 이미지 설명 삽입

Supongo que te gusta

Origin blog.csdn.net/u013412391/article/details/128224160
Recomendado
Clasificación