Shader水波紋效果
阿新 • • 發佈:2018-12-12
使用噪聲紋理模擬波紋
參考 《unity shader 入門精要》
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
Shader "Book/15.WaterWave" {
Properties {
_Color ("Main Color", Color) = (0, 0.15, 0.115, 1)
_MainTex ("Base (RGB)", 2D) = "white" {}
_WaveMap ("Wave Map", 2D) = "bump" {}
_Cubemap ( "Environment Cubemap", Cube) = "_Skybox" {}
_WaveXSpeed ("Wave Horizontal Speed", Range(-0.1, 0.1)) = 0.01
_WaveYSpeed ("Wave Vertical Speed", Range(-0.1, 0.1)) = 0.01
_Distortion ("Distortion", Range(0, 100)) = 10
}
SubShader {
Tags {"RenderType"="Opaque" "Queue"="Transparent"}
GrabPass{ "_RefractionTex"}
Pass {
Tags {"LightMode"="ForwardBase" }
CGPROGRAM
#include "UnityCG.cginc"
#include "Lighting.cginc"
#pragma multi_compile_fwdbase
#pragma vertex vert
#pragma fragment frag
fixed4 _Color;
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _WaveMap;
float4 _WaveMap_ST;
samplerCUBE _Cubemap;
fixed _WaveXSpeed;
fixed _WaveYSpeed;
float _Distortion;
sampler2D _RefractionTex;
//_RefractionTex紋理的畫素大小,假設紋理大小為256*512,畫素大小為(1/256,1/512)
float4 _RefractionTex_TexelSize;
struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 tangent : TANGENT;
float4 texcoord : TEXCOORD0;
};
struct v2f {
float4 pos : SV_POSITION;
float4 srcPos : TEXCOORD0;
float4 uv : TEXCOORD1;
float3 TtoW0 : TEXCOORD2;
float3 TtoW1 : TEXCOORD3;
float3 TtoW2 : TEXCOORD4;
float3 worldPos:TEXCOORD5;
};
v2f vert( a2v v ) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = v.texcoord*_MainTex_ST.xy + _MainTex_ST.zw;
o.uv.zw = v.texcoord*_WaveMap_ST.xy + _WaveMap_ST.zw;
o.srcPos = ComputeGrabScreenPos(o.pos);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
float3 worldNormal = mul(v.normal,(float3x3)unity_WorldToObject);
float3 worldTangent= mul((float3x3)unity_ObjectToWorld,v.tangent.xyz).xyz;
float3 worldBinormal = cross(worldNormal,worldTangent.xyz)*v.tangent.w;
o.TtoW0 = float3(worldTangent.x, worldBinormal.x, worldNormal.x);
o.TtoW1 = float3(worldTangent.y, worldBinormal.y, worldNormal.y);
o.TtoW2 = float3(worldTangent.z, worldBinormal.z, worldNormal.z);
return o;
}
fixed3 unpackNormal(fixed4 packedNormal)
{
fixed3 tangentNormal;
#if defined(UNITY_NO_DXT5nm)
tangentNormal.xyz = packedNormal.xyz*2 -1;
#else
// --rgba -- xyzw
//DXTnm 格式中a通道(即w分量)對應發現x分量,g通道(即y分量)對應發現y分量,
//tangentNormal.xy = packedNormal.ag*2 -1;
tangentNormal.xy = packedNormal.wy*2 -1;
//tangentNormal=tangentNormal* _BumpScale;
tangentNormal.z = sqrt(1.0-max(0,dot(tangentNormal.xy,tangentNormal.xy)));
#endif
return tangentNormal;
}
//反射
float3 Reflect(float3 I,float3 normal)
{
//return I - 2*normal*dot(normal,I);
return I - 2*normal*mul(I,float3x1( normal.x,normal.y,normal.z));
}
half4 frag(v2f i) : SV_Target {
float3 viewDir = _WorldSpaceCameraPos.xyz - i.worldPos;
viewDir = normalize(viewDir);
float2 speed =_Time.y*float2(_WaveXSpeed,_WaveYSpeed);
// Get the normal in tangent space
fixed3 bump1 = unpackNormal(tex2D(_WaveMap,i.uv.zw + speed)).rgb;
fixed3 bump2 = unpackNormal(tex2D(_WaveMap,i.uv.zw - speed)).rgb;
fixed3 bump = normalize(bump1 + bump2);
// Compute the offset in tangent space
float2 offset = bump.xy*_Distortion*_RefractionTex_TexelSize.xy;
i.srcPos.xy = offset*i.srcPos.z + i.srcPos.xy;
fixed3 refrCol = tex2D(_RefractionTex,i.srcPos.xy/i.srcPos.w).rgb;
// Convert the normal to world space
float3x3 rotation = float3x3(i.TtoW0,i.TtoW1,i.TtoW2);
bump = normalize(mul(rotation,bump));
//bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));
fixed4 texColor = tex2D(_MainTex, i.uv.xy + speed);
fixed3 reflDir = Reflect(-viewDir, bump);
fixed3 reflCol = texCUBE(_Cubemap, reflDir).rgb * texColor.rgb * _Color.rgb;
fixed fresnel = pow(1 - saturate(dot(viewDir, bump)), 4);
fixed3 finalColor = reflCol * fresnel + refrCol * (1 - fresnel);
return fixed4(finalColor,1);
}
ENDCG
}
}
FallBack "Diffuse"
}
效果:有失真壓縮了