This page has been translated automatically.
Video Tutorials
Interface
Essentials
Advanced
How To
UnigineEditor
Interface Overview
Assets Workflow
Settings and Preferences
Working With Projects
Adjusting Node Parameters
Setting Up Materials
Setting Up Properties
Lighting
Landscape Tool
Sandworm
Using Editor Tools for Specific Tasks
Extending Editor Functionality
Built-in Node Types
Nodes
Objects
Effects
Decals
Light Sources
Geodetics
World Nodes
Sound Objects
Pathfinding Objects
Players
Programming
Fundamentals
Setting Up Development Environment
Usage Examples
C++
C#
UnigineScript
Plugins
File Formats
Rebuilding the Engine Tools
GUI
Double Precision Coordinates
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
Content Creation
Content Optimization
Materials
Art Samples
Tutorials

Creating a Custom Shader for Post-Processing

Unigine engine allows you to create your own post-effects by writing custom shaders. To write post-effect shaders, you should use the Scriptable Materials workflow: create the material, write the necessary shaders, and apply it globally or per-camera.

This tutorial explains how to create a post-effect grayscale material, write the shader for it, add a parameter to the material to be able to specify the value from the UnigineEditor.

See Also#

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 custom pass for shaders and textures.

The material will have the following structure:

Source Code (ULON)
BaseMaterial greyscale <preview_hidden=true var_prefix=var texture_prefix=tex>
{
	
	Texture color <type="procedural">
	Texture dirt = "core/textures/water_global/foam_d.dds" <anisotropy=true>

	
	Slider grayscale_power = 0.5 <min=0.0 max=1.0 max_expand=true>
	Slider dirt_power = 0.5 <min=-1.0 max=1.0 max_expand=true>

	/* ... */
	// more code below
}

The key features of this post material are:

  • Added the shader and textures for post pass.
  • Added the shared grayscale_power and dirt_power parameters.

Save the new material as grayscale.basemat file to the data folder.

Create Fragment Shader#

This section contains the sample code for the fragment shader (also known as pixel shader).

To create the fragment shader for the custom pass, add the following ULON node to the material:

Source Code (ULON)
/* ... */

// define the custom render pass
Pass my_pass
{
	Fragment = 
	#{
		// Include the UUSL fragment shader header
		#include <core/shaders/common/fragment.h>

		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_color, uv);
			
			// Get the dirt color
			float4 dirt_color = TEXTURE_BIAS_ZERO(tex_dirt, uv);
			
			// Calculate the grayscale
			float3 gray_scene_color = to_float3(rgbToLuma(scene_color.rgb));
			scene_color.rgb = lerp(scene_color.rgb, gray_scene_color, var_grayscale_power);

			// add some dirt and calculate the final color
			OUT_COLOR = scene_color + dirt_color * var_dirt_power;
			
		MAIN_END

		// end
	#}
}

/* ... */
// more code below
Warning
You should add a new line (press Enter) after closing the instruction (after MAIN_END command).

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.
  • We convert the color of the scene to grayscale.
  • By using lerp function (which performs a linear interpolation), we add the custom grayscale_power parameter to adjust the grayscale power.
  • We also get the dirt texture and apply it to the final scene color to simulate dirt 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).
Notice
Use the materials_reload console command to reload shaders whilst the engine is running.

See Also#

Perform Custom Render Pass#

Write the Expression callback in Unigine Script which is called after the Post Materials stage (RENDER_CALLBACK_END_POST_MATERIALS) of the render sequence to perform the custom grayscale render pass.

Source Code (ULON)
/* ... */

// the expression in Unigine Script defines a callback 
Expression RENDER_CALLBACK_END_POST_MATERIALS = 
#{
	// declare the source texture from the screen frame
	Texture source = engine.render.getTemporaryTexture(engine.render_state.getScreenColorTexture());

	// define the source texture from the screen frame
	source.copy(engine.render_state.getScreenColorTexture());

	//set the color source texture to use it in the shader
	setTexture("color", source);

	// render the result texture to output it to the screen 
	renderPassToTexture("my_pass", engine.render_state.getScreenColorTexture());

	// release the temporaty texture
	engine.render.releaseTemporaryTexture(source);
#}

/* ... */
// more code below

Save the material file and let's proceed to UnigineEditor.

Editing the Material#

Material has been created, the shader has been written, it's time to use it in the project!

  1. Open UnigineEditor and launch your project.
  2. Create a new material by inheriting from the recently created grayscale material in the Materials Hierarchy window.
  3. Open the Settings window by choosing Windows -> Settings from the main menu
  4. In the Settings window choose Runtime -> World -> Render -> Scriptable Materials and specify the name of the child grayscale material in the field.

    The grayscale post-effect will be applied.

  5. Configure your post-effect by adjusting the Grayscale Power and Dirt Power parameters.

    The final scene.
Last update: 2021-08-24
Build: ()