创建用于后处理的自定义着色器
Unigine engine allows you to create your own post-effects by writing custom shaders. To write post-effect shaders, you should use the same workflow as for deferred and forward rendering passes: create the material, write vertex and fragment shaders. Unigine引擎允许您通过编写自定义着色器来创建自己的后效果。要编写后效果着色器,应使用与延迟渲染和前向渲染过程相同的工作流程:创建材质,编写顶点和片段着色器。
This tutorial explains how to create a post-effect material, write shaders for it (both vertex and fragment), add a parameter to the material to be able to specify the value from the UnigineEditor.本教程介绍了如何创建后效果材质,为其编写着色器(顶点和片段),向材质添加参数以能够从UnigineEditor中指定值。
- Getting StartedGetting Started
- Materials Files FormatsMaterials Files Formats
- Creating a Custom Shader for Deferred Rendering passCreating a Custom Shader for Deferred Rendering pass
- Creating a Custom Shader for Forward Rendering passCreating a Custom Shader for Forward Rendering pass
- UUSL Data Types and Common Intrinsic FunctionsUUSL Data Types and Common Intrinsic Functions
- UUSL TexturesUUSL Textures
- UUSL SemanticsUUSL Semantics
- UUSL ParametersUUSL Parameters
- Getting Started 入门
- Materials Files Formats 材料文件格式
- Creating a Custom Shader for Deferred Rendering pass 为延迟渲染过程创建自定义着色器
- Creating a Custom Shader for Forward Rendering pass 为正向渲染过程创建自定义着色器
- UUSL Data Types and Common Intrinsic Functions UUSL数据类型和常见的内部函数
- UUSL Textures UUSL纹理
- UUSL Semantics UUSL语义
- UUSL Parameters UUSL参数
See Also也可以看看#
- The article on Material Settings关于 材料设置 的文章
- The article on Custom Materials关于 自定义材料 的文章
Create a Material创建材料#
As in all other shaders tutorials, you should create the material first. Let's add a new base material to your project.与所有其他着色器教程一样,您应该首先创建材质。让我们向您的项目添加新的基础材料。
To create post-effect material, you should specify the post pass for shaders and textures.要创建后效材质,应为着色器和纹理指定后期处理。
The material will have the following structure:该材料将具有以下结构:
<?xml version="1.0" encoding="utf-8"?>
<base_material version="2.0" name="custom_post" editable="0">
<!-- Post-effect shaders -->
<shader pass="post"
defines="BASE_POST"
vertex="shaders/vertex/post.vert"
fragment="shaders/fragment/post.frag"/>
<!-- Textures -->
<texture name="color" pass="post" unit="0" type="procedural"/>
<texture name="dirt" pass="post" unit="1" anisotropy="1" workflow="0" tooltip="Dirt color texture">core/textures/water_global/foam_d.dds</texture>
<!-- Parameters -->
<slider name="grayscale_power" shared="1" min="0.0" max="1.0" flags="max_expand">0.5</slider>
<slider name="dirt_power" shared="1" min="-1.0" max="1.0" flags="max_expand">0.5</slider>
</base_material>
The key features of this post material are:这篇文章的主要特征是:
- Added shaders and textures for post pass.为post传递添加了着色器和纹理。
- Added the shared grayscale_power and dirt_power parameters.添加了共享的grayscale_power和dirt_power参数。
Save the new material as custom_post.basemat file to the data folder.将新材料作为custom_post.basemat文件保存到data文件夹。
Create Vertex Shader创建顶点着色器#
Since we write a simple shader example, let's write a simple shader like the vertex shader for the deferred rendering pass.由于我们编写了一个简单的着色器示例,因此让我们编写一个简单的着色器,例如延迟的渲染遍历的顶点着色器。
- Write the shader code in the plain text editor:
// Include the UUSL header #include <core/shaders/common/common.h> // Input data struct STRUCT(VERTEX_IN) INIT_ATTRIBUTE(float4,0,POSITION) // Vertex position INIT_ATTRIBUTE(float4,1,TEXCOORD0) // Vertex texcoords INIT_ATTRIBUTE(float4,2,COLOR0) // Vertex color END // Output data struct STRUCT(VERTEX_OUT) INIT_POSITION // Output projected position INIT_OUT(float2,0) // Texcoords (x and y only) END MAIN_BEGIN(VERTEX_OUT,VERTEX_IN) // Set output position OUT_POSITION = getPosition(IN_ATTRIBUTE(0)); OUT_DATA(0).xy = IN_ATTRIBUTE(1).xy; MAIN_END // end
You should add a new line (press Enter) after closing the instruction (after MAIN_END command).在纯文本编辑器中编写着色器代码:You should add a new line (press Enter) after closing the instruction (after MAIN_END command).You should add a new line (press Enter) after closing the instruction (after MAIN_END command).// Include the UUSL header #include <core/shaders/common/common.h> // Input data struct STRUCT(VERTEX_IN) INIT_ATTRIBUTE(float4,0,POSITION) // Vertex position INIT_ATTRIBUTE(float4,1,TEXCOORD0) // Vertex texcoords INIT_ATTRIBUTE(float4,2,COLOR0) // Vertex color END // Output data struct STRUCT(VERTEX_OUT) INIT_POSITION // Output projected position INIT_OUT(float2,0) // Texcoords (x and y only) END MAIN_BEGIN(VERTEX_OUT,VERTEX_IN) // Set output position OUT_POSITION = getPosition(IN_ATTRIBUTE(0)); OUT_DATA(0).xy = IN_ATTRIBUTE(1).xy; MAIN_END // end
You should add a new line (press Enter) after closing the instruction (after MAIN_END command).关闭指令后(在MAIN_END命令之后),您应该添加新行(按Enter)。 - Save the shader file as post.vert to the data/shaders/vertex folder.将着色器文件另存为post.vert到data/shaders/vertex文件夹。
The code of the vertex shader is simple since we don't need to work with the geometry.顶点着色器的代码很简单,因为我们不需要使用几何。
Create Fragment Shader创建片段着色器#
This section contains instruction how to create a fragment shader (also known as pixel shader).本节包含有关如何创建片段着色器(也称为 pixel shader )的说明。
To create the fragment shader for post-process pass, perform the following:要为后处理传递创建片段着色器,请执行以下操作:
- Open a plain text editor, and write the following:
// Include the UUSL fragment shader header #include <core/shaders/common/fragment.h> // Define the texture of the scene INIT_TEXTURE(0,TEX_SCENE) INIT_TEXTURE(1,TEX_DIRT) // Input values STRUCT(FRAGMENT_IN) INIT_POSITION // Projected position INIT_IN(float2,0) // Texcoords END // Define the grayscale_power parameter CBUFFER(parameters) UNIFORM float grayscale_power; UNIFORM float dirt_power; END MAIN_BEGIN(FRAGMENT_OUT,FRAGMENT_IN) // Get the UV float2 uv = IN_DATA(0); // Get the scene color float4 scene_color = TEXTURE_BIAS_ZERO(TEX_SCENE,uv); // Get the dirt color float4 dirt_color = TEXTURE_BIAS_ZERO(TEX_DIRT,uv); // Calculate the grayscale float3 gray_scene_color = dot(float3(0.3f, 0.59f, 0.11f), scene_color.rgb); scene_color.rgb = lerp(scene_color.rgb,gray_scene_color,grayscale_power); // add some dirt OUT_COLOR = scene_color+dirt_color*dirt_power; MAIN_END // end
You should add a new line (press Enter) after closing the instruction (after MAIN_END command).打开一个纯文本编辑器,并编写以下内容:You should add a new line (press Enter) after closing the instruction (after MAIN_END command).You should add a new line (press Enter) after closing the instruction (after MAIN_END command).// Include the UUSL fragment shader header #include <core/shaders/common/fragment.h> // Define the texture of the scene INIT_TEXTURE(0,TEX_SCENE) INIT_TEXTURE(1,TEX_DIRT) // Input values STRUCT(FRAGMENT_IN) INIT_POSITION // Projected position INIT_IN(float2,0) // Texcoords END // Define the grayscale_power parameter CBUFFER(parameters) UNIFORM float grayscale_power; UNIFORM float dirt_power; END MAIN_BEGIN(FRAGMENT_OUT,FRAGMENT_IN) // Get the UV float2 uv = IN_DATA(0); // Get the scene color float4 scene_color = TEXTURE_BIAS_ZERO(TEX_SCENE,uv); // Get the dirt color float4 dirt_color = TEXTURE_BIAS_ZERO(TEX_DIRT,uv); // Calculate the grayscale float3 gray_scene_color = dot(float3(0.3f, 0.59f, 0.11f), scene_color.rgb); scene_color.rgb = lerp(scene_color.rgb,gray_scene_color,grayscale_power); // add some dirt OUT_COLOR = scene_color+dirt_color*dirt_power; MAIN_END // end
You should add a new line (press Enter) after closing the instruction (after MAIN_END command).关闭指令后(在MAIN_END命令之后),您应该添加新行(按Enter)。 - Save the shader file as post.frag to the data/shaders/fragment folder.将着色器文件另存为post.frag到data/shaders/fragment文件夹。
Well, let's clarify what is under the hood of this fragment shader:好吧,让我们澄清一下该片段着色器的内幕:
- We get the texture which was specified in the post-effect material.我们获得后效果材料中指定的纹理。
- By applying a standard grayscale equation, we change the color of the scene.通过应用标准灰度方程式,我们可以更改场景的颜色。
- By using lerp function (which performs a linear interpolation), we add the custom grayscale_power parameter to adjust the grayscale power.通过使用lerp函数(执行线性插值),我们添加了自定义grayscale_power参数来调整灰度等级。
- We also get the dirt texture and apply it to the final scene color to simulate dirn on camera lens (can also be used for vignette effect etc.)我们还获得了污垢纹理并将其应用于最终场景颜色,以模拟相机镜头上的污垢(也可以用于晕影效果等)。
- A custom dirt_power parameter to adjust intensity of the dirt texture (its impact on the final image).一个自定义dirt_power参数,用于调整污垢纹理的强度(其对最终图像的影响)。
See Also也可以看看#
- Grayscale article on Wikipedia. Grayscale article on Wikipedia.
Editing the Material编辑材料#
Material has been created, shaders have been written, it's time to use it in the project!已经创建了材质,编写了着色器,是时候在项目中使用它了!
- Open UnigineEditor and launch your project.打开UnigineEditor并启动您的项目。
- Create a new material by inheriting from the recently created one in the Materials Hierarchy window.通过继承Materials Hierarchy窗口中最近创建的材料来创建新材料。
- Open the Settings window by choosing Windows -> Settings from the main menu
通过从主菜单中选择Windows -> Settings打开Settings窗口。
- In the Settings window choose Runtime -> World -> Render -> Screen Space Materials and specify the name of the child post material in the Post field.
The grayscale post-effect will be applied.The grayscale post-effect will be applied.
The grayscale post-effect will be applied.在Settings窗口中,选择Runtime -> World -> Render -> Screen Space Materials,然后在Post字段中指定子帖子材料的名称。
The grayscale post-effect will be applied.将应用灰度后效果。
- Select your material in the Materials window. Then in the Parameters window select Parameters tab.
The final scene.The final scene.The final scene.在Materials窗口中选择材料。然后在Parameters窗口中选择Parameters选项卡。The final scene.最终场景。