Unity Shader實現圖形繪製(藍天白雲大海)
阿新 • • 發佈:2020-04-30
Unity Shader學習:2D圖形繪製(藍天白雲大海),供大家參考,具體內容如下
基本是一些數學上的演算法
shader部分:
Shader "Unlit/2D-Ocean" { Properties { _MainTex ("Texture",2D) = "white" {} _SunColor("SunColor",Color) = (1,1,1) _SunRoundColor("SunRoundColor",1) _WaveColor1("WaveColor1",1) _WaveColor2("WaveColor2",1) _WaveColor3("WaveColor3",1) _WaveColor4("WaveColor4",1) _WaveColor5("WaveColor5",1) _SkyColor("SkyColor",Color)=(0,1) _CloudPos1("CloudPos1",Vector)=(0,0) _CloudPos2("CloudPos2",Vector) = (0,0) _CloudPos3("CloudPos3",0) _CloudPos4("CloudPos4",0) _CloudPos5("CloudPos5",0) _WaveFactor1("WaveFactor1",0) _WaveFactor2("WaveFactor2",0) _WaveFactor3("WaveFactor3",0) _WaveFactor4("WaveFactor4",0) _WaveFactor5("WaveFactor5",0) _SunPos("SunPos",0) _SunRoundFactor("SunRoundFactor",Range(0.0,2.0)) = 0.1 _SunSize("SunSize",1.0)) = 1.0 } SubShader { Tags { "RenderType"="Transparent" } LOD 100 Blend SrcAlpha OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; float4 _CloudPos1; float4 _CloudPos2; float4 _CloudPos3; float4 _CloudPos4; float4 _CloudPos5; float4 _WaveColor1; float4 _WaveColor2; float4 _WaveColor3; float4 _WaveColor4; float4 _WaveColor5; float4 _WaveFactor1; float4 _WaveFactor2; float4 _WaveFactor3; float4 _WaveFactor4; float4 _WaveFactor5; float4 _SunColor; float4 _SunRoundColor; float4 _SunPos; float _SunRoundFactor; float _SunSize; float4 _SkyColor; //畫單個圓(uv,位置,大小,抗鋸齒) float4 Circle(float2 uv,float2 center,float size,float blur) { uv = uv - center; uv = uv / size; float len = length(uv); //長度大於一個半徑單位透明度為0,小於透明度為1 float val = smoothstep(1.0,1.0-blur,len); return float4(1,val); } //畫單個雲 float4 DrawCloud(float2 uv,float size) { uv = uv - center; uv = uv / size; float4 col = Circle(uv,float2(0.0,0.0),0.2,1); //將圓中不想要的部分剪下掉 col = col * smoothstep(-0.1,-0.1 + 0.01,uv.y); //圓擺放不同位置組成雲 col += Circle(uv,float2(0.15,-0.05),0.1,1); col += Circle(uv,-0.1),0.11,float2(-0.15,float2(-0.3,-0.08),float2(-0.2,0.15,1); return col; } //畫複數雲 float4 DrawClouds(float2 uv) { uv.x += 0.03*_Time.y; //使得左右連續 uv.x = frac(uv.x + 0.5) - 0.5; float4 col = DrawCloud(uv,_CloudPos1.xy,0.1); col += DrawCloud(uv,_CloudPos2.xy,0.12); col += DrawCloud(uv,_CloudPos3.xy,0.14); col += DrawCloud(uv,_CloudPos4.xy,0.16); col += DrawCloud(uv,_CloudPos5.xy,0.18); return col; } //畫太陽光環 float4 DrawSunCircle(float2 uv,float size) { uv = uv - center; uv = uv / size; //atan2返回點(x,y)與x軸的夾角,範圍(-π,π] //獲取極座標的θ角度 float degree = atan2(uv.y,uv.x ) + _Time.y * -0.1; //uv向量離中心點距離 //獲取極座標的r=x2+y2開方 float len = length(uv); //根據極座標玫瑰線:r(θ)=a*sin(kθ) //求得r;a為擴散幅度,k為花瓣數*0.5 float r = 0.3*abs(sin(degree*5.0)); //畫花瓣 //保留r值小於到中心點距離的所有畫素 float sunRound= smoothstep(r + 0.1 + _SunRoundFactor,r + _SunRoundFactor,sunRound)*_SunRoundColor; } //畫波浪(引數:uv,頻率,振幅,整體高度,移動速度) float4 DrawWave(float2 uv,float waveFrequency,float waveAmplitude,float waveHeight,float speed) { uv.x += speed * _Time.y; uv.y += sin(_Time.y+waveHeight)*0.02; //uv.y大於sin函式的部分透明度為0,小於的部分透明度為1 float val = uv.y - sin(uv.x*waveFrequency)*waveAmplitude - waveHeight; val = smoothstep(0.001,0.0,val); return float4(1,val); } //畫背景 float4 DrawBackground(float2 uv) { float4 val = lerp(float4(1,1),_SkyColor,uv.y); return val; } //混合圖層(b為前景,a為背景) float4 LerpImages(float4 a,float4 b) { return float4(lerp(a,b,b.a).rgb,a.a + b.a); } v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv,_MainTex); return o; } float4 frag (v2f i) : SV_Target { //太陽中心 float4 sunCoreColor = Circle(i.uv,_SunPos.xy,_SunSize,0.05)*_SunColor; //太陽光環 float4 sunAroundColor = DrawSunCircle(i.uv,_SunSize); //雲 float4 cloudsColor = DrawClouds(i.uv); //波浪 float4 wave1 = DrawWave(i.uv,_WaveFactor1.x,_WaveFactor1.y,_WaveFactor1.z,_WaveFactor1.w)*_WaveColor1; float4 wave2 = DrawWave(i.uv,_WaveFactor2.x,_WaveFactor2.y,_WaveFactor2.z,_WaveFactor2.w)*_WaveColor2; float4 wave3 = DrawWave(i.uv,_WaveFactor3.x,_WaveFactor3.y,_WaveFactor3.z,_WaveFactor3.w)*_WaveColor3; float4 wave4 = DrawWave(i.uv,_WaveFactor4.x,_WaveFactor4.y,_WaveFactor4.z,_WaveFactor4.w)*_WaveColor4; float4 wave5 = DrawWave(i.uv,_WaveFactor5.x,_WaveFactor5.y,_WaveFactor5.z,_WaveFactor5.w)*_WaveColor5; //背景 float4 backgroundColor = DrawBackground(i.uv); //圖層疊加 float4 finalColor = LerpImages(backgroundColor,sunAroundColor); finalColor = LerpImages(finalColor,sunCoreColor); finalColor= LerpImages(finalColor,wave1); finalColor = LerpImages(finalColor,wave2); finalColor = LerpImages(finalColor,wave3); finalColor = LerpImages(finalColor,wave4); finalColor = LerpImages(finalColor,wave5); finalColor = LerpImages(finalColor,cloudsColor); return finalColor; } ENDCG } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。