图形API学习工程(29):解决在shader文件中使用include的问题

news2025/1/10 20:52:15

工程GIT地址:https://gitee.com/yaksue/yaksue-graphics

无用的前言

看了下提交记录,这个工程上次更新已经是一年以前了。最近想想,还是应该回来再继续学学,暂且不论是否对工作有帮助,我在这个工程上获得的愉悦感相比学其他东西是更大的。

所以今天又把工程拉了下来。由于最近重装了系统,所以要重新配置下环境。但说是配置,其实也很简单。可能是因为装了最新的系统,所以D3D11和D3D12不需要额外的操作就能跑了。而OpenGL本来也就是借助Glad,也不需要配置。唯一要做的就是安装一个VulkanSDK就行了(安装时会添加环境变量,而工程里会通过环境变量找到VulkanSDK的库)。

刚回坑,就先搞个相对简单的问题好了(搞完后发现也挺多坑的。。):

目标

由于我以后可能需要定义些通用的shader函数,自然想要将他们放入单独的shader文件并由其他shader文件include它们。
这在hlsl中会很容易,但是glsl默认状态下并不支持。本篇目标是学习如何解决这个问题,最终让工程里D3D11、D3D12、OpenGL、Vulkan都可以在shader中使用 include

1. D3D11

由于hlsl直接就支持,所以直接就能使用。

我将当前一些通用的函数放入同目录的"Utils.hlsl"文件中后,使用时直接include就行:

#include "Utils.hlsl"

2. D3D12

本以为D3D12也是直接支持,但是遇到了一个小错误。
编译shader时显示的错误如下:
在这里插入图片描述

我在这里找到了解决方法:
DX11开发报错error X1505: No include handler specified, can’t perform a #include._MaloFleur的博客-CSDN博客

即编译shader时指定D3D_COMPILE_STANDARD_FILE_INCLUDE
在这里插入图片描述
随后就能正常使用了。

3. OpenGL

相对来说,glsl默认是不支持的。
这里有对于这个问题做讨论:
在这里插入图片描述
因此问题变得复杂了些,如果你要使用include的话,你需要这么做:


首先,你需要GL_ARB_shading_language_include这个扩展。这在当时使用glad得到的文件中没有包含,所以我需要拐回头再使用一次glad,将生成的文件替换到工程里:(这里也有相关的讨论:LearnGL - 12 - GLSL include - GL_ARB_shading_language_include (Extensions扩展) - 各种踩坑_Jave.Lin的博客-CSDN博客)
在这里插入图片描述
然后,在C++中时,你需要事先把想要include的文件加入,我这里在初始化阶段加入了下面的代码:
(我在这里找到了些参考)

//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文件中,就可以include了:(还要启用GL_ARB_shading_language_include

#extension GL_ARB_shading_language_include : require

#include "/Utils.glsl"

而这么做的缺点,也在这里有讨论:
在这里插入图片描述

4. Vulkan

本以为Vulkan也需要费事,但实际是,并不需要做任何操作。参考这里的讨论,使用 glslc 编译时已经具备了include功能了!

5. 让Vulkan和OpenGL可使用相同的glsl文件

虽然Vulkan省事了,但由于它现在和OpenGL使用的是同一个glsl文件,所以会遇到问题,它提示不支持 GL_ARB_shading_language_include:(也可以理解,毕竟它也不需要)
error: ‘#extension’ : extension not supported: GL_ARB_shading_language_include
在这里插入图片描述
所以我最后决定,让OpenGL编译shader时在C++中通过字符串编辑加入这个GL_ARB_shading_language_include,这样就不影响Vulkan了。

不过这里还遇到个问题就是,#version必须在第一行且无法声明两次:
error C0204: version directive must be first statement and may not be repeated
在这里插入图片描述

所以,我不能直接加这个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虽然直接使用遇到了问题,但也可以通过在编译shader时指定D3D_COMPILE_STANDARD_FILE_INCLUDE来解决。

Vulkan 由于使用了 glslc 编译shader,也是支持include的。

OpenGL最费事,要使用GL_ARB_shading_language_include功能。需要提前读取被include的shader文件。另外,我这里为了让Vulkan和OpenGL可使用相同的glsl文件,我选择让OpenGL编译shader在C++中加入GL_ARB_shading_language_include

至此,四个图形API都可以使用include了。

其他:显示D3D编译shader文件时遇到的错误信息

之前编译shader时并不会显示错误信息,今天为了定位遇到的D3D12的问题也改了下代码,即编译时传入一个ID3DBlob用于容纳错误的信息,如果出现错误则显示它:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/71034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Excel 是您最容易被忽视的设计工具 设计师对世界排名第一的电子表格工具的看法——如何构建信息图表、仪表板、演示文稿等

人们对 Excel 有很多误解。许多人认为它不过是处理临时预算的电子表格工具。或者它非常适合处理数据,但您需要像 PowerPoint 这样的单独工具才能很好地显示它。 这些误解限制了我们使用 Excel 的方式。 但 Excel 的功能远不止于此,它所需要的只是了解一些鲜为人知的功能。我…

JAVA SCRIPT设计模式--创建型设计模式之工厂方法(3)

JAVA SCRIPT设计模式是本人根据GOF的设计模式写的博客记录。使用JAVA SCRIPT语言来实现主体功能,所以不可能像C,JAVA等面向对象语言一样严谨,大部分程序都附上了JAVA SCRIPT代码,代码只是实现了设计模式的主体功能,不代…

机器学习笔记之配分函数(三)对比散度

机器学习笔记之配分函数——对比散度引言回顾:随机最大似然求解模型参数的过程随机最大似然的缺陷吉布斯采样的缺陷与对比散度思想对比散度名称的由来从KL\mathcal K\mathcal LKL散度的角度描述极大似然估计对比散度的本质引言 上一节介绍了随机最大似然(Stochasti…

第十四届蓝桥杯集训——JavaC组第四篇——ASCII码表与Scanner扫描器

第十四届蓝桥杯集训——JavaC组第四篇——ASCII码表与Scanner扫描器 目录 第十四届蓝桥杯集训——JavaC组第四篇——ASCII码表与Scanner扫描器 ASCII码表 Scanner扫描器 1、Scanner含义 2、使用方法: next和nextLine的区别 next: nextLine&#…

微服务框架 SpringCloud微服务架构 23 搜索结果处理 23.2 分页

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式,系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构23 搜索结果处理23.2 分页23.2.1 分页23.2.2 深度分页问题23.2.3 深度分页…

Zookeeper常用命令大全之四字监控命令

文章目录四字监控命令0. 官方文档1. conf命令2. cons命令3. crst命令4. dump命令5. envi命令6. ruok命令7. stat命令8. srst命令9. wchs命令10. wchc命令(一般不用)11. wchp命令(一般不用)12. mntr命令四字监控命令 zookeeper支持某些特定的四字命令与其的交互。它们大多是查询…

自媒体短视频,如何起一个让人一看就记住的昵称?看一眼就知道你的定位

上一篇我们说了头像如何设置更吸引人,今天上午在我赢且力手小禾呈序里聊了一个好听好记的昵称应该是怎样的? 这是文字版,大家可以看一看。 昵称起名的方式无非几种: 职业加昵称,昵称加地点,昵称加领域&a…

全球数据集大全之mavenanalytics学习分析世界杯数据集

mavenanalytics数据集平台介绍 探索和下载由 Maven 讲师精心挑选的示例数据集。练习将您的数据分析和可视化技能应用于现实世界的数据,从航班延误和电影收视率到鲨鱼袭击和不明飞行物目击事件。 平台效果 是否支持下载 可以免费下载 https://www.mavenanalytics.io/data-p…

Java基于jsp大学生收支管理系统

随着计算机技术的飞速发展,计算机在系统管理中的应用越来越普及,利用计算机实现各个系统的管理显得越来越重要。随着人们消费水平的提高,消费量一直在加大 ,可是如何能够合理的管理和记录自己的消费方向是一个很大的问题&#xff…

深度学习炼丹-不平衡样本的处理

前言一,数据层面处理方法 1.1,数据扩充1.2,数据(重)采样 数据采样方法总结 1.3,类别平衡采样 二,算法(损失函数)层面处理方法 2.1,Focal Loss2.2,…

Akka 学习(三)Actor的基本使用

目录一 基本案例1.1 Java 版1.2 Scala版二 Actor的创建2.1 ActorRef2.2 Props2.3 ActorSelection三 Promise、Future和事件驱动的编程模型3.1 阻塞与事件驱动3.2 Future进行Actor响应3.2.1 Java版3.2.2 Scala 版3.2.3 总结3.3 成功处理3.4 失败处理3.5 恢复3.6 链式调用3.7 结果…

小程序开发工具怎么使用?

小程序开发工具怎么用? 小程序开发工具分两种: 一种是微信官方提供的微信开发者工具 这个需要从事代码行业,职业是程序员又或者对代码知识有一定程度的人,才能上手使用。 另一种是第三方小程序开发平台,提供的小程序开发工具 …

python环境、基础语法、几种常见的数据类型

文章目录前言一、基本知识介绍二、举例实操以及重要知识再现(列表、元组、集合、字典)前言 一、基本知识介绍 python基础 标准库与扩展库中的对象的导入与使用: import 模块名(as别名) import numpy as np from 模块名 import 对象名&#x…

程序人生:快来一起学习软件测试,一起月薪过万(测试理论基础学习)

测试基础 为什么要有测试呢?现在软件已经和人的生活息息相关了,所以保证软件的稳定很重要。但是所有开发出来的软件都是有缺陷的。包括代码错误,逻辑错误,设计不合理等。 测试的目的 测试的目的主要有四个点 1找到软件缺陷 2…

Flink SQL增量查询Hudi表

前言 前面总结了Spark SQL增量查询Hudi表和Hive增量查询Hudi表。最近项目上也有Flink SQL增量查询Hudi表的需求,正好学习总结一下。 官网文档 地址:https://hudi.apache.org/cn/docs/querying_data#incremental-query 参数 read.start-commit 增量查…

WWW2022 | 基于领域增强的图对比协同过滤方法+代码实践

嘿,记得给“机器学习与推荐算法”添加星标今天跟大家分享一篇将对比学习应用于图协同过滤方法的文章,该论文发表于WWW2022会议上。其主要思想是在图神经网络协同过滤方法上应用了两种领域类型的对比学习方法,分别是显式的结构领域和隐式的语义…

TGK-Planner-前后端路径规划(基于梯度的后端无约束优化)

高速移动无人机的在线路径规划一直是学界当前研究的难点,引起了大量机器人行业的研究人员与工程师的关注。然而无人机的计算资源有限,要在短时间内规划出一条安全可执行的路径,这就要求无人机的运动规划算法必须轻型而有效。本文将介绍一种无…

electron-vue中报错 Cannot use import statement outside a module解决方案(亲测有效!!!)

错误: Cannot use import statement outside a module(不能在模块之外使用导入语句)。 原因: 安装的某个依赖包里使用了import语法,因为我们打包输出的是commonjs规范,所以不识别import语法而导致报错。 可以从 .electron-vue/w…

PrimoBurnerSDK蓝光刻录工具开发工具包

PrimoBurnerSDK蓝光刻录工具开发工具包 PrimoBurnerSDK是一个CD、DVD和蓝光刻录工具开发工具包。它还提供了一个全面灵活的API,用于快速轻松地实现各种燃烧/翻录替代方案。 PrimoBurner SDK for.NET的强大功能: 自2003年以来一直在发展的广泛使用的老式发…

比机器人还智能的数字孪生地下停车场监管系统!

现在的停车场管理大多采用人工或智能收费系统,两种方式都有一个弊端就是无法直接知晓停车场内部信息。 车驶入停车场只能自行寻找停车位,工作人员也只有走进停车场才能知晓停车场内部情况,无可避免造成很多麻烦。 停车场智慧监管系统结合数…