做网站的合作案例,京津冀协同发展英文,黄金网站,wordpress表单数据前台显示这次要用表面着色器实现一个水的特效。先翻到最下边看代码#xff0c;看不懂再看下面的解释。
首先第一步要实现水的深浅判断#xff0c;实现深水区和浅水区的区分。
这里需要用到深度图的概念。不去说太多概念#xff0c;只去说怎么实现的#xff0c;首先我们的水面是在…这次要用表面着色器实现一个水的特效。先翻到最下边看代码看不懂再看下面的解释。
首先第一步要实现水的深浅判断实现深水区和浅水区的区分。
这里需要用到深度图的概念。不去说太多概念只去说怎么实现的首先我们的水面是在地面上的我们可以利用深度图计算得到人眼到地面的距离depth人眼到水面的距离记作IN.Proj.z 可以看的出来当我们看深水区的时候depth-IN.Proj.z的差值会比浅水区大所以可以通过这个差值的大小去判断深水区和浅水区。这个IN就是我这个水面的其中某一块着色面片表面着色器的输入结构体值。depth可以通过调一系列api得到里面涉及到很多空间变换不仔细去讲了只说大体思路。
然后在判断完水的深浅以后我们要通过设置一个深水色和一个浅水色将我们的depth-IN.Proj.z映射到[0,1]中这样通过对每个面片设置一个lerp差值lerp(_WaterShallowColor,_WaterDeepColor, min(_DepthRange, deltaDepth)/_DepthRange)就可以得到整片水域的颜色深浅过度而这个映射的过程我们可以通过设置另外一个变量_DepthRange实现。
min(_DepthRange, deltaDepth)/_DepthRange这个意思就是当我水很深的时候min(_DepthRange, deltaDepth)_DepthRange整体得1所以在lerp函数中取的是深水色当我水很浅的时候min(_DepthRange, deltaDepth)deltaDepthlerp的第三个参数就成了deltaDepth/_DepthRange因为水很浅所以这个数接近0颜色是接近浅水色如果水的深浅介于深水和浅水之间那么颜色也介于深水色和潜水色之间。但是这样深水和浅水虽然区分开了但是都是纯色的没有立体效果。
第二步通过对法线贴图采样实现水的立体效果。
下面的代码是说本来把法线贴图假设是第i,j个面片采样到我当前模型的面片但是现在不是采样到我当前面片 而是到了x方向加上_WaterSpeed * _Time.x这个值的面片先不管_Time.x会动因为uv的范围都是0-1所以本质上是在0-1的范围内采样的数量少了因为是本来是法线0-1对应模型0-1,现在相当于同样一个点采样的距离大了假设法线0-1对应模型0-1.4模型1-1.4的不会显示所以相当于是原来的0.6倍。 float4 bumpOffset1 tex2D(_NormalTex, IN.uv_NormalTex float2(_WaterSpeed * _Time.x, 0));
剩下三个计算也是同理只不过需要注意_Time.x是会变的这样子本来法线贴图假设是第i,j个面片采样到模型的m,n个面片一段时间后就是对应到了模型第m k,n个面片所有面片都这样映射相当于整体是移动了也就是有了大波浪效果汹涌澎湃。 float4 bumpOffset2 tex2D(_NormalTex, float2(1 - IN.uv_NormalTex.y, IN.uv_NormalTex.x) float2(_WaterSpeed * _Time.x, 0)); float4 offsetColor (bumpOffset1 bumpOffset2)/2; float2 offset UnpackNormal(offsetColor).xy * _Refract; float4 bumpColor1 tex2D(_NormalTex, IN.uv_NormalTex offset float2(_WaterSpeed * _Time.x, 0)); float4 bumpColor2 tex2D(_NormalTex, float2(1 - IN.uv_NormalTex.y, IN.uv_NormalTex.x) offset float2(_WaterSpeed * _Time.x, 0)); 第三步是要实现波纹主要对浅水区波纹的实现是要对WaveTex贴图进行采样。
WaveTex贴图就是一个黑白交替的图白色表示有波纹黑色表示没有但它是0-1对应模型0-1但其实我们是需要将一个更大范围的x映射到一个更小范围的WaveTex贴图上的此时就可以用到GPUGem里讲的正弦波模拟水面波纹了 首先要对波形图和噪声图进行采样对波形图进行采样两次是为了产生两道波纹采样的时候使用噪声图是为了产生随机的效果对波形图采样要采用上面的正弦波的方式去采这样就有一个波浪的效果了 fixed4 waveColor tex2D(_WaveTex,float2(waveA _WaveRange * sin(_Time.x * _WaveSpeed noiseColor.r) , 1) offset); fixed4 waveColor2 tex2D(_WaveTex,float2(waveA _WaveRange * sin(_Time.x * _WaveSpeed _WaveDelta noiseColor.r) , 1) offset); Shader Custom/MyWater2
{Properties{_Color (Color, Color) (1,1,1,1)_MainTex (Albedo (RGB), 2D) white {}_WaterShallowColor(WaterShallowColor, Color) (1,1,1,1)_WaterDeepColor(WaterDeepColor, Color) (1,1,1,1)_TranAmount(TranAmount, Range(0,100)) 0.5_DepthRange(DepthRange,float) 1_NormalTex(Normal,2D) bump{}_WaterSpeed(WaterSpeed,float) 5//控制法线的密集程度_Refract(Refract,float) 0.5_Specular(Specular,float) 1_Gloss(Gloss,float) 0.5_SpecularColor(_SpecularColor, Color) (1,1,1,1)//波浪效果需要先对波浪图采样噪声图是为了产生随机效果_WaveTex(WaveTex,2D) white{}_NoiseTex(NoiseTex,2D) white{}_WaveSpeed(WaveSpeed,float) 1_WaveRange(WaveRange,float) 0.5_WaveRangeA(WaveRangeA,float) 1_WaveDelta(WaveDelta, float) 0.5} SubShader{Tags { RenderTypeTransparent QueueTransparent }LOD 200//水是透明的所以关闭ZWriteZWrite offCGPROGRAM// Physically based Standard lighting model, and enable shadows on all light types#pragma surface surf WaterLight vertex:vert alpha noshadow// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0//加float是为了增加精度sampler2D_float _CameraDepthTexture;sampler2D _MainTex;fixed4 _WaterShallowColor;fixed4 _WaterDeepColor;half _TranAmount;half _DepthRange;sampler2D _NormalTex;half _WaterSpeed;sampler2D _WaveTex;sampler2D _NoiseTex;float _WaveSpeed;float _WaveRange;//这两个控制波浪的范围float _WaveRangeA;float _WaveDelta;struct Input{float2 uv_MainTex;float4 proj;float2 uv_NormalTex;float2 uv_WaveTex;float2 uv_NoiseTex;};half _Glossiness;half _Metallic;fixed4 _Color;half _Refract;half _Specular;half _Gloss;fixed4 _SpecularColor;// Add instancing support for this shader. You need to check Enable Instancing on materials that use the shader.// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.// #pragma instancing_options assumeuniformscalingUNITY_INSTANCING_BUFFER_START(Props)// put more per-instance properties hereUNITY_INSTANCING_BUFFER_END(Props)fixed4 LightingWaterLight(SurfaceOutput s, fixed3 lightDir, half3 viewDir, fixed atten){float diffuseFactor max(0,dot(normalize(lightDir),s.Normal));half3 halfDir normalize(lightDir viewDir);float nh max(0,dot(halfDir,s.Normal));float spec pow(nh, s.Specular * 128) * s.Gloss;fixed4 c;c.rgb (s.Albedo * _LightColor0.rgb * diffuseFactor _SpecularColor.rgb * spec * _LightColor0.rgb) * atten;c.a s.Alpha spec * _SpecularColor.a;return c;}void vert(inout appdata_full v,out Input i){UNITY_INITIALIZE_OUTPUT(Input, i);i.proj ComputeScreenPos(UnityObjectToClipPos(v.vertex));COMPUTE_EYEDEPTH(i.proj.z);}void surf (Input IN, inout SurfaceOutput o){//关键点是深度图判断深水和浅水法线移动实现波浪效果//tex2Dproj(_CameraDepthTexture, IN.proj)tex2D(_CameraDepthTexture, IN.proj.xy/IN.proj.w)//对深度图采样采样屏幕空间//它的uv表示当前模型在顶点着色器画到屏幕后的坐标//采样后的每个变量都是一样的取r即可//越近深度图上对应的区域越红深度值接近1越远则越黑深度值接近0。也就是说深度值从0到1代表的是从远到近。half depth LinearEyeDepth(tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(IN.proj)).r);//depth 就相当于是这样计算出来的//SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.proj));//UNITY_PROJ_COORD(IN.proj)是返回的采样后的纹理坐标大多数平台就是返回的IN.proj所以写不写区别不大//摄像机深度贴图的深度值减去地面模型面片的深度值half deltaDepth depth - IN.proj.z;fixed4 c lerp(_WaterShallowColor,_WaterDeepColor, min(_DepthRange, deltaDepth)/_DepthRange);//对法线贴图采样float4 bumpOffset1 tex2D(_NormalTex, IN.uv_NormalTex float2(_WaterSpeed * _Time.x, 0));float4 bumpOffset2 tex2D(_NormalTex, float2(1 - IN.uv_NormalTex.y, IN.uv_NormalTex.x) float2(_WaterSpeed * _Time.x, 0));float4 offsetColor (bumpOffset1 bumpOffset2)/2;float2 offset UnpackNormal(offsetColor).xy * _Refract;float4 bumpColor1 tex2D(_NormalTex, IN.uv_NormalTex offset float2(_WaterSpeed * _Time.x, 0));float4 bumpColor2 tex2D(_NormalTex, float2(1 - IN.uv_NormalTex.y, IN.uv_NormalTex.x) offset float2(_WaterSpeed * _Time.x, 0));//波浪 跟水的深浅相反即可 min(_DepthRange, deltaDepth)/_DepthRange接近1的地方应该无波浪//因为波浪要出现在水的边缘min(_DepthRange, deltaDepth)/_DepthRange接近1的地方 表示deltadepth很大水很深half waveA 1 - min(_WaveRangeA,deltaDepth)/_WaveRangeA;fixed4 noiseColor tex2D(_NoiseTex,IN.uv_NoiseTex);//sin函数来对波纹图采样产生流动效果fixed4 waveColor tex2D(_WaveTex,float2(waveA _WaveRange * sin(_Time.x * _WaveSpeed noiseColor.r) , 1) offset);fixed4 waveColor2 tex2D(_WaveTex,float2(waveA _WaveRange * sin(_Time.x * _WaveSpeed _WaveDelta noiseColor.r) , 1) offset);o.Albedo c.rgb (waveColor.rgb waveColor2.rgb) * waveA;o.Normal UnpackNormal((bumpColor1 bumpColor2)/2).xyz;o.Gloss _Gloss;o.Specular _Specular;o.Alpha min(_TranAmount,deltaDepth) / _TranAmount;}ENDCG}FallBack Diffuse
}法线贴图噪声图波纹图网盘链接
链接https://pan.baidu.com/s/1Qdm3ly2YW9vq9lNqYvZnbA?pwdjk3l 提取码jk3l