Examples of Opengl Shader Luminescent Lines

Keywords: Fragment

Maintain address for forwarding: http://blog.csdn.net/stalendp/article/details/21993227

This article mainly analyses a Shader, so as to feel the charm of Shader, and learn the usage of related shader functions.

Let's see how Shader works first:


Here is the code:

  1. Shader "shadertoy/Waves" {  //see https://www.shadertoy.com/view/4dsGzH  
  2.   
  3.     CGINCLUDE    
  4.   
  5.         #include "UnityCG.cginc"                
  6.         #pragma target 3.0    
  7.         struct vertOut {    
  8.             float4 pos:SV_POSITION;    
  9.             float4 srcPos;   
  10.         };  
  11.   
  12.         vertOut vert(appdata_base v) {  
  13.             vertOut o;  
  14.             o.pos = mul (UNITY_MATRIX_MVP, v.vertex);  
  15.             o.srcPos = ComputeScreenPos(o.pos);  
  16.             return o;  
  17.         }  
  18.   
  19.         fixed4 frag(vertOut i) : COLOR0 {  
  20.   
  21.             fixed3 COLOR1 = fixed3(0.0,0.0,0.3);  
  22.             fixed3 COLOR2 = fixed3(0.5,0.0,0.0);  
  23.             float BLOCK_WIDTH = 0.03;  
  24.   
  25.             float2 uv = (i.srcPos.xy/i.srcPos.w);  
  26.   
  27.             // To create the BG pattern  
  28.             fixed3 final_color = fixed3(1.0);  
  29.             fixed3 bg_color = fixed3(0.0);  
  30.             fixed3 wave_color = fixed3(0.0);  
  31.   
  32.             float c1 = fmod(uv.x, 2.0* BLOCK_WIDTH);  
  33.             c1 = step(BLOCK_WIDTH, c1);  
  34.             float c2 = fmod(uv.y, 2.0* BLOCK_WIDTH);  
  35.             c2 = step(BLOCK_WIDTH, c2);  
  36.             bg_color = lerp(uv.x * COLOR1, uv.y * COLOR2, c1*c2);  
  37.   
  38.             // TO create the waves   
  39.             float wave_width = 0.01;  
  40.             uv = -1.0 + 2.0*uv;  
  41.             uv.y += 0.1;  
  42.             for(float i=0.0; i<10.0; i++) {  
  43.                 uv.y += (0.07 * sin(uv.x + i/7.0 +  _Time.y));  
  44.                 wave_width = abs(1.0 / (150.0 * uv.y));  
  45.                 wave_color += fixed3(wave_width * 1.9, wave_width, wave_width * 1.5);  
  46.             }  
  47.             final_color = bg_color + wave_color;  
  48.   
  49.             return fixed4(final_color, 1.0);  
  50.         }  
  51.   
  52.     ENDCG    
  53.   
  54.     SubShader {    
  55.         Pass {    
  56.             CGPROGRAM    
  57.   
  58.             #pragma vertex vert    
  59.             #pragma fragment frag    
  60.             #pragma fragmentoption ARB_precision_hint_fastest     
  61.   
  62.             ENDCG    
  63.         }    
  64.   
  65.     }     
  66.     FallBack Off    
  67. }  

The following analysis:

1. ComputeScreenPos analysis:

Used to convert three-dimensional coordinates into points on the screen. There are two ways, please refer to. Official example

ComputeScreenPos is defined in the UnityCG.cginc file as follows:

  1. // Projected screen position helpers  
  2. #define V2F_SCREEN_TYPE float4  
  3. inline float4 ComputeScreenPos (float4 pos) {  
  4.     float4 o = pos * 0.5f;  
  5.     #if defined(UNITY_HALF_TEXEL_OFFSET)  
  6.     o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w * _ScreenParams.zw;  
  7.     #else  
  8.     o.xy = float2(o.x, o.y*_ProjectionParams.x) + o.w;  
  9.     #endif  
  10.      
  11.     #if defined(SHADER_API_FLASH)  
  12.     o.xy *= unity_NPOTScale.xy;  
  13.     #endif  
  14.       
  15.     o.zw = pos.zw;  
  16.     return o;  
  17. }  
Principle analysis (to be continued)

2. Drawing Background

2.1) fmod For the remainder, for example, fmod(1.5, 1.0) returns 0.5;

2.2) step(a,x): 0 if x < a; 1 if x >= a; for example: step(1, 1.2), return 1; step(1, 0.8) return 0;

2.3) Combining fmod and step can get a dotted line effect. For example, the code to get the dotted line length of 1 is as follows:

c1 = fmod(x, 2*width); c1=step(width,c1); // where width is 1

Then if the range of x is [0,1], the value of C 1 is 0; in the range of [1,2], the value of C 1 is 1; 2 is a period;

Then fmod plays a role in the production cycle, step calculates 0 and 1 in the cycle;

2.4) By applying the knowledge in 2.3 to 2 dimensions, the square can be calculated.

The usage of lerp function: lerp (a, b, f) F is a percentage (range of values [0, 1]); if f is 0, then lerp returns a, f is 1, then b. If f is between 0 and 1, the value between a and b is returned.

In code lerp(uv.x * COLOR 1, uv.y * COLOR 2, c1*c2); where the values of c1 and C2 are either 1 or 0, they can be meshed. The background is drawn as follows:


3. Drawing of ripple

3.1) Conversion of coordinates

UV = 1.0 + 2.0 * uv; / / / extend and displace the original UV to get a new uv. Our operation is done on the new uv, and the final display will map to the original uv. Please refer to the following figure.


3.2) Draw a straight line:

Since the y axis is moved to the center of the screen, the upper half of the screen is positive and the lower half is negative. The code is as follows:

  1. wave_width = abs(1.0 / (50.0 * uv.y));  
  2. wave_color = fixed3(wave_width * 1.9, wave_width, wave_width * 1.5);  
Among them, 50.0 is used to control the width of the line (the larger the value, the thinner the line). The effect is as follows:


3.3) Change a straight line into a curve and make it move:

  1. uv.y += (0.07 * sin(uv.x*10 + _Time.y));  
  2. wave_width = abs(1.0 / (50.0 * uv.y));  
  3. wave_color = fixed3(wave_width * 1.9, wave_width, wave_width * 1.5);  
The results are as follows:


3.4) Draw more curves to form waves:

[csharp] view plain copy
 
  1. for(float i=0.0; i<10.0; i++) {  
  2.     uv.y += (0.07 * sin(uv.x + i/7.0 +  _Time.y));  
  3.     wave_width = abs(1.0 / (150.0 * uv.y));  
  4.     wave_color += fixed3(wave_width * 1.9, wave_width, wave_width * 1.5);  
  5. }  
See the beginning of the article for the final effect.

In fact, shader writing, many times through continuous effect overlay and debugging to achieve results.

Posted by sdallas411 on Fri, 19 Apr 2019 15:54:33 -0700