@@ -615,7 +615,7 @@ uniform1i
615615## 概述解决方案
616616
617617- 将支持各种功能的默认GLSL分解为多个小块
618- - 用户实现GLSL的JSON配置文件,指定如何组合小块的GLSL ,以及指定在渲染时需要发送的顶点数据和Uniform数据的配置数据
618+ - 用户实现GLSL的JSON配置文件,指定如何拼接小块的GLSL ,以及指定在渲染时需要发送的顶点数据和Uniform数据的配置数据
619619
620620
621621## 给出UML?
@@ -631,37 +631,45 @@ Client是用户
631631
632632我们看下数据和ChunkConverter这两个部分:
633633
634- GLSL Config是的GLSL的JSON配置文件,它的内容由用户给出,它的格式(也就是类型)由ChunkHandler定义
634+ Target GLSL是支持某些功能的一套GLSL,相当于之前的BasicMaterialShaderGLSL(Add Define)或者PBRMaterialShaderGLSL(Add Define),两者的区别是Target GLSL没有预定义的宏,它只有支持的功能的GLSL,没有分支
635+ 一套Target GLSL包括了一个VS GLSL和一个FS GLSL
636+ 这里最多可有8套Target GLSL,分别对应基础材质的4种情况和PBR材质的4种情况
637+
638+
639+ Send Config是如何获得和发送顶点数据和Uniform数据的配置数据
640+ 具体来说,每个Send Config包括了多个getData函数和多个sendData函数,前者获得对应的顶点数据或者Uniform数据,后者发送它们
641+ 因为一个Send Config对应一套Target GLSL,所以最多有8个Send Config
642+
643+
644+
645+
646+
647+ GLSL Config是的GLSL的JSON配置文件,用来指定如何拼接Target GLSL,并包括了Send Config
648+ 它的内容由用户给出,它的格式(也就是类型)由ChunkHandler定义
649+
635650
636651GLSL Chunk是一小块的GLSL,有多个GLSL Chunk,它们由引擎给出
637652一个GLSL Chunk可以是VS GLSL中一小块GLSL文件(如common_vertex.glsl),也可以是FS GLSL中一小块GLSL文件(common_fragment.glsl)
638653
639654
655+ ChunkConverter负责转换GLSL Chunk
640656因为GLSL Chunk是自定义文件,有一些自定义的语法,不能直接使用,所以引擎需要调用gulp任务来对其预处理。
641657在gulp任务中,调用了ChunkConverter来处理所有的GLSL Chunk,并将其合并为一个Merged GLSL Chunk,成为一个Typescript或者Rescript文件
642658<!-- 这样做的原因是GLSL Chunk是自定义的文件,不能直接被Typescript或者Rescript调用,所以需要将其转换为可被调用文件;另外,需要将其集中在一个文件中,方便管理 -->
643659
644660
645- Send Config是一个Shader的获得和发送顶点数据和Uniform数据的配置数据
646- 具体来说,每个Send Config包括了多个getData函数和多个sendData函数,前者获得对应的顶点数据或者Uniform数据,后者发送它们
647- 因为这里最多有8个Shader,所以最多有8个Send Config
648-
649661
650- Target GLSL是支持某些功能的一套GLSL,相当于之前的BasicMaterialShaderGLSL(Add Define)或者PBRMaterialShaderGLSL(Add Define),两者的区别是Target GLSL没有预定义的宏,它只有支持的功能的GLSL,没有分支
651- 一套Target GLSL包括了一个VS GLSL和一个FS GLSL
652- 这里最多可有8套Target GLSL,分别对应基础材质的4种情况和PBR材质的4种情况
653662
663+ 我们看下ChunkHandler和引擎这两个部分:
654664
665+ ChunkHandler负责拼接Target GLSL和获得Send Config
655666
656- 我们看下引擎和ChunkHandler这两个部分:
657667
658668Engine、Render跟之前一样
659669<!-- Engine是引擎的门户,负责封装API给Client -->
660670<!-- Engine有一个EngineState,用来保存引擎的所有数据; -->
661671
662672InitMaterialShader负责初始化所有材质的Shader,它有两个函数:initBasicMaterialShader、initPBRMaterialShader,分别负责初始化所有基础材质的Shader和初始化所有PBR材质的Shader
663-
664-
665673这两个函数遍历了所有的基础材质或者PBR材质,在每次遍历中的步骤一样,具体步骤如下:
666674通过调用ChunkHandler的buildGLSL函数,按照GLSL Config的配置数据将Merged GLSL Chunk中对应的GLSL Chunk拼接为一个Target GLSL,然后使用它创建材质使用的shaderIndex和program;
667675通过调用ChunkHandler的getSendConfig函数,从GLSL Config中获得Send Config
@@ -711,7 +719,7 @@ shader_chunks.json是一个数组,其中的每个元素定义了一套GLSL Chu
711719
712720
713721这两个文件的关系是“总-分”的关系,具体如下:
714- 因为每种Shader的GLSL由多个GLSL Chunk组合而成 ,所以shaders.json是“总”,shader_chunks.json是“分”
722+ 因为每种Shader的GLSL由多个GLSL Chunk组合拼接而成 ,所以shaders.json是“总”,shader_chunks.json是“分”
715723
716724
717725下面我们来看下这两个文件的主要代码:
@@ -821,7 +829,7 @@ shaders字段定义了所有种类的Shader的GLSL配置数据
821829值得说明的是:
822830实际上也存在没有材质的Shader,如后处理(如绘制轮廓)的Shader、天空盒的Shader等,这些种类的Shader也定义在shaders字段,只是没有对应材质而已。这种Shader我们会在后面的扩展中讨论
823831
824- 每种Shader的GLSL由多个GLSL Chunk组合而成 ,它们定义在shader_chunks字段中
832+ 每种Shader的GLSL由多个GLSL Chunk组合拼接而成 ,它们定义在shader_chunks字段中
825833<!-- groups字段定义了多组GLSL Chunk,每组的value字段包括了多个GLSL Chunk,它们跟shader_chunks.json的name关联 -->
826834<!-- 此处定义了一个名为render_basic的Shader,它包括的所有的代码块定义在shader_chunks字段中。 -->
827835在shader_chunks字段中,如果type为static_branch,那么就通过name关联到static_branchs字段;
@@ -990,7 +998,7 @@ export let createState = ([shaders, shaderChunks]): state => {
990998
991999
9921000引擎定义的GLSL Chunk具体是后缀名为.glsl的文件
993- 我们通过自定义的字符:@top 、@define 、@varDeclare 、@funcDeclare 、@funcDefine 、@body 以及对应的@end ,将一个完整的GLSL分割为从上往下的不同区域的的代码片段,这样便于更细粒度的组合
1001+ 我们通过自定义的字符:@top 、@define 、@varDeclare 、@funcDeclare 、@funcDefine 、@body 以及对应的@end ,将一个完整的GLSL分割为从上往下的不同区域的代码片段,这样便于更细粒度的组合拼接
9941002
9951003一个GLSL Chunk可以包括多个区域的代码片段
9961004
@@ -1236,7 +1244,7 @@ _initOneMaterialTypeShader函数在遍历所有的基础材质时,首先调用
12361244<!-- 值得说明的是: -->
12371245ChunkHandler的buildGLSL函数和getSendConfig函数都接受了引擎实现的函数,它们被用于处理shaders.json和shader_chunks.json中的一些字段,从而实现分支处理或者从中获得Send Config
12381246
1239- 因为这些字段的值是离散的,它们的的范围是引擎定义的 ,用户只能从范围内选择某个具体的值,所以这些字段的类型是定义在引擎端,类型中明确了有哪些值的范围 。
1247+ 因为这些字段的值是离散的,它们的范围是引擎定义的 ,用户只能从范围内选择某个具体的值,所以这些字段的类型是定义在引擎端,在类型中明确了有哪些值的范围 。
12401248<!-- 具体是定义在引擎的GLSLConfigType.ts中,代码如下: -->
12411249类型定义的部分代码如下:
12421250GLSLConfigType
@@ -1402,84 +1410,129 @@ let _sendUniformData = (uniformSendConfig: Array<uniformSendConfig>, state: stat
14021410## 一句话定义?
14031411
14041412
1405- TODO continue
1406-
14071413<!-- 可配置地拼接小块数据 -->
14081414
1409- 分解包括各种分支的大数据为小块单位 ,按照配置文件来拼接
1415+ 分解有各种分支的大数据为多个小块数据 ,按照配置文件来拼接
14101416
14111417
14121418## 补充说明
14131419
1414- 把每个分支对应的数据都对应分解为一块数据;
1420+ 大数据中的每个分支都可以分解为一块数据,如有下面的一个大数据:
1421+ ``` ts
1422+ #ifdef INSTANCE
1423+ 数据1
1424+ #endif
1425+
1426+ #ifdef NO_INSTANCE
1427+ 数据2
1428+ #endif
1429+ ```
1430+ 它有两个分支,可以将其分解为数据1、数据2这两个小块数据
14151431
1416- 由用户给出配置文件来指定:有哪些分支、要构造哪些Target数据、每个Target数据包括哪些块、每块有哪些配置数据
1432+
1433+ 配置文件由用户给出,包括下面的内容:
1434+ 有哪些分支、要构造哪些Target数据、每个Target数据包括哪些块、每块有哪些配置数据
14171435
14181436
14191437
14201438
14211439## 通用UML?
1422- ![ image ] ( https://img2023.cnblogs.com/blog/419321/202304/419321-20230403163737312-1241675852.png )
1440+ TODO tu
14231441
14241442
14251443
14261444## 分析角色?
14271445
14281446我们来看看模式的相关角色:
14291447
1430- TODO rename Main to System
1448+ 总体来看,分为数据、ChunkConverter、ChunkHandler、系统这四个部分
1449+
1450+
1451+ 我们看下数据和ChunkConverter这两个部分:
1452+
1453+
1454+ - Target
1455+ 该角色是拼接后的符合某种特定分支条件的数据,如[ 支持方向光,支持贴图,支持Instance] 的GLSL就是一个Target
1456+
1457+ - Runtime Config
1458+ 该角色是如何操作运行时数据的配置数据
1459+ 具体来说,每个Runtime Config包括了多个getData函数和多个sendData函数,前者获得对应的运行时数据,后者发送它们
1460+ <!-- 因为一个Send Config对应一个Shader,而这里最多有8个Shader,所以最多有8个Send Config -->
1461+
1462+ <!-- ,它在初始化时从Target Config中获得,在运行时被使用 -->
1463+
14311464
14321465
1433- TODO rename Runtime Data to Runtime Config
14341466
14351467- Target Config
1436- 该角色是配置数据,用来指定如何拼接数据
1468+ 该角色是配置数据,用来指定如何拼接Target,并包括了Runtime Config
1469+ 它的内容由用户给出,它的格式(也就是类型)由ChunkHandler定义
1470+ Target Config中某些字段的值是离散的,它们的范围是系统定义的,用户只能从范围内选择某个具体的值
14371471
14381472- Target Chunk
1439- 该角色是小块的数据,它是通过对原始的大数据抽象分解后得到的,一般来说大数据中的一个分支对应一个Target Chunk数据
1473+ 该角色是小块的数据,由系统给出
1474+ <!-- 它是通过对原始的大数据抽象分解后得到的,一般来说大数据中的一个分支对应一个Target Chunk数据 -->
14401475
1441- - Merged Target Chunk
1442- 该角色是合并了所有的Target Chunk后的数据,它将所有的Target Chunk文件合并为一个Hash Map
14431476
1444- - Target
1445- 该角色是拼接后的符合某种特定分支条件的数据,如[ 支持方向光,支持贴图,支持Instance] 的GLSL
14461477
1447- - Runtime Data
1448- 该角色是运行时数据,它在初始化时从Target Config中获得,在运行时被使用
14491478
14501479- ChunkConverter
1451- 该角色负责在预处理时合并所有的Target Chunk为一个Merged Target Chunk文件
1480+ 该角色负责在系统预处理处理Target Chunk,并将其合并为一个Merged Target Chunk
1481+
1482+
1483+ - Merged Target Chunk
1484+ 该角色是合并了所有的Target Chunk后的数据,它是一个Typescript或者Rescript文件
1485+
1486+
1487+
1488+ 我们看下ChunkHandler和系统这两个部分:
14521489
14531490- ChunkHandler
1454- 该角色定义了Target Config的格式(也就是类型),并且实现了拼接Target和获得Runtime Data的相关函数
1491+ 该角色负责拼接Target和获得Runtime Config
14551492
1456- - Main
1493+ - System
14571494该角色为系统的门户,提供API给Client
14581495
14591496- Init
1460- 该角色实现系统的初始化,调用ChunkHandler->buildTarget来拼接了Target并且直接使用它,调用ChunkHandler->getRuntimeData来获得了Runtime Data
1497+ 该角色实现系统的初始化,它包括下面的步骤:
1498+ 调用ChunkHandler的buildTarget函数,按照Target Config的配置数据将Merged Target Chunk中对应的Target Chunk拼接为一个Target,然后使用它;
1499+ 调用ChunkHandler的getRuntimeConfig函数,从Target Config中获得Runtime Config
14611500
14621501- OperateWhenRuntime
1463- 该角色进行某个在运行时的操作,使用了Runtime Data
1502+ 该角色在运行时进行某个操作(如渲染),使用了Runtime Config
1503+
1504+
1505+
1506+ <!-- ## 与之前构造GLSL案例的UML的区别
1507+
1508+ TODO -->
14641509
14651510
14661511## 角色之间的关系?
14671512
1468- - 应该有多个Target Chunk,它们由系统给出
1513+ - 有多个Target Chunk
14691514
1470- - Target Config的格式由ChunkHandler定义。其中由系统处理的字段的类型由系统再次定义,目的是定义这些字段的所有可能的值
1515+ <!-- - Target Config的格式由ChunkHandler定义。其中由系统处理的字段的类型由系统再次定义,目的是定义这些字段的所有可能的值 -->
14711516
1472- - Target Config的内容由Client给出
1517+ <!-- - Target Config的内容由Client给出 -->
14731518
14741519- Target Config通常包含两个配置文件:targets_config、chunks_config
1520+ 这两个文件的关系是“总-分”的关系,其中targets_config是“总”,chunks_config是“分”
14751521
1476- - 应该有多个Target ,如[ 支持方向光,支持贴图,支持Instance] 的GLSL和 [ 支持方向光,不支持贴图,支持Instance] 的GLSL
1522+ - 有多个Target ,如[ 支持方向光,支持贴图,支持Instance] 的GLSL是一个Target, [ 支持方向光,不支持贴图,支持Instance] 的GLSL是另外一个Target
14771523
1524+ - 有多个Runtime Config,一个Runtime Config对应一个Target
14781525
14791526## 角色的抽象代码?
14801527
1528+
1529+ 值得注意的是:
1530+ 这里只考虑了一个Target和一个Runtime Config的情况,因此Init中也没有进行遍历
1531+
1532+
14811533下面我们来看看各个角色的抽象代码:
14821534
1535+ TODO continue
14831536
14841537- 一个Target Chunk的抽象代码
14851538``` ts
@@ -1659,7 +1712,7 @@ state = operateWhenRuntime(state)
16591712` ` ` ts
16601713declare function _handleConfigFunc1(state: state, someConfigData): any
16611714
1662- declare function _addRuntimeDataFunc1(someRuntimeDataFromState , someConfigData): any
1715+ declare function _addRuntimeConfigFunc1(someRuntimeConfigFromState , someConfigData): any
16631716
16641717export let parseConfig = ChunkHandler.parseConfig
16651718
@@ -1683,21 +1736,21 @@ export let init = (state: state, someConfigData): state => {
16831736
16841737 console.log("使用target...")
16851738
1686- let runtimeData = ChunkHandler.getRuntimeData (
1687- [_addRuntimeDataFunc1 , ... ],
1739+ let runtimeConfig = ChunkHandler.getRuntimeConfig (
1740+ [_addRuntimeConfigFunc1 , ... ],
16881741
16891742 target
16901743 )
16911744
16921745 return {
16931746 ...state,
16941747 target: target,
1695- runtimeData: runtimeData
1748+ runtimeConfig: runtimeConfig
16961749 }
16971750}
16981751
16991752export let operateWhenRuntime = (state: state): state => {
1700- console.log("使用state.runtimeData ...")
1753+ console.log("使用state.runtimeConfig ...")
17011754
17021755 return state
17031756}
@@ -1711,9 +1764,9 @@ type target = any
17111764
17121765export declare function buildTarget(handleConfigFuncs, parsedConfig: config, targetChunk, someConfigData): target
17131766
1714- type runtimeData = any
1767+ type runtimeConfig = any
17151768
1716- export declare function getRuntimeData(addRuntimeDataFuncs , target: target): runtimeData
1769+ export declare function getRuntimeConfig(addRuntimeConfigFuncs , target: target): runtimeConfig
17171770` ` `
17181771
17191772
@@ -1734,7 +1787,7 @@ TODO finish
17341787拼接后的Target 数据没有分支判断,非常精简
17351788
17361789- 提高性能
1737- 系统能够在初始化时一次性从配置文件中获得Runtime Data ,然后在运行时无需进行分支判断而是直接发送Runtime Data ,这样就提高了性能
1790+ 系统能够在初始化时一次性从配置文件中获得Runtime Config ,然后在运行时无需进行分支判断而是直接发送Runtime Config ,这样就提高了性能
17381791
17391792
17401793
0 commit comments