Unity Shader基於視差對映的雲海效果
雲海效果的實現
這裡的雲海shader有RPM和POM兩個版本,最終使用的是RPM。
在迭代次數足夠的情況下,兩種差別不大。
躁波圖的rgb是顏色,a是高度
VS方法
v2f vert (appdata_full v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex) + frac(_Time.y*_HeightTileSpeed.zw);
o.uv2 = v.texcoord * _HeightTileSpeed.xy;
o.posWorld = mul(unity_ObjectToWorld, v.vertex);
o.normalDir = UnityObjectToWorldNormal(v.normal);
TANGENT_SPACE_ROTATION;
o.viewDir = mul(rotation, ObjSpaceViewDir(v.vertex));
o.color = v.color;
#if USING_FOG
HeightFog(o.posWorld.xyz,o.fog);
#endif
UNITY_TRANSFER_FOG(o,o.pos);
return o;
}
shader計算了兩套uv,uv是高度和顏色貼圖的uv,uv2是做擾動用的uv
viewDir是切線空間下的視線向量,透明度寫在頂點色裡
FS方法裡初始化
float3 viewRay = normalize(-i.viewDir);
viewRay.z = abs(viewRay.z)+0.42;
viewRay.xy *= _Height;
float3 shadeP = float3(i.uv,0);
float3 shadeP2 = float3(i.uv2,0);
0.42的一個hack的值,是為了防止攝像機向量V和法向量N夾角過大。本身精度足夠是不需要這個值的,但是為了減少迭代次數必須加上這個值。
_Height控制雲的凹凸程度。
shadeP、shadeP2 用於記錄迭代的狀態。
shadeP的xy是取樣uv,z是當前深度。
shadeP2的xy是擾動uv,z沒有用到。
視差計算
RPM版
const int linearStep = 2;
const int binaryStep = 5;
float4 T = tex2D(_MainTex, shadeP2.xy);
float h2 = T.a * _HeightAmount;
// linear search
float3 lioffset = viewRay / (viewRay.z * (linearStep+1));
for(int k=0; k<linearStep; k++)
{
float d = 1.0 - tex2Dlod(_MainTex, float4(shadeP.xy,0,0)).a * h2;
shadeP += lioffset * step(shadeP.z, d);
}
// binary search
float3 biOffset = lioffset;
for(int j=0; j<binaryStep; j++)
{
biOffset = biOffset * 0.5;
float d = 1.0 - tex2Dlod(_MainTex, float4(shadeP.xy,0,0)).a * h2;
shadeP += biOffset * sign(d - shadeP.z);
}
先線性查詢,再用二分法查詢。
取樣過程中乘上擾動的高度值。
注:專案用的深度圖其實是高度圖,所以取樣和上文有點區別,取的是一個反向的值。
迭代次數越多,效果越好,過少會出現顏色分層。
POM版
float linearStep = 7;
float4 T = tex2D(_MainTex, shadeP2.xy);
float h2 = T.a * _HeightAmount;
float3 lioffset = viewRay / (viewRay.z * linearStep);
float d = 1.0 - tex2Dlod(_MainTex, float4(shadeP.xy,0,0)).a * h2;
float3 prev_d = d;
float3 prev_shadeP = shadeP;
while(d > shadeP.z)
{
prev_shadeP = shadeP;
shadeP += lioffset;
prev_d = d;
d = 1.0 - tex2Dlod(_MainTex, float4(shadeP.xy,0,0)).a * h2;
}
float d1 = d - shadeP.z;
float d2 = prev_d - prev_shadeP.z;
float w = d1 / (d1 - d2);
shadeP = lerp(shadeP, prev_shadeP, w);
先線性查詢,最後直接對最後兩次查詢做線性插值。
迭代的次數過少會丟失細節。
光照計算
half4 c = tex2D(_MainTex,shadeP.xy) * T * _Color;
half Alpha = i.color.r;
float3 normal = normalize(i.normalDir);
half3 lightDir = UnityWorldSpaceLightDir(i.posWorld);
float NdotL = max(0,dot(normal,lightDir));
#if USING_FOG
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.posWorld));
float sunFog = saturate( dot(-viewDir,lightDir));
half3 sunFogColor = lerp(_HeightFogColor,_sunFogColor,pow(sunFog,2));
fixed3 finalColor = c.rgb * (NdotL * lightColor + unity_AmbientEquator.rgb * sunFogColor * _LightIntensity);
unity_FogColor.rgb = lerp(sunFogColor, unity_FogColor.rgb, i.fog.y*i.fog.y);
finalColor.rgb = lerp(finalColor.rgb,unity_FogColor.rgb, i.fog.x);
#else
fixed3 finalColor = c.rgb*(NdotL*lightColor + unity_AmbientEquator.rgb);
#endif
UNITY_APPLY_FOG(i.fogCoord, finalColor);
return ColorOutput(fixed4(finalColor.rgb,Alpha));
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70016819/viewspace-2895935/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Unity Shader 實現雨天的水面漣漪效果Unity
- Unity Shader 基於光照圖的簡易晝夜變化Unity
- Unity Shader 00 - 梳理 Unity Shader 的基本結構Unity
- Unity Shader之磨砂玻璃與水霧玻璃效果Unity
- 網頁視差效果精品教程:具有視差效果的標籤頁切換網頁
- Unity3D中的shader基礎知識Unity3D
- 10個關於視差滾動效果的教程和外掛
- Unity2D橫板遊戲之背景視差與無限滾動效果Unity遊戲
- 用css實現視差效果CSS
- CSS完成視差滾動效果CSS
- Unity 的 Surface Shader有關記錄Unity
- 【Unity Shaders】Mobile Shader Adjustment—— 什麼是高效的ShaderUnity
- unity 統一替換shaderUnity
- 基於直接地址對映的CMAC神經網路Mac神經網路
- 基於Pixel Shader的FFT已經完成FFT
- css實現視差滾動效果CSS
- UIMotionEffect和Home頁背景視差效果UI
- 《Unity Shader入門精要》自學筆記(五)第八章 透明效果Unity筆記
- [非專業翻譯] Mapster - 基於規則的對映
- Spring MVC 基於URL的攔截和對映規則SpringMVC
- unity shader 溶解,上下左右,cutoffUnity
- Mybatis 基礎xml對映MyBatisXML
- Unity3D學習筆記3——Unity Shader的初步使用Unity3D筆記
- 視覺差緩動效果的輪播--React版視覺React
- Unity&Shader常用函式的使用方法Unity函式
- Unity Shader 入門精要 筆記(1)Unity筆記
- Unity3D 透明物體ShaderUnity3D
- 【Unity Shader入門精要】— 高階篇Unity
- ElasticSearch - 基礎概念和對映Elasticsearch
- 視差滾動效果的10個教程和外掛
- mybatis入門基礎(四)----輸入對映和輸出對映MyBatis
- 基於JDBC寫一個和mybatis類似的對映框架—DBUtilsJDBCMyBatis框架
- Unity3D Shader官方教程翻譯(三)----Shader語法:屬性Unity3D
- Unity3D Shader官方教程翻譯(四)----Shader語法:SubShaderUnity3D
- 關於CCmdTarget及訊息對映
- 用 Stellar.js 製作視差滾動效果JS
- Unity開發--(三)Shader程式設計:寫一個shader讓圖片的背面不被剔除Unity程式設計
- 【Unity3D Shader程式設計】之二 雪山飛狐篇:Unity的基本Shader框架寫法&顏色、光照與材質Unity3D程式設計框架