准备1:
加入以下脚本到摄像机让depth texture 有效,水面整体颜色变化基于深度。

using UnityEngine;public class CameraDepthTextureMode : MonoBehaviour
{[SerializeField]DepthTextureMode depthTextureMode;private void OnValidate(){SetCameraDepthTextureMode();}private void Awake(){SetCameraDepthTextureMode();}private void SetCameraDepthTextureMode(){GetComponent<Camera>().depthTextureMode = depthTextureMode;}
}

准备2:
加入以下脚本到摄像机,得到一张在view空间的normal纹理

using UnityEngine;public class NormalsReplacementShader : MonoBehaviour
{[SerializeField]Shader normalsShader;private RenderTexture renderTexture;private new Camera camera;private void Start(){Camera thisCamera = GetComponent<Camera>();// Create a render texture matching the main camera's current dimensions.renderTexture = new RenderTexture(thisCamera.pixelWidth, thisCamera.pixelHeight, 24);// Surface the render texture as a global variable, available to all shaders.Shader.SetGlobalTexture("_CameraNormalsTexture", renderTexture);// Setup a copy of the camera to render the scene using the normals shader.GameObject copy = new GameObject("Normals camera");camera = copy.AddComponent<Camera>();camera.CopyFrom(thisCamera);camera.transform.SetParent(transform);camera.targetTexture = renderTexture;camera.SetReplacementShader(normalsShader, "RenderType");camera.depth = thisCamera.depth - 1;}
}

最终效果,已经详细中文注解了

水shader:

Shader ""
{Properties{// 浅颜色,根据深度渐变到深色_DepthGradientShallow("Depth Gradient Shallow", Color) = (0.325, 0.807, 0.971, 0.725)// 深颜色_DepthGradientDeep("Depth Gradient Deep", Color) = (0.086, 0.407, 1, 0.749)// 从浅到深的距离范围,是个渐变的cutoff_DepthMaxDistance("Depth Maximum Distance", Float) = 1// 泡沫颜色_FoamColor("Foam Color", Color) = (1,1,1,1)// 波浪纹理_SurfaceNoise("Surface Noise", 2D) = "white" {}// 滚动速度_SurfaceNoiseScroll("Surface Noise Scroll Amount", Vector) = (0.03, 0.03, 0, 0)// 卡通化阈值,控制色阶范围_SurfaceNoiseCutoff("Surface Noise Cutoff", Range(0, 1)) = 0.777// r g 两个值的法线图进行波浪扭曲_SurfaceDistortion("Surface Distortion", 2D) = "white" {} // 控制扭曲强度_SurfaceDistortionAmount("Surface Distortion Amount", Range(0, 1)) = 0.27// 控制泡沫范围_FoamMaxDistance("Foam Maximum Distance", Float) = 0.4_FoamMinDistance("Foam Minimum Distance", Float) = 0.04       }SubShader{Tags{"Queue" = "Transparent"}Pass{Blend SrcAlpha OneMinusSrcAlpha// 关闭写入深度,防止水遮挡后面物体ZWrite OffCGPROGRAM// 控制平滑插值结果范围#define SMOOTHSTEP_AA 0.01#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog#include "UnityCG.cginc"float4 alphaBlend(float4 top, float4 bottom){float3 color = (top.rgb * top.a) + (bottom.rgb * (1 - top.a));float alpha = top.a + bottom.a * (1 - top.a);return float4(color, alpha);}struct appdata{float4 vertex : POSITION;float4 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f{float4 vertex : SV_POSITION; float2 noiseUV : TEXCOORD0;float2 distortUV : TEXCOORD1;float4 screenPosition : TEXCOORD2;float3 viewNormal : NORMAL;UNITY_FOG_COORDS(3)};sampler2D _SurfaceNoise;float4 _SurfaceNoise_ST;sampler2D _SurfaceDistortion;// Unity自动填充tiling和offsetfloat4 _SurfaceDistortion_ST;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);// 由于要采样深度图,需要屏幕空间位置o.screenPosition = ComputeScreenPos(o.vertex);// transform_tex 会应用_ST的float4,进行tiling和offset变换o.distortUV = TRANSFORM_TEX(v.uv, _SurfaceDistortion);o.noiseUV = TRANSFORM_TEX(v.uv, _SurfaceNoise);o.viewNormal = COMPUTE_VIEW_NORMAL;UNITY_TRANSFER_FOG(o, o.vertex);return o;}float4 _DepthGradientShallow;float4 _DepthGradientDeep;float4 _FoamColor;float _DepthMaxDistance;float _FoamMaxDistance;float _FoamMinDistance;float _SurfaceNoiseCutoff;float _SurfaceDistortionAmount;float2 _SurfaceNoiseScroll;// 这张纹理并不用在properties声明,全局可用// 近处为1,远处为0,一张灰度图表示深度sampler2D _CameraDepthTexture;sampler2D _CameraNormalsTexture;float4 frag (v2f i) : SV_Target{// 取出已经渲染过非水体的深度值,虽然是0~1,但并不是线性的// 此处tex2Dproj和tex2D是可以替换的float existingDepth01 = tex2Dproj(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenPosition)).r;// 进行线性化,并且是世界单位(从相机开始)float existingDepthLinear = LinearEyeDepth(existingDepth01);// 计算水深值,使用w即可float depthDifference = existingDepthLinear - i.screenPosition.w;// 使用水深值,插值 深 浅 颜色float waterDepthDifference01 = saturate(depthDifference / _DepthMaxDistance);float4 waterColor = lerp(_DepthGradientShallow, _DepthGradientDeep, waterDepthDifference01);// 为了增加和水面垂直体之间的泡沫(深度值大),补偿foamdistance// 取出已经渲染过的法线float3 existingNormal = tex2Dproj(_CameraNormalsTexture, UNITY_PROJ_COORD(i.screenPosition));// 对水面和物体使用dot(垂直时为0,同方向为1,方向相反为-1),作为补偿float3 normalDot = saturate(dot(existingNormal, i.viewNormal));// 通过插值决定foamdistancefloat foamDistance = lerp(_FoamMaxDistance, _FoamMinDistance, normalDot);// 补偿值,控制cutofffloat foamDepthDifference01 = saturate(depthDifference / foamDistance);// 使用补偿值减弱的cut off,会显示更多noise,产生海岸线float surfaceNoiseCutoff = foamDepthDifference01 * _SurfaceNoiseCutoff;// 扭曲贴图是一张只有红和绿的法线图,使用这个vector2来拉扯noise的uv// *2 - 1 从 0 ~ 1 变换到 1 ~ -1 ,用_SurfaceDistortionAmount 来控制扭曲强度float2 distortSample = (tex2D(_SurfaceDistortion, i.distortUV).xy * 2 - 1) * _SurfaceDistortionAmount;// 利用偏移UV,模拟水的流动+扭曲float2 noiseUV = float2((i.noiseUV.x + _Time.y * _SurfaceNoiseScroll.x) + distortSample.x, (i.noiseUV.y + _Time.y * _SurfaceNoiseScroll.y) + distortSample.y);// 采样perlinNoise模拟波浪float surfaceNoiseSample = tex2D(_SurfaceNoise, noiseUV).r;// 卡通化处理,使用noisecutoff(float surfaceNoise = surfaceNoiseSample > _SurfaceNoiseCutoff ? 1 : 0;)// smoothstep 非线性插值,慢入慢出的曲线。 SMOOTHSTEP_AA 小值为 0.01float surfaceNoise = smoothstep(surfaceNoiseCutoff - SMOOTHSTEP_AA, surfaceNoiseCutoff + SMOOTHSTEP_AA, surfaceNoiseSample);// 泡沫偏色float4 surfaceNoiseColor = _FoamColor;surfaceNoiseColor.a *= surfaceNoise;// 泡沫色 混合 插值水色float4 r = alphaBlend(surfaceNoiseColor, waterColor);UNITY_APPLY_FOG(i.fogCoord, r);return r;}ENDCG}}
}

可运行的UnityPackage

如何使用:
1 导入unityPackage
2 Camera上需要添加CameraDepthTextureMode和NormalsReplacementShader,否则影响泡沫效果
3 在水面mesh上使用ToonWater材质
4 其中WaterBob脚本是模拟漂浮用的,可观察本例子中Cube物体效果

Shader实例:卡通水 Unity toon water shader相关推荐

  1. Unity3D Shader编程】之二 雪山飞狐篇:Unity的基本Shader框架写法颜色、光照与材质

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/40955607 作者:毛星云(浅墨) ...

  2. Shader山下(一)第一个Shader

    学习Unity3D就得学Shader,然而新手学习Shader往往不知道从何处下手,没有找对门,谈何入门. 本系列主要介绍Shader的一些基础知识,希望可以带你找对门,然后入得了门. (本文作者也尚 ...

  3. [Unity Shader] 水纹着色器 Water Shader

    着色器效果 基于Unity 2018.3.0.Amplify Shader Editor 1.5.7 water_shader.gif 参数设置 不进行背面剔除,这样从水下也能看到. 投射阴影和接受阴 ...

  4. 【Unity Shader实例】 水体WaterEffect(一) 设计

    Unity Shader 水体效果实现的设计 在设计水体效果的实现方案之前,我们先参考一下大神们写好的精彩的例子,比如DCG Water Shader的效果,这也是我们努力的目标. 好!~ 现在开始实 ...

  5. shader实例:实现类似宝可梦 Pokemon 的战斗转场

    宝可梦游戏在进入战斗前会有类似这样转场动画. 例子中使用的纹理质量较差,边缘比较模糊,和shader无关. 这个UI是盖在所有UI最前面的.可以使用shader来完成这个工作,而不是复杂的动画. 使用 ...

  6. D3D9 Shader实例教程

    啥是Shader? Shader是一段运行在GPU上的小程序,是运行在GPU上的Pipeline上的特定的可编程单元的小程序. 从D3D9 API层面学习Shader编程 随着Unity3D的流行,很 ...

  7. 2.在unity中创建shader模板

    知识提要: Mesh Filter : 存储一个Mesh(网格,模型的网格,就是模型的由哪些三角面组成,组成一个什么样子的模型,三角面的一些顶点信息) Mesh Renderer:用来渲染一个模型的外 ...

  8. Shader实例(流光实现)

    Shader实例(流光实现) 流光效果 首先来看一下流光效果.流光效果是一个非常常见的效果,不仅仅是游戏,一些广告之类的也都会有这种效果.流光的原理还是比较简单的:首先就是需要一张流光图,这张流光图的 ...

  9. Shader实例:Planar Reflection 平面反射

    目前采用比较多的反射,最终效果示例: 代码已经中文注解,有2部分需扩展:反射矩阵.歪截头体矩阵.注解中有来源链接可以去理解推导过程. 可用于镜面和水面. 咱还是直接看注解过的代码 MirrorRefl ...

最新文章

  1. 函数 tostring_Kotlin实战之Fuel的高阶函数
  2. linux 无法挂载系统,解决无法挂载Linux文件系统的问题
  3. 30款顶级CSS工具及应用-CSDN.NET
  4. 基于mysql的springmvcjar_糊涂jar_SpringMVC+Spring+Mybatis项目实战[SSM/MySQL/AJAX/IDEA]_Java视频-51CTO学院...
  5. android 设备连接,Android安卓设备连接Mac的方法
  6. 最简单的视音频播放示例6:OpenGL播放YUV420P(通过Texture,使用Shader)
  7. stol函数在linux下使用,linux socket编程(一)
  8. findfont: Font family [‘sans-serif‘] not found. Falling back to DejaVu Sans.
  9. MISRA C编程规范标准
  10. office卸载重新安装,并安装mathtype7数学编辑公式
  11. (个人)太极拳学习系统创新实训第一周(一)
  12. Python3网络爬虫:腾讯新闻App的广告数据抓取
  13. javaScripty笔记
  14. 改变边框线条与背景重叠的布局
  15. Ubuntu 下安装zsh和oh-my-zsh
  16. 在html页面中使用模板继承,HTML5下的模板继承
  17. 视频直播系统源码,保存平台视频内容到本地
  18. VARCHART XGantt系列教程:如何利用颜色来丰富甘特图智能
  19. 大学计算机素质教育认识,试论技术院校中计算机教育与素质教育的关系
  20. Laya_TS 鼠标点击事件

热门文章

  1. java实现五子棋_java实现五子棋
  2. tensorflow2.0 Keras VGG16 VGG19 系列 代码实现
  3. eac found not rust_rust进服务器卡eac | 手游网游页游攻略大全
  4. Python---GUI
  5. 保险行业数字化转型必须知道的 10 项「黑科技」
  6. 国内食品包装机选哪个品牌?云易科包装机怎么样?
  7. 镜子的Spring之旅 之 Spring MVC
  8. flutter自定义单元格_使用自定义大小的单元格制作复杂的UICollectionView布局(第1部分)
  9. mysql使用技巧之比较两个表是否有不同的数据
  10. 孩子不听话,打骂不管用,怎么教育?这6种方法比打骂更有效,越教越优秀