Tutorial: Cocos Shader Series - Use a Noise Map to Make a Dissolve Texture

Cocos Shader Series - Use a Noise Map to Make a Dissolve Texture

Series Chapters

  1. Basic Introduction
  2. Build A Triangle
  3. Draw More Things
  4. Add Some Texture
  5. Draw Shaders With Cocos Creator
  6. Change a shader with a texture map
  7. Use a Noise Map to Make a Dissolve Texture
  8. Building With WebGL
  9. Alpha Testing and Blending
  10. Blend Testing

In the previous chapter, we successfully used custom effects and materials to replace the built-in materials of the Sprite component. In this chapter, we try to modify the custom Effect to achieve the texture dissolving effect.

To achieve this effect, you need to mark which pixels are displayed and which pixels disappear. A better way is to use a noise map to mark each pixel. A noise map is similar to the figure below. A noise map has only three colors of black, white, and gray. The black, white, and gray are not uniformly distributed, leading to an irregular dissolution effect.

image

The most straightforward production of the dissolving effect usually requires two parameters: the noise map and the threshold for controlling the filtering of black/white pixels. Let’s try to define these two parameters.

Cocos Effect

CCEffect

In the previous article, we know that the CCEffect package is a rendering process description list edited in YAML format. The main content involves interaction with the editor and data interaction with CCProgram. Recalling the structure of CCEffect, the content is roughly the following:

CCEffect %{
    techniques: # technique Rendering technology represents the completion of a final effect plan. A plan can be completed by the integration of one or more Passes.  - passes: # A pass is a GPU drawing, which generally includes a vertex shader and a fragment shader.
      - vert: vs:vert
      frag: fs:frag
}

CCProgram vs %{
    //...
}

CCProgram fs %{
    //...
}

This is the most basic shader declaration (for example, the shader of the graphics component Graphics). If you want to add a parameter or texture, it cannot be satisfied. So we need to understand more parameters of pass. The most commonly used parameters are as follows:

Parameters

Property Name Description Notes
properties It stores the customizable parameters in the pass that need to be displayed on the property inspector Refer to the properties parameters table
blendState Mixed state of the material Please refer to the mixing section in the pass parameter list of the Cocos Creator manual
depthStencilState Depth & template direction status The corresponding depthStencilState section of the pass optional configuration parameter of Cocos Creator manual
rasterizerState Rasterization status data processing. At present, only the face culling option can be configured Please refer to the RasterizerState section in the pass parameter list of Cocos Creator manual
switch Specifies a power switch for the current pass. It could be any valid macro name that’s not defined in the shader. The macro name shouldn’t collide with any existing macros inside the shader This property doesn’t exist by default, which means the pass is executed unconditionally

Among them, blendState, depthStencilState, and rasterizerState can be worked on.

Properties

Property name Default value Transparent term Notes
target undefined undefined Any valid uniform components, no random swizzle
Value Refer to default values
editor.displayName Refine parameter of any string
editor.type vector vector, color Parameter type
editor.visible true true, false Whether the parameter is visible to the editor
editor.tooltip Parameter usage prompt, any string
editor.range [min,max,[step]] Parameter value range
editor.slide falsetrue Whether the parameter values should be changed, which can be used in combination with the range
editor.parent Specifies that a macro can only be used when it is enabled
sampler.minFilter/magFilter Linear None, point, linear, anisotropic Picture wrapping
sampler.addressU/addressV/addressW wrap wrap,mirror, clamp, border Picture wrapping

Defalut values

Type Default value Optional
int, ivec2/3/4
float, vec2/3/4
sampler2D default Black, grey, white, normal, default
samplerCube default-cube Black-cube, white-cube, default-cube

For more pass and properties parameters, please refer to the pass parameters list in the reference below.

After understanding some crucial parameters, you can start to define parameters. Add some content to the final modified shader in the previous chapter:

CCEffect% { 
  Techniques: 
  - passes: 
    - Vert: VS: Vert 
      the frag: FS: the frag 
      blendState: 
        Targets: 
    - Blend:  to true
        BlendSrc: src_alpha 
        blendDst: one_minus_src_alpha 
        blendDstAlpha: one_minus_src_alpha 
        rasterizerState: 
        cullMode: none 
        Properties: 
            u_dissolveMap: {value: White, editor: {tooltip:  'Noise map'  }} 
            dissolveThreshold: {value: 0.5, editor: {range:[0, 1, 0.01], slide:  true , tooltip:  'dissolution threshold'  }}  # The parameters defined here are all Must point to the uniform declared at CCProgram
 }%

CCProgram vs %{ 
  precision highp  float ; #inc lude <cc-global> in vec3  a_position; in vec2  a_texCoord; in vec4  a_color;  out vec4  color;  out vec2  uv0;  vec4  vert () {  vec4  pos =  vec4 (a_position, 1) ;     pos = cc_matViewProj * pos;     uv0 = a_texCoord;     color = a_color;  return pos;   } }% CCProgram fs %{  precision highp float; in vec4  color; 

  uniform  Dissolve{ 
    float  dissolveThreshold;// Lava threshold [0, 1]; 
  };  #if  USE_TEXTURE in vec2  uv0;   uniform sampler2D  u_dissolveMap;// Lava shape texture;    #pragma  builtin(local)     layout( set  = 2, binding = 10)  uniform sampler2D  cc_spriteTexture;   #endif  vec4 frag  () {  vec4  o =  vec4 (1, 1, 1, 1);   #if  USE_TEXTURE       o *= texture(cc_spriteTexture, uv0);    #endif     o *= color; return  o ;   } }%

Then, go back to the editor, select the material, and you can see that two new adjustable parameters have been added:

After correlating the noise, process the solubility according to the dissolution threshold:

CCEffect% { 
  Techniques: 
  - passes: 
    - Vert: VS: Vert 
      the frag: FS: the frag 
      blendState: 
        Targets: 
        - Blend:  to true
            BlendSrc: src_alpha 
            blendDst: one_minus_src_alpha 
            blendDstAlpha: one_minus_src_alpha 
      rasterizerState: 
            cullMode: none 
      Properties: 
            u_dissolveMap: {value: White, editor: {tooltip:  'Noise map'  }} 
            dissolveThreshold: {value: 0.5, editor: {range:[0, 1, 0.01], slide:  true , tooltip:  'dissolution threshold'  }}  # The parameters defined here are all Must point to the uniform declared at CCProgram
 }%

CCProgram vs %{ 
  precision highp float; 
  #include <cc-global> in vec3  a_position; in  vec2  a_texCoord; in vec4  a_color;   out vec4  color;  out vec2  uv0;   vec4  vert () {   vec4  pos =  vec4 (a_position, 1);     pos = cc_matViewProj * pos;     uv0 = a_texCoord;     color = a_color; return  pos;   } }% CCProgram fs %{  

  precision highp float; 

  in  vec4  color; 

  uniform  Dissolve{
    float  dissolveThreshold;// Lava threshold [0, 1]; 
  }; 

  #if  USE_TEXTURE 
    in  vec2 uv0; 
    uniform sampler2D  u_dissolveMap; // The texture of the lava shape; 
    #pragma builtin(local)     layout( set  = 2, binding = 10)  uniform sampler2D  cc_spriteTexture;   #endif    vec4  frag () {   vec4  o =  vec4 (1, 1, 1, 1); float  value = 1.0;     #if USE_TEXTURE    vec4  dissolveMap = texture(u_dissolveMap, uv0); // If the r component of the color Less than the threshold, discard this coloring operation;         value *= dissolveMap.r;     #endif if (value <dissolveThreshold) { 
      discard; // Discard fragments smaller than the threshold to form a dissolution 
    } 

    #if USE_TEXTURE       o *= texture(cc_spriteTexture, uv0); // Blend with the original texture;     #endif     o *= color; if  (value <dissolveThreshold + 0.05) {       o = vec4(0.9, 0.6, 0.3, oa); // Set an edge over color on the edge of the dissolve     } return  o;   } }% 

Finally, I replaced the original image with the Cocos logo and adjusted the threshold to 0.2. The effect of the screen presentation is as follows:

If you want to modify the threshold at runtime, you can use the following methods:

const sprite = this.getComponent(Sprite);
const mat = sprite.customMaterial;
mat.setProperty('dissolveThreshold', 0.5);

So far, we have completed the transformation of a shader, and it seems very simple? Getting started with the shader requires us to keep trying, so you must try more shader transformations when you are learning. There are also many examples on the Internet, and you can try them out.

Content reference

Pass optional configuration parameters

2 Likes

Can you upload effect file @slackmoehrle ? There’s something wrong with the code in this post

Blockquote
const sprite = this.getComponent(Sprite);
const mat = sprite.customMaterial;
mat.setProperty(‘dissolveThreshold’, 0.5);

Version 3.6.x, I using this code but it not bring Property affect to shader :grimacing:
Ok, this work if turn of Packable in main Sprite inspector :joy: