一种跨平台模块化的着色器语言通用集成方法

文档序号:29029988发布日期:2022-02-24 12:03阅读:211来源:国知局
一种跨平台模块化的着色器语言通用集成方法

1.本发明涉及图像渲染技术领域,尤其涉及一种跨平台模块化的着色器语言通用集成方法。


背景技术:

2.图像渲染是将三维的光能传递处理转换为一个二维图像的过程。场景和实体用三维形式表示,更接近于现实世界,便于操纵和变换,而图形的显示设备大多是二维的光栅化显示器和点阵化打印机。从三维实体场景的表示n维光栅和点阵化的表示就是图像渲染——即光栅化。光栅显示器可以看作是一个像素矩阵,在光栅显示器上显示的任何一个图形,实际上都是一些具有一种或多种颜色和灰度象素的集合。
3.着色器语言shader language目前主要有3种语言:基于opengl的opengl shading language,简称glsl;基于directx的high level shading language,简称hlsl;还有metal语言,具体如下:
4.opengl(全写open graphics library)是一个定义了跨编程语言、跨平台的编程接口规格的专业图形程序接口。它用于三维图像(二维亦可),是一个功能强大,调用方便的底层图形库。
5.directx(direct extension,简称dx)是由微软公司创建的多媒体编程接口。由c++编程语言实现,遵循com。被广泛适用于microsoft windows、microsoft xbox、microsoft xbox 360和microsoft xbox one电子游戏开发,并且只能支持这些平台。
6.metal提供对图形处理器(gpu)的接近直接访问,能最大程度地发挥ios、macos和apple tvos app中的图形和计算潜能。metal构建于易用的低开销架构之上,而且提供预编译的gpu着色器和精细的资源控制,并支持多线程处理。目前,在图像渲染api中,不同平台分别对应了不同的着色器语言(shader language),这些着色语言不兼容,如:windows平台使用directx,其他平台基本都是基于opengl,移动端平台出于性能考虑使用glsl的一个子集——gles,除此之外,metal及vulkan等api也应运而生。如此众多的图形api接口都提供了各自的着色器语言,在进行跨平台开发时,同一个功能需要针对多个平台编写多份着色器程序,使得编程效率低下。
7.为了解决跨平台的渲染问题,目前比较主流的的解决方案为编写glsl程序,再利用glslang编译器将glsl编译成一种“中间表示语言”spir-v,再利用spirv-cross反编译为各个平台的可使用的shader,如glsl/hlsl/msl等。此方案利用spir-v作为中间语言编写一份着色器程序,以实现跨平台。
8.现有技术存在以下缺陷:第一,将glsl编译成spir-v有使用限制,即在实际的使用过程中,着色器需要根据宏定义设置参数,那么着色器程序只能根据传入的宏定义在线编译生成spir-v,然后再反编译为各个平台对应的shader,这就需要有在线编译和反编译两个步骤,这使得整个渲染过程非常耗时,在渲染引擎中经常是无法直接使用的。第二,着色器不支持如c/c++这种高级语言的模块引入语法,这就导致在编写着色器时,底层共通的代
码段不得不分布在各个着色器中,导致程序规模扩大时,难以维护。无法做到模块通用性。


技术实现要素:

9.本发明提供一种跨平台模块化的着色器语言通用集成方法,以克服上述技术问题。
10.一种跨平台模块化的着色器语言通用集成方法,其特征在于,包括以下步骤,
11.步骤一,定义宏定义解析文件的格式与语法,创建宏定义解析文件;
12.步骤二,创建语法解析器shader-x,使用shader-x解析器预编译着色器文件,所述shader-x解析器包括着色器语法以及预编译指令;
13.步骤三,解析宏定义解析文件,生成宏定义结果集合,根据宏定义结果集合生成宏定义结果有序列表;
14.步骤四,分别计算宏定义结果有序列表的哈希值,分别根据宏定义结果生成宏定义结果所对应平台的着色器文件,通过shader-x解析器将着色器文件预编译为二进制文件,并通过宏定义结果有序列表的哈希值以及平台对二进制文件进行标记;
15.所述根据宏定义结果生成宏定义结果所对应平台的着色器文件是指首先通过glslang编译器将glsl程序编译成spir-v文件,然后通过spirv-cross生成平台所对应的着色器文件,
16.所述平台包括且不限于windows平台、ios平台、macos平台;
17.步骤五,渲染程序根据宏定义结果的哈希值以及平台,定位二进制文件并执行,所述定位二进制文件是根据宏定义结果有序列表的哈希值以及平台匹配相应的二进制文件。
18.优选地,所述通过shader-x解析器将着色器文件预编译为二进制文件还包括根据预编译指令进行模块引入和模块引入重复性检查,所述预编译指令包括模块引入的指令以及模块引入重复性检查的指令,所述模块引入是指通过模块引入的指令#include调用具有特定功能的模块,所述模块引入重复性检查是指通过模块引入重复性检查的指令#pragma once检查所引入模块是否重复引用。
19.本发明提供一种跨平台模块化的着色器语言通用集成方法,具有以下效果,
20.第一,建立宏定义预编译解析方案,并结合哈希值生成技术,实现同一套着色器代码可在不同平台使用,无需在线编译,即达到跨平台的目的,又提高了渲染性能,还使得渲染程序更加灵活。
21.第二,创建语法解析器shader-x以支持模块化的编程方案,提高着色器编程效率
22.第三,模拟c++的预编译方式,并应用在着色器的语法解析上,让着色器可以支持更高级的语法。
附图说明
23.为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作一简单地介绍,显而易见地,下面描述中的附图是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
24.图1是本发明方法流程图。
具体实施方式
25.为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
26.图1为本发明方法流程图,如图1所示,本实施例的方法可以包括:
27.一种跨平台模块化的着色器语言通用集成方法,实现实时跨平台模块化的着色器语言通用集成方案,以宏定义预编译的方式结合自定义模块化的语法解析器,形成性能更加优越、设计更加灵活的着色器语言通用集成方案,包括以下步骤,
28.步骤一,定义宏定义解析文件的格式与语法,创建宏定义解析文件;
29.创建宏定义解析文件,例如创建一个shaderlists.txt文件,文件中记录需要进行转换的shader文件路径、支持的宏macro以及宏定义的值macro value,具体格式如下所示:
[0030][0031]
其中“*”后是需要使用的编译文件,“》”所在行列出的是支持的macro,其后的每一个新行对应了不同的宏定义版本,可以定义多组以支持不同的平台。
[0032]
在进行解析时,只解析支持的宏,遇到声明的宏定义不在支持列表中,不进行解析。
[0033]
以max_num_lights 5,chromakey为例,通过“,”分割成两个宏定义,其预编译后对应的代码如下所示:
[0034]
#define max_num_lights 5
[0035]
#define chromakey
[0036]
步骤二,创建语法解析器shader-x,使用shader-x解析器预编译着色器文件,所述shader-x解析器包括着色器语法以及预编译指令;
[0037]
创建语法解析器shader-x,是在原有shader语法基础上,添加新的语法解析器shader-x,它在原有的shader语法基础上,仿照c++添加了自定义预编译指令“#include”和“#pragma once”,其中“#include”表示引用其它模块文件,“#prgama once”表示如果遇到重复的模块引用,只展开一次。
[0038]
步骤三,解析宏定义解析文件,生成宏定义结果集合,根据宏定义结果集合生成宏定义结果有序列表;
[0039]
本实施例根据宏定义,将每组宏定义结果生成宏定义结果有序列表,再通过遍历此列表利用metrohash生成64bit哈希值,保证每一组宏定义即使顺序不一致也都能对应唯一的哈希值,可以在文件名上可以进行区分,具有不同宏定义的glsl文件经过预编译和反编译,将生成带有哈希值的程序文件,
[0040]
例如:“max_num_lights 5,chromakey”的这组宏定义,通过哈希算法转化为哈希值为5d3887577ec22ee2,在通过spirv-cross生成不同平台版本的着色器文件时,分别针对
不同平台,在着色器文件命名时先加上各个平台的简称,如:gles\glsl\hlsl\msl等,同时每个平台对应一个顶点和边的着色器文件,最后就形成了如表(1)所示的文件名列表:
[0041]
表1着色器文件名列表
[0042][0043]
同时,本实施例也支持没有宏定义的方式,如下所示:
[0044]
gles.textured.vert/gles.textured.frag
[0045]
步骤四,分别计算宏定义结果有序列表的哈希值,分别根据宏定义结果生成宏定义结果所对应平台的着色器文件,通过shader-x解析器将着色器文件预编译为二进制文件,并通过宏定义结果有序列表的哈希值以及平台对二进制文件进行标记;
[0046]
所述根据宏定义结果生成宏定义结果所对应平台的着色器文件是指首先通过glslang编译器将glsl程序编译成spir-v文件,然后通过spirv-cross生成平台所对应的着色器文件,
[0047]
所述平台包括且不限于windows平台、ios平台、macos平台;
[0048]
将解析出的多组宏定义结果传入编译器,使其分别编译成不同版本的spir-v文件,如表(1)中的示例所示:共定义了3组宏定义版本,需要编译成3组spir-v对应文件,然后通过spirv-cross生成不同平台版本的着色器文件。这3组着色器文件必须可以区分开,否则实际使用时,不同的平台无法针对不同的宏定义进行选择。
[0049]
步骤五,渲染程序根据宏定义结果的哈希值以及平台,定位二进制文件并执行,所述定位二进制文件是根据宏定义结果有序列表的哈希值以及平台匹配相应的二进制文件。
[0050]
将文件编译成不同平台的二进制文件供渲染程序使用,渲染程序根据程序中的宏定义生成相应的哈希值,此哈希值与预编译时采用哈希算法生成的文件名中哈希值一致,结合对应平台,可以直接定位相应的文件并执行,并且无需在线编译,提高了性能。其中,为保证每一组宏定义对应的哈希值一致,需要预先将每一组宏定义按照一定顺序进行排序,再将其转换为哈希值。
[0051]
进一步地,可将上述执行过程编写成脚本,即可进行批量处理,提高预编译效率,如下所示。
[0052][0053]
通过shader-x解析器将着色器文件预编译为二进制文件还包括根据预编译指令进行模块引入和模块引入重复性检查,所述预编译指令包括模块引入的指令以及模块引入重复性检查的指令,所述模块引入是指通过模块引入的指令#include调用具有特定功能的模块,所述模块引入重复性检查是指通过模块引入重复性检查的指令#pragma once检查所引入模块是否重复引用。
[0054]
利用shaderx语法解析器对shader文件进行预编译,遇到#include和#pragma once这两条指令,则将模块内容在当前文件展开,如果遇到#pragma once,则检查模块重复引用,防止编译错误。此模块化的方案使得shader支持了高级语言才有的模块引入和重复性检查功能,提高了shader的模块化,以例子进一步说明,编写了一个模块化文件blending_func.frag,如下所示:
[0055][0056][0057]
这个模块文件需要在多个shader中使用,传统的方式必须在需要此代码在每个文件中都进行添加,不利于模块化和代码维护。使用本方案自定义的shaderx预编译器先进行解析,那么引用模块的文件可写成如下形式:
[0058]
#include"blending_func.frag"
[0059]
void main()
[0060]
{
[0061]

[0062]
}
[0063]
在开发渲染框架时,通常会内置一些通用模块,可让开发者更容易的进行开发,对于这种内置模块,本方案定义了一套新的协议,根据模块功能的不同定义不同的协议,比如对于引擎部分,定义engine://module1.frag,对于sdk部分,定义sdk://module1.frag。在解析#include模块时,首先检查协议格式,如果满足"(.*://)"这样的正则表达式,就引用内置模块,根据协议去查找对应的模块,否则就引用的自定义模块。
[0064]
整体有的有益效果:本发明提供一种跨平台模块化的着色器语言通用集成方法,具有以下效果,
[0065]
第一,建立宏定义预编译解析方案,并结合哈希值生成技术,实现同一套着色器代码可在不同平台使用,无需在线编译,即达到跨平台的目的,又提高了渲染性能,还使得渲染程序更加灵活。
[0066]
第二,创建语法解析器shader-x以支持模块化的编程方案,提高着色器编程效率
[0067]
第三,模拟c++的预编译方式,并应用在着色器的语法解析上,让着色器可以支持更高级的语法。
[0068]
最后应说明的是:以上各实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述各实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分或者全部技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的范围。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1