文章目录
自言自语
学习shader已经有几个月了。痛并快乐着。今天是学习简单水效果制作。 根据书中讲解。又自己调整和变化了下。出现如下效果。写起来挺简单,不过思路确实如果书上不说,我可想不到。面板就不贴了,支持颜色和方向光颜色强度,存档在这 后边继续。 想把投影也加进去。结果太晚了。肝不动了 空了再说吧。
一、效果
二、shader部分
Shader "TNShaderPractise/ShaderPractise_WaterMate_041"
{
Properties
{
[HDR]_Color("水体颜色",color)=(1.0,1.0,1.0,1.0)
[HDR]_Color2("水体反射颜色",color)=(1.0,1.0,1.0,1.0)
_MainTex ("表面水花", 2D) = "white" {}
_WaterBump("水体噪声法线贴图",2D)="bump"{}
_CubeMap("镜面反射环境贴图",Cube)="Skybox"{}
_Distortion("水折射强度",Range(0,1000.0))=1000
_Xspeed("横向水流速度", Range(-0.1,0.1))=0
_Yspeed("横向水流速度",Range(-0.1,0.1))=0
_AlphaValue("水体透明度",Range(0,1.0))=1.0
}
SubShader
{
Tags { "RenderType"="Opaque" "Queue"="Transparent" }
GrabPass{"_RefrctionTex"}
Pass
{
Tags{"LightMode"="ForwardBase"}
Cull Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
#pragma multi_compile_fwdbase
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _WaterBump;
float4 _WaterBump_ST;
samplerCUBE _CubeMap;
sampler2D _RefrctionTex;
float4 _RefrctionTex_TexelSize;
fixed4 _Color;
float _Xspeed;
float _Yspeed;
float _Distortion;
float4 _Color2;
float _AlphaValue;
struct a2v
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal : NORMAL;
float4 tangent : TANGENT;
};
struct v2f
{
float4 uv : TEXCOORD1;
float4 pos : SV_POSITION;
float4 posWS : TEXCOORD2;
float3 TtoW1 : TEXCOORD3;
float3 TtoW2 : TEXCOORD4;
float3 TtoW3 : TEXCOORD5;
float4 scrPos : TEXCOORD7;
SHADOW_COORDS(6)
};
v2f vert (a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
o.uv.zw = TRANSFORM_TEX(v.texcoord, _WaterBump);
o.posWS = mul(unity_ObjectToWorld,v.vertex);
//获取当前像素所在的屏幕空间坐标
o.scrPos = ComputeGrabScreenPos(o.pos);
//常规TBN
float3 normalWS = UnityObjectToWorldNormal(v.normal);
float3 tangentWS =UnityObjectToWorldDir(v.tangent.xyz);
float3 binormalWS = cross(tangentWS,normalWS)*v.tangent.w;
o.TtoW1 = float3 (tangentWS.x,binormalWS.x,normalWS.x);
o.TtoW2 = float3 (tangentWS.y,binormalWS.y,normalWS.y);
o.TtoW3 = float3 (tangentWS.z,binormalWS.z,normalWS.z);
TRANSFER_SHADOW(o)
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//声明一个XY轴的速度变量
float2 speed = _Time.y * float2 (_Xspeed,_Yspeed);
float3 vDir = normalize(UnityWorldSpaceViewDir(i.posWS.xyz));
fixed4 col = tex2D (_MainTex,i.uv.xy+speed);
//通过动态坐标采样并叠加两层 做出水的两层不同流向的感觉
fixed3 bump1 = UnpackNormal(tex2D(_WaterBump,i.uv.zw+speed));
fixed3 bump2 = UnpackNormal(tex2D(_WaterBump,i.uv.zw-speed));
fixed3 bump = normalize(bump1+bump2);
//做折射表现 因为我乘了一个透明度,所以折射会被削弱那么这里再除回来 进行加强
float2 offset = bump.xy*_Distortion*_RefrctionTex_TexelSize.xy/_AlphaValue;
//这个是随着深度加强折射变强 也可以不要乘以i.scrPos.z
i.scrPos.xy = offset*i.scrPos.z+i.scrPos.xy;
//折射吗 齐次除法后进行采样
fixed4 refR = tex2D(_RefrctionTex,i.scrPos.xy/i.scrPos.w);
half3 nDir = normalize(half3(dot(i.TtoW1.xyz,bump),dot(i.TtoW2.xyz,bump),dot(i.TtoW3.xyz,bump)));
//反射方向来了哦
float3 reflDir = normalize(reflect(-vDir,nDir));
float3 ambCol = UNITY_LIGHTMODEL_AMBIENT.xyz*col ;
UNITY_LIGHT_ATTENUATION(atten,i,i.posWS);
//这里加上灯光强度和颜色对海水的影响 感觉还不错
fixed4 refL = (texCUBE(_CubeMap,reflDir)*_Color2+_Color*col)*atten*_LightColor0+_LightColor0*0.3+float4(ambCol,1);
//加上frsnel进行动态插值 这样更符合睡眠反射原理
float fresnel =1- pow(saturate(dot(vDir,nDir)),4);
float4 finalCol = lerp(refR,refL,fresnel);
return fixed4 (finalCol.rgb,_AlphaValue);
}
ENDCG
//应该再有pass写投影.但是太晚了 有空再加吧
}
}
FallBack "Diffuse"
}
总结
反正挺有意思的 继续努力