// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' Shader "ylq/Water Wave" { 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// _DistanceFactor("DistanceFactor",Float)=1//距离因子 _TimeFactor("TimeFactor",Float)=1//时间因子 _MaxOffSet("MaxOffSet",Float)=1//主纹理偏移因子 _WaveWidth("WaveWidth",Float)=0//波宽 _WaveAmount("WaveAmount",Float)=1//波数 _WavePoint("WavePoint",Color)=(0,0,0,0)//波点 } SubShader { Tags { "Queue"="Transparent" "RenderType"="Opaque" }//物体类型 渲染队列 GrabPass { "_RefractionTex" } Pass { Tags { "LightMode"="ForwardBase" }//参照灯光类型 Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM//开始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; float4 _RefractionTex_TexelSize; fixed _DistanceFactor; fixed _TimeFactor; fixed _MaxOffSet; fixed _WaveAmount; fixed _WaveWidth; fixed4 _WavePoint; struct a2v { //结构体 application to vertex float4 vertex : POSITION;//顶点 float3 normal : NORMAL;//法线 float4 tangent : TANGENT; //切线 正切 float4 texcoord : TEXCOORD0;//纹理 }; struct v2f { //vertex to fragment float4 pos : SV_POSITION;//位置 float4 scrPos : TEXCOORD0;//屏幕位置 float4 uv : TEXCOORD1;// float4 TtoW0 : TEXCOORD2; // float4 TtoW1 : TEXCOORD3; // float4 TtoW2 : TEXCOORD4; // }; v2f vert(a2v v) { //顶点函数 传入顶点 v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex);//模型空间转换到剪裁空间 o.scrPos = ComputeGrabScreenPos(o.pos);//将模型从剪裁空间转换到屏幕空间 o.uv.xy = TRANSFORM_TEX(v.texcoord, _MainTex);//获取主纹理屏幕的xy o.uv.zw = TRANSFORM_TEX(v.texcoord, _WaveMap);//获取波纹理屏幕的xy float3 worldPos = mul(_Object2World, v.vertex).xyz; //模型空间转换到世界空间 fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); //将法线从模型空间转换到世界空间 fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz); //将切线从模型空间转换到世界空间 fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w; //叉乘(法线,正切) o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x); o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y); o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z); return o; } fixed4 frag(v2f i) : SV_Target //为什么要用矩阵,因为c#控制纹理缩放,偏移,旋转,要比shader慢 { float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w); fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));// float2 speed = _Time.y * float2(_WaveXSpeed, _WaveYSpeed);//二维向量的波速 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);//叠加 float2 offset = bump.xy * _Distortion * _RefractionTex_TexelSize.xy;//获取偏移 i.scrPos.xy = offset * i.scrPos.z + i.scrPos.xy;//使得定点的位置,变换到偏移之后的位置 fixed3 refrCol = tex2D( _RefractionTex, i.scrPos.xy/i.scrPos.w).rgb; 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); float2 dir = _WavePoint.xy - i.uv.xy; float dis = length(dir); float2 offset1 = normalize(dir)*sin(dis*_DistanceFactor + _Time.y*_TimeFactor)*_MaxOffSet*0.1; float t1 = smoothstep(0, 1, _WaveWidth - dis); float t2 = 1 - t1; float4 offcol = tex2D(_MainTex,i.uv.xy+offset1);//主纹理偏移 return lerp(fixed4(finalColor,t2)*_Color,fixed4(offcol.rgb,t1),t1*_WaveAmount);//lerp为什么三个参数?? } ENDCG//结束CG } } // Do not cast shadow FallBack Off }
unity shader水波源码
最新推荐文章于 2025-06-02 21:33:51 发布