# lcc-render **Repository Path**: haotxp/lcc-render ## Basic Information - **Project Name**: lcc-render - **Description**: 便捷,自由,可调 cocos creator 自定义渲染框架 - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 86 - **Created**: 2020-10-23 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 仓库地址:[**lcc-render**](https://gitee.com/nomat/lcc-render "lcc-render") # lcc-render Cocos Creator自定义渲染框架,更便捷,更自由的构建渲染效果。 ## 前言 没怎么写过文档,可能写得不太好,请谅解。
最近在Cocos论坛上看到很多人发的Shader效果,自己也想使用这些效果。但是发现大家发的Shader在Creator里面并不是太好使用,大家的Shader并没有考虑到Creator自己的合图与渲染合批功能,使用限制比较大。于是就有了这个项目。
本人最早是做cocos2dx的,接触creator没有多久,基本算是直接用吧,可能下面的代码会有更好的实现方式。 ## 安装 安装十分简单,只要把这个项目作为Creator插件放到插件目录就可以了,具体请查看[**Creator插件包**](https://docs.cocos.com/creator/manual/zh/extension/your-first-extension.html "Creator插件包")。
## 使用 如果你想自己用插件中已经有的效果你可以直接在节点上添加效果组件,如图:
![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ%E6%88%AA%E5%9B%BE20201021211709.png)
你可以直接添加一个以`render.Effect*`开始的效果组件,当然添加完后,一般需要再把渲染的图片拖动到自动添加的render.ShaderSpriteFrame组件里面。如图:
![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201021212711.png)
好了,渲染效果应该已经出来了,你可以通过修改`render.Effect*`组件上的参数改变渲染效果。当然,如果你想要定制你的渲染,那么就需要看看下面的文档了。
其实渲染效果的基本参数都可以在`render.Effect*`里面设置,比如这个马赛克效果组件:
![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201022095118.jpg)
* 当然上面只是框架上附带的一些懒人包效果,多谢Cocos论坛上提供效果的大佬们。 * 再看框架设计前,你应该具备一些基本的shader知识。 # 框架设计 框架并不是单个渲染组件,而是把节点作为渲染的容器,各种渲染参数通过组件的方式加入渲染系统中。渲染组件主要分为: * 渲染系统`RenderSystem`
这类组件继承了`RenderComponent`组件,主要负责渲染组织和刷新流程等操作。具体比如更新材质,属性,形状,顶点等。 * 着色器组件`ShaderComponent`
着色器组件就是具体的渲染数据或则控制数据,比如 SpriteFrame, Color, Float, Vec2, Vec3, Vec4, Macro等。这类组件与向着色器传递的数据相关。 ## 1、传递什么数据到Shader中? 框架通过`着色器组件`组织需要向Shader传递的数据。比如我们需要渲染一张图片那么`ShaderSpriteFrame`组件应该是需要加入到渲染系统的,这个组件会负责把图片的数据传递到Shader里面,但是如果我们需要做`Shader遮罩`那么我们可能需要再添加一个 `ShaderSpriteFrame` 来把遮罩图片的数据传递进去。嗯,如果再想自定义下颜色,我们再加一个 `ShaderColor` 组件吧。传递数据的大小是可控的,不需要的数据就不传。 ## 2、如何传递数据到Shader中? 一般我们向Shader中传递数据的方式有两种: * uniform 以常量的方式传递,在Creator中我们可以通过获取渲染组件的材质直接设置属性的值。 优势是简单;缺点是不利于渲染合批。 * attribute 顶点数据的方式传递,在现在的Creator中我们不自定义渲染的类是办不到的。优势是可以合批渲染;缺点是现在Creator中不好实现,会消耗更多的内存。 但是特别是在需要大量渲染的地方,渲染合批是很重要的。所以框架使用了 `自定义数据传递方式` ,我们可以在着色器组件中选择每个数据传递的方式。当然有些数据是应该用指定的方式传递的,这类数据不能切换方式。
我们可以根据一个效果图对比:
=>这是使用uniform方式传递数据的效果
![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201022093602.jpg)
=>这是使用attribute方式传递数据的效果
![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201022093525.jpg)
可以看出使用attribute方式`Draw Call` 数量少得多。 ## 3、如何自定义数据传递方式? 得益于Creator的Shader定义可以使用宏,比如: ``` #if USE_TEXTURE uniform sampler2D texture; #endif ``` 通过宏定义我们可以动态裁剪Shader代码。比如我们在Shader的片段着色器写入下面的代码: ``` #if ATTR_COLOR in vec4 color; #elif UNIF_COLOR uniform UNIF_COLOR { vec4 color; }; #else vec4 color = vec4(1,1,1,1); #endif ``` 如果我们想使用顶点传递颜色(顶点可以使用不同的颜色),那么我们可以在材质上定义`ATTR_COLOR`为`true`, `UNIF_COLOR`为`false`,然后通过顶点传递数据。如果我们想使用常量,可以定义`ATTR_COLOR`为`false`, `UNIF_COLOR`为`true`,然后定义常量。当然还有个默认的值,如果我们都定义为`false`的话。
在使用数据的时候我们也可以通过 ``` if ATTR_COLOR || UNIF_COLOR // ... ... 这是如果传递了数据到着色器的操作 #endif ``` 那么顶点着色器该怎么传递这些数据呢(这个框架当前基本没有考虑顶点着色器使用数据的情况,好像大部分效果都没有使用到)很简单。 ``` // 定义颜色 #if ATTR_COLOR in vec4 a_color; out vec4 color; #endif ... void main(){ ... #if ATTR_COLOR color = a_color; // 就把颜色传递过去了 #endif ... } ``` 哈哈,看着是不是感觉还是要写很多东西,但是我们有宏,可以简化这些操作。 ``` ############## 顶点着色器 // 定义颜色 LCC_VERT_VALUE_DEFINE(COLOR, vec4, color) ... void main(){ ... LCC_VERT_VALUE_PASS(COLOR, color) ... } ############## 片段着色器 LCC_FRAG_VALUE_DEFINE(COLOR, vec4, color, vec4(1.0,1.0,1.0,1.0)) ... void main(){ ... gl_FragColor = color; // 这里color就随便用了 ... } ``` * 由于还没有怎么搞清楚插件怎么定义shader的include文件。所以现在框架都是手动添加的,具体的defines文件路径 `lcc-render/framework/src/render/build/lcc-defines.inc` ## 4、着色器组件上如何选择传递的方式? 在着色器组件上的变量基本上都定义了2种方式,如图: * `UNIFORM` 常量格式 ![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201021230131.png)
`Unif Macro`表示这个常量使用的宏,`Name`是宏名称,`Check Only`表示这个常量的宏只作为检测使用。 * `所谓检测使用 表示只有前面定义了这个宏为true的时候,这个常量才启用,传递其值` 这个用在多个数据绑定上,比如:
``` #if USE_TEXTURE in vec2 a_uv; out vec2 uv; #endif ``` 只有在定义了`USE_TEXTURE`才会传递`a_uv`, 没有纹理,他的UV也没有作用。 `Unif Name` 表示这个常量在Shader中的名称。 * `ATTRIBUTE` 顶点数据 ![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201021230223.png)
顶点数据的`Attr Macro` 与 `Name` 和上面常量意义相同, `特别注意的是如果是通过顶点传递数据,可以给每个顶点分配不一样的数据,比如给图片的四个点设置不同的颜色`
# 着色器组件介绍 ## ShaderSpriteFrame 这个组件和图片相关,如果你的渲染效果需要图片的话需要添加这个组件,需要多少张图片就可以添加多少个。 ![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201021232912.png)
* `Apply Shape` 是否应用当前图片的尺寸,如果选择,那么渲染的尺寸以下面的设置为准(`如果整个渲染系统中没有组件应用形状,则会用节点矩形的形状`)。 * `Shape Type` 形状的类型,可以直接使用节点的形状也可以自定义。 * `Trim` 和`Sprite`组件一致,配合上面的形状可以实现`Sprite`中的Simple模式。 * `Apply UV` 应用这张图片的UV到Shader中。 * `Custom UV` 可以定义UV顶点的顺序。 * `Apply UVRect` 应用UV在合图后的rect矩形到Shader中,`再也不用关闭合图了,但是你可能要计算真实UV与图片UV的关系,宏定义提供了宏函数`。 * `Apply Frame Size` 这个可以算是传递图片的像素尺寸到Shader中,一些效果比如高斯模糊需要。 ## ShaderColor 这个组件和颜色有关,如果你的渲染效果需要传递颜色的话,需要添加这个组件。 ![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201021233033.png)
* `Apply Node Color` 直接应用节点的颜色。 * `Color Type` 可以定义单色,也可以定义每个顶点颜色。 * `Vertex Colors` 每个顶点的颜色, 顺序是 左下, 右下, 左上, 右上。可以在修改的时候直接看变化。 ## ShaderFloat/ShaderVec2/ShaderVec3/ShaderVec4 这一些数值的着色器组件只有数据类型不一样,具体用法包含在`ShaderColor`里面。 ## ShaderMacro 这个着色器组件主要是可以自由定义Shader中的宏。 ![avatar](https://gitee.com/nomat/lcc-render/raw/master/docs/QQ截图20201021234849.png)
* `Macro Name` 定义的宏的名称。 * `Check Macro` 如果不为空,则会检测这个宏是否为`true`, 如果为`true`才会定义这个组件的宏。 * `Value Type` 宏的值类型,有`Value`数值和`Bool`布尔。 * 注意Shader中的宏,定义值的方式。 ``` #pragma define LAYERS range([4, 5]) #pragma define METALLIC_SOURCE options([r, g, b, a]) ``` [**Effect 语法**](https://docs.cocos.com/creator3d/manual/zh/material-system/effect-syntax.html "Effect 语法") * `Bool` 布尔值。 * `Value` 数值。 ## ShaderEffect*系列具体效果组件 这些组件基本上就是在组装多个着色器组件,并且统一控制他们,没有什么特别。可以看看框架的ShaderEffect*组件类源码。
当前框架中内置的效果组件: * `EffectFlashLight` 扫光效果,可以配置扫光速度,角度,数量,间距,宽度等参数。 * `EffectFluxaySuper` 流光效果,可以配置速度。 * `EffectGaussianBlur` 高斯模糊,因为如果太大会有性能问题,所以没有开放配置接口。 * `EffectGlowInner` 内发光效果,可以配置颜色,宽度,阈值和闪烁等。 * `EffectGlowOutter` 外发光效果,和内发光效果差不多。 * `EffectMosaic` 马赛克效果,可以配置程度(0-1)。 * `EffectOutline` 外轮廓线效果,可以配置颜色,宽度,闪烁等。 * `EffectPhoto` 照片效果,可以配置老照片/变灰,程度等。 * `EffectRoundCornerCrop` 圆角裁剪效果,可以配置程度等。 * `EffectSpriteMask` Shader遮罩效果,配置原图和遮罩图等,`为了最好的效果,请关闭图片的自动裁剪,并且最好大小一样`。 其实,在添加了这些内置效果组件后,你同样可以再添加其他的着色器组件,比如马赛克组件是没有设置颜色的,你完全可以自己在节点上添加一个ShaderColor组件以控制颜色。