1. 程式人生 > >【OpenGL】Shader例項分析(七)- 雪花飄落效果

【OpenGL】Shader例項分析(七)- 雪花飄落效果

研究了一個雪花飄落效果,感覺挺不錯的,分享給大家,效果如下:


程式碼如下:

Shader "shadertoy/Flakes" {  // https://www.shadertoy.com/view/4d2Xzc
	Properties{
		iMouse ("Mouse Pos", Vector) = (100,100,0,0)
		iChannel0("iChannel0", 2D) = "white" {}  
		iChannelResolution0 ("iChannelResolution0", Vector) = (100,100,0,0)
	}
	  
	CGINCLUDE    
	 	#include "UnityCG.cginc"   
  		#pragma target 3.0      
  		#pragma glsl

  		#define vec2 float2
  		#define vec3 float3
  		#define vec4 float4
  		#define mat2 float2x2
  		#define iGlobalTime _Time.y
  		#define mod fmod
  		#define mix lerp
  		#define atan atan2
  		#define fract frac 
  		#define texture2D tex2D
  		// 螢幕的尺寸
  		#define iResolution _ScreenParams
  		// 螢幕中的座標,以pixel為單位
  		#define gl_FragCoord ((_iParam.srcPos.xy/_iParam.srcPos.w)*_ScreenParams.xy) 
  		
  		#define PI2 6.28318530718
  		#define pi 3.14159265358979
  		#define halfpi (pi * 0.5)
  		#define oneoverpi (1.0 / pi)
  		
  		fixed4 iMouse;
  		sampler2D iChannel0;
  		fixed4 iChannelResolution0;
  		
        struct v2f {    
            float4 pos : SV_POSITION;    
            float4 srcPos : TEXCOORD0;   
        };              
        
       //   precision highp float;
        v2f vert(appdata_base v){  
        	v2f o;
        	o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
            o.srcPos = ComputeScreenPos(o.pos);  
            return o;    
        }  
        
        vec4 main(v2f _iParam);
        
        fixed4 frag(v2f _iParam) : COLOR0 {  
			return main(_iParam);
        }  
        
        
		vec4 main(v2f _iParam) {
		    vec2 p = gl_FragCoord.xy/iResolution.xy;
		    vec3  col = vec3(0,0,0);
		    float dd = 150;
		    for( int i=0; i<dd; i++ )
		    {
		        float an = 6.2831*float(i)/dd;
		        vec2  of = vec2( cos(an), sin(an) ) * (1.0+0.6*cos(7.0*an+iGlobalTime)) + vec2( 0.0, iGlobalTime );
		        col = max( col, texture2D( iChannel0, p + 20*of/iResolution.xy ).xyz );
		        col = max( col, texture2D( iChannel0, p +  5.0*of/iResolution.xy ).xyz );
		    }
		    col = pow( col, vec3(1.0,2.0,3.0) ) * pow( 4.0*p.y*(1.0-p.y), 0.2);
		    
			return vec4( col, 1.0 );
		}

    ENDCG    
  
    SubShader {    
        Pass {    
            CGPROGRAM    
  
            #pragma vertex vert    
            #pragma fragment frag    
            #pragma fragmentoption ARB_precision_hint_fastest     
  
            ENDCG    
        }    
    }     
    FallBack Off    
}

程式碼分析:

1)七邊形雪花的繪製演算法

具體程式碼如下:
float dd = 150;
for( int i=0; i<dd; i++ )
{
	float an = 6.2831*float(i)/dd;
	vec2  of = vec2( cos(an), sin(an) ) * (1.0+0.6*cos(7.0*an+iGlobalTime)) + vec2( 0.0, iGlobalTime );
	col = max( col, texture2D( iChannel0, p + 20*of/iResolution.xy ).xyz );
	col = max( col, texture2D( iChannel0, p +  5.0*of/iResolution.xy ).xyz );
}
在理解這段程式碼前,先理解怎麼畫一個圈,程式碼如下:
float dd = 30;
for( int i=0; i<dd; i++ )
{
	float an = 6.2831*float(i)/dd;
	vec2  of = vec2( cos(an), sin(an) );
	col = max( col, texture2D( iChannel0, p + 20*of/iResolution.xy ).xyz );
}
然後再準備一張貼圖,圖片中間是一個白色畫素,周圍都是黑色


效果如下:


這段程式碼處於fragment shader中,意味著螢幕上每個點都會進行上述的演算法。具體如下,遍歷貼圖中該點周圍的點(上面的程式碼中為距離該點為20單位的圓上的點),把周圍點中最亮的作為該點的顏色。 上面的貼圖有點特殊,只有一個點是白色,其餘點都是黑色的。那麼只有距離該點正好為20單位的點才會變成亮色,其餘的點都是黑色,如上圖的結果。一句話總結上面演算法的效果:

貼圖中的每一個“相對亮點”的周圍都會產生“相對亮的特定圖形”,圖形的亮度取決於該點的亮度,越亮越明顯效果可以參考文末的圖片。

接下來理解這段程式碼:

float dd = 150;
for( int i=0; i<dd; i++ )
{
	float an = 6.2831*float(i)/dd;
	vec2  of = vec2( cos(an), sin(an) ) * (1.0+0.7*cos(7.0*an));
	col = max( col, texture2D( iChannel0, p + 20*of/iResolution.xy ).xyz );
//	col = max( col, texture2D( iChannel0, p +  5.0*of/iResolution.xy ).xyz );
}
輸出結果如下:


a)  1.0+0.7*cos(7.0*an)的影象如下:


b)演算法中 of 向量的路徑為:


最後加上時間就可以實現動畫了:

vec2  of = vec2( cos(an), sin(an) ) * (1.0+0.6*cos(7.0*an+iGlobalTime)) + vec2( 0.0, iGlobalTime );
第一個iGlobalTime,用來控制雪花的旋轉,第二個iGlobalTime使雪花下落。

2)後期顏色等處理

這裡可以理解為一種postEffect處理,具體是如下的程式碼貢獻的效果:

col = pow( col, vec3(1.0,2.0,3.0) ) * pow( 4.0*p.y*(1.0-p.y), 0.2);

a)  pow(col, vec3(1.0, 2.0, 3.0)) 這句話使得顏色變成暖色調。col值的範圍為[0,1],對小數繼續pow運算,次數越高,該值越小。比如:0.5的1次方是0.5, 2次方為0.25, 3次方為0.125等;所以這句話的作用很明顯:red成份不變,green變小一些,blue變的更小。達到的效果,使得整體顏色會偏向暖色調。

b)pow(4.0*p.y*(1.0-p.y), 0.2) 使得螢幕上下兩邊變暗。

最後附上shader中用到的貼圖:


經過程式處理後,得到如下:


文章完畢,歡迎討論。

相關推薦

OpenGLShader例項分析- 雪花飄落效果

研究了一個雪花飄落效果,感覺挺不錯的,分享給大家,效果如下: 程式碼如下: Shader "shadertoy/Flakes" { // https://www.shadertoy.com/view/4d2Xzc Properties{ iMouse ("Mo

OpenGLShader例項分析- 照片閃光,圓角和遮罩

在遊戲中,當戰鬥結束後,對一些獲取的寶貝需要進行閃光處理。這篇文章介紹一個進行閃光處理的shader,執行效果如下: 程式碼如下: Shader "stalendp/imageShine" {       Properties {           _i

cocos2d-x 強大的shader系列:OpenGLShader例項分析-Wave

這篇文章主要分析一個Shader,從而感受shader的魅力,並學習相關shader的函式的用法。 下面是程式碼: Shader "shadertoy/Waves" {  //see https://www.shadertoy.com/view/4dsGz

OpenGLShader例項分析- AngryBots中的主角受傷特效

AngryBots是Unity官方的一個非常棒的例子,很有研究價值。以前研究的時候,由於其內容豐富,一時間不知道從哪入手寫文章分析。這一段時間研究shader技術比較多一些,就從shader的這一方面開始吧。首先分析其中的一個螢幕特效:當主角受到攻擊時會出現的全屏效果(p

OpenGLShader實例分析- 雪花飄落效果

mouse llb cto 接下來 pix lan details effect art 轉發請保持地址:http://blog.csdn.net/stalendp/article/details/40624603 研究了一個雪花飄落效果。感覺挺不錯的。分享給大家,效

筆記Mybatis高階查詢--儲存過程呼叫

以下例子展示Mybatis儲存過程呼叫,與普通查詢基本一樣,只是在配置對映時要加上statementType=“CALLABLE”,由於儲存過程方式不支援Mybatis的二級快取,所以要加上useCache=“false”。 在儲存過程中使用引數時,除了配置屬性名外,還需要指定

原始碼主成分分析PCA與獨立分量分析ICAMATLAB工具箱

本MATLAB工具箱包含PCA和ICA實現的多個函式,並且包括多個演示示例。 在主成分分析中,多維資料被投影到最大奇異值相對應的奇異向量上,該操作有效地將輸入訊號分解成在資料中最大方差方向上的正交分量。因此,PCA常用於維數降低的應用中,通過執行PCA產生資料的低維表示,同時,該低維表

Elasticsearch 5.6.12 原始碼——3啟動過程分析

版權宣告:本文為博主原創,轉載請註明出處! 簡介 本文主要解決以下問題: 1、ES啟動過程中的Node物件都初始化了那些服務? 構造流程 Step 1、建立一個List暫存初始化失敗時需要釋放的資源,並使用臨時的Logger物件輸出開始初始化的日誌。 這裡首先建立了一個List

Elasticsearch 5.6.12 原始碼——2啟動過程分析

版權宣告:本文為博主原創,轉載請註明出處! 簡介 本文主要解決以下問題: 1、啟動ES的入口類及入口方法是哪個?2、分析梳理ES服務啟動的主要流程? 入口類 ES的入口類為org.elasticsearch.bootstrap.Elasticsearch,啟動方法為: public

原創docker原始碼分析2---docker server

上一節,分析了Engine和job。那這一節就開始講下docker server。 1、docker server 1.1 主體流程 我們從main函式開始,看看docker server

OpenLayers專案分析 資料解析以GML為例

前面也提到過,OpenLayers設計是符合標準的,有良好的框架結構和實現機制,非常值得學習。OpenLayers支援的格式比較多,有XML、GML、GeoJSON、GeoRSS、JSON、KML、WFS等。這回主要以GML為例來看OpenLayers 資料的解析過程。   

主成分分析PCA原理解析

本文轉載於 http://www.cnblogs.com/jerrylead/archive/2011/04/18/2020209.html 主成分分析(Principal components analysis)-最大方差解釋      在這一篇之前的

原創docker原始碼分析1---框架與engine

原始碼為docker 1.6.2版本 為啥要用1.6.2版本,這是因為我買了一本書《Docker容器與容器雲》,這本書裡面也是用的1.6.2版本。 一邊可以學習這本書,一邊研究原始碼,事半功

OpenGLShader實例分析- AngryBots中的主角受傷特效

spa 2.7 imp ttext pro tint shader 作用 負責 轉發請保持地址:http://blog.csdn.net/stalendp/article/details/40859441 AngryBots是Unity官方的一個非常棒的樣例。非常有研究

原創Linux虛擬化KVM-Qemu分析之timer虛擬化

# 背景 - `Read the fucking source code!` --By 魯迅 - `A picture is worth a thousand words.` --By 高爾基 說明: 1. KVM版本:5.9.1 2. QEMU版本:5.0.0 3. 工具:Source Insight

原創VBA學習筆記2--例項,VBA刪除表中的空行

Sub 巨集1迴圈內刪列() '資料不規範,有的空行是4,有的是6,有的是1就不好處理了     For i = 15 To 100 Step 2          Rows(i).Delete Shift:=xlUp &nb

BZOJ4821[SDOI2017]相關分析線段樹

【BZOJ4821】[SDOI2017]相關分析(線段樹) 題面 BZOJ 洛谷 題解 看看詢問要求的東西是什麼。把所有的括號拆開,不難發現要求的就是\(\sum x,\sum y,\sum xy,\sum x^2\) 考慮修改操作。先是區間加法,對於\(\sum x,\sum y\)而言直接加就好了

NOI2015程式自動分析並查集

傳送門 開始想錯了,寫了個種類並查集 結果發現可能會有很多個種類 便直接離線做 先把所有相等的 m e

模型詳解AutoEncoder詳解——棧式自編碼:Stacked AutoEncoder

更新時間:2018-12-05 前言 之前介紹了AutoEncoder及其幾種拓展結構,如DAE,CAE等,本篇部落格介紹棧式自編碼器。 模型介紹 普通的AE模型通過多層編碼解碼過程,得到輸出,最小化輸入輸出的差異從而使模型學到有用的特徵。但是這種AE結構又

Web容器Tomcat原始碼分析3-生命週期管理

前言   從server.xml檔案解析出來的各個物件都是容器,比如:Server、Service、Connector等。這些容器都具有新建、初始化完成、啟動、停止、失敗、銷燬等狀態。tomcat的實現提供了對這些容器的生命週期管理,本文將通過對Tomcat7.0的