前几天,家里出了一些问题,搞得心情很不好,面试我也取消了。
唉,反正那个伤心啊,不过,昨天处理好了。
所以说啊,家和万事兴。
加油加油!!!

所以心情好了,我又写博客了。

另外说一下:图形我今年2019.5才开始正式学习。
所以每个shader效果有些实现方法可能不是很好的,欢迎大神多多指点。

进入主题吧:

今天实现:Unity Shader - 实现类似镜面反射、水面扰动效果

Quad 效果

Cube 效果

思路

平面的过渡效果,可参考我之前写的一个,模型按平面渡效果:Unity Shader - 模型过滤效果
Noise 噪点实现类型水面可参考我之前写的:Unity Shader - Noise 噪点应用,实现类似流水的表面效果
模板缓存来只绘制镜面的内容:Unity Shader - 模板简单测试 - 实现镂空/遮罩、描边

上面两个效果组合,就差不多可以得到上面的效果了。

两个pass现实

第一个pass:绘制镜面模型

将模型的顶点按传进来的平面的法线、任一点,来对本体模型镜面顶点
这样再去绘制,就看起来又镜面的效果了
同时我们在镜像体绘制时,添加了纹理柏林噪点偏移UV,看起来有点像水流效果

但我们的镜面体的显示只能在那个地板模型中才绘制,所以我们给地板shader添加了Stencil处理(Stencil的功能实例看上面链接)

镜面详细讲解一下:

  • 首先我们需要将镜面的法线、任意平面点传入shader(*.cs脚本:下面将法线、坐标传入shader我列出来)
  • 然后利用平面信息将顶点镜像处理,具体看下图

第二个pass:绘制本体模型

绘制模型本体
但需要处理,上面Unity Shader - 模型过滤效果 的过渡效果,因为超过镜面底下,我们就不显示了(可以按需求来处理)
然后再对纹理UV扰动想水流似的,基本就这样就完了

将法线、坐标传入shader

// jave.lin 2019.08.15
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class UpdateProps : MonoBehaviour
{private static int nHash;private static int pHash;public GameObject obj;public GameObject plane;private Material objMat;// Start is called before the first frame updatevoid Start(){objMat = obj.GetComponent<MeshRenderer>().sharedMaterial;nHash = Shader.PropertyToID("n");pHash = Shader.PropertyToID("p");}// Update is called once per framevoid Update(){// n==normal of plane// p==position of planevar n = plane.transform.up;var p = plane.transform.position;objMat.SetVector(nHash, n);objMat.SetVector(pHash, p);}
}

镜面的模板shader

// jave.lin 2019.08.15
Shader "Test/MirrorGroundStencil"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Color ("Color", Color) = (1,1,1,1)}SubShader{Tags { "Queue"="Geometry+1" "RenderType"="Opaque" }Stencil {Ref 1Comp AlwaysPass Replace}Pass {CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata {float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f {float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;};sampler2D _MainTex;float4 _MainTex_ST;fixed4 _Color;v2f vert (appdata v) {v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}fixed4 frag (v2f i) : SV_Target {fixed4 col = tex2D(_MainTex, i.uv);return col * _Color;}ENDCG}}
}

需要绘制镜面效果的完整Shader

注释我写的相当详细了

// jave.lin 2019.08.15
Shader "Test/PerlinNoiseMirror" {Properties {[NoScaleOffset] _MainTex ("MainTex", 2D) = "white" {}               // 主纹理[NoScaleOffset] _NoiseTex ("NoiseTex", 2D) = "white" {}             // 噪点图_NoiseScaleX ("NoiseScaleX", Range(0, 1)) = 0.1                     // 水平噪点放大系数_NoiseScaleY ("NoiseScaleY", Range(0, 1)) = 0.1                     // 垂直放大系数_NoiseSpeedX ("NoiseSpeedX", Range(0, 10)) = 1                      // 水平扰动速度_NoiseSpeedY ("NoiseSpeedY", Range(0, 10)) = 1                      // 垂直扰动速度_NoiseBrightOffset ("NoiseBrightOffset", Range(0, 0.9)) = 0.25      // 噪点图整体的数值偏移_NoiseFalloff ("NoiseFalloff", Range(0, 1)) = 1                     // 扰动衰减_MirrorRange ("MirrorRange", Range(0, 3)) = 1                       // 镜面范围(最大范围,超出该范围就不反射)_MirrorAlpha ("MirrorAlpha", Range(0, 1)) = 1                       // 镜面图像不透明度_MirrorFadeAlpha ("_MirrorFadeAlpha", Range(0,1)) = 0.5             // 镜面范围值边缘位置的不透明度,如果调整为0,意思越接近该最大范围的透明就越接近该值:0}CGINCLUDE#include "UnityCG.cginc"#include "Lighting.cginc"#include "AutoLight.cginc"struct appdata {float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f {float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;float3 wPos : TEXCOORD1;};struct v2f_m {float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;float4 normal : TEXCOORD1;float4 wPos : TEXCOORD2;};sampler2D _MainTex;sampler2D _NoiseTex;fixed _NoiseScaleX, _NoiseScaleY;fixed _NoiseSpeedX, _NoiseSpeedY;fixed _NoiseBrightOffset;fixed _NoiseFalloff;float _MirrorRange, _MirrorAlpha, _MirrorFadeAlpha;float3 n, p; // 镜面法线,镜面任意点v2f vert_normal (appdata v) {v2f o;o.wPos = mul(unity_ObjectToWorld, v.vertex).xyz;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = v.uv;return o;}fixed4 frag_normal (v2f i) : SV_Target {float3 dir = i.wPos.xyz - p;                // 平面与插值点的指向half d = dot(dir, n);                       // 与反向镜面的距离if (d < 0) discard;                         // 如果平面背面,那就丢弃return tex2D(_MainTex, i.uv);}v2f_m vert_mirror (appdata v) {v2f_m o;o.wPos = mul(unity_ObjectToWorld, v.vertex);float3 nn = -n;                 // 法线反向float3 dp = o.wPos.xyz - p;     // 平面点与世界空间的点的向量(即:从平面的点指向世界空间点的方向)half nd = dot(n, dp);           // 计算出点与平面的垂直距离o.wPos.xyz += nn * (nd * 2);    // 将垂直距离反向2倍的距离,就是镜像的位置o.vertex = mul(unity_MatrixVP, o.wPos);o.normal.xyz = UnityObjectToWorldNormal(v.normal);fixed t = nd / _MirrorRange;       // 将位置与镜面最大范围比利作为fade alpha的插值系数fixed a = lerp(_MirrorAlpha, _MirrorAlpha * _MirrorFadeAlpha, t);o.normal.w = a;     // 透明度我们存于o.normal.wo.wPos.w = nd;      // 距离存于o.wPos.wo.uv = v.uv;return o;}fixed4 frag_mirror (v2f_m i) : SV_Target {if (i.wPos.w > _MirrorRange) discard;       // 超过镜像范围也丢弃if (i.normal.w <= 0) discard;               // 透明度为0丢弃float3 dir = i.wPos.xyz - p;                // 平面与插值点的指向half d = dot(dir, n);                       // 与反向镜面的距离if (d > 0) discard;                         // 如果超过了平面,那就丢弃fixed2 ouvxy = fixed2( // 噪点图采样,用于主纹理的UV偏移的tex2D(_NoiseTex, i.uv + fixed2(_Time.x * _NoiseSpeedX, 0)).r,tex2D(_NoiseTex, i.uv + fixed2(0, _Time.x * _NoiseSpeedY)).r);ouvxy -= _NoiseBrightOffset; // 0~1 to ==> -_NoiseBrightOffset~ 1 - _NoiseBrightOffsetouvxy *= fixed2(_NoiseScaleX, _NoiseScaleY);    // 扰动放大系数float scale = i.wPos.w / _MirrorRange;          // 用距离来作为扰动衰减scale = lerp(scale, 1, (1 - _NoiseFalloff));    // 距离越近扰动越是衰减(即:与镜面距离越近,基本是不扰动的,所以我们可以看到边缘与镜面的像素是吻合的)ouvxy *= scale;fixed4 col = tex2D(_MainTex, i.uv + ouvxy);     // 加上扰动UV后再采样主纹理return fixed4(col.rgb, i.normal.w);}ENDCGSubShader {Tags { "Queue"="Geometry+2" "RenderType"="Opaque" }Pass {Cull frontZTest AlwaysZWrite OffBlend SrcAlpha OneMinusSrcAlphaStencil {Ref 1Comp Equal}CGPROGRAM#pragma vertex vert_mirror#pragma fragment frag_mirrorENDCG}Pass {CGPROGRAM#pragma vertex vert_normal#pragma fragment frag_normalENDCG}}
}

Source Project

TestShaderToy_NoiseAndMirror 提取码: j1kh 复制这段内容后打开百度网盘手机App,操作更方便哦

打开:PerlinNoiseMirror.unity 场景即可

(今天要去探亲,我就过几天再回来学习shader,然后再博客)

Unity Shader - 实现类似镜面反射、水面扰动效果相关推荐

  1. 着色器编程_unity中的基础纹理,使用Unity Shader实现基础纹理的渲染效果

    学习通过使用Unity Shader实现基础纹理的渲染效果 目录 学习通过使用Unity Shader实现基础纹理的渲染效果 问1:详细描述一下漫反射纹理.高度纹理.法线纹理.渐变纹理和遮罩纹理? 问 ...

  2. Unity Shader深度相关知识总结与效果实现

    鸣谢:puppet_master (VIA CSDN)贡献此文 前言 前言废话依旧比较多,感觉我是个写游戏体验评测的,233.最近想起了<恶灵附身>这款游戏的几个效果: <恶灵附身& ...

  3. 如何用Unity Shader制作类似《炉石传说》卡牌的动态效果?

    此篇为鄙人在卡牌项目中,尝试模仿<炉石传说>卡面特效所制作的特效Shader总结回顾,几经修改,最终成为了现在的样子,因为使用简单,效果明显,虽然距离<炉石传说>的卡面特效还有 ...

  4. Unity Shader 实现简单的压扁效果

    有点累啊,一个CoverMap搞了一周多,还是太嫩了,还有好多东西等着我去学呢,今天就写个简单的东西吧--一个把模型压扁的效果,参考博客Unity Shader - 一些玩具Shader.话不多说,先 ...

  5. Unity Shader学习案例一: 流光效果

    Unity Shader Lab新手宝典简单Shader案例一:流光效果 + 相关基础知识说明 Shader "Samples/Light Flow"//shader名称 {Pro ...

  6. Unity Shader学习笔记/Urp/水墨风效果

    实现简易的水墨风效果大致分为三部分: 1.将原始的rgb贴图转化为灰度图 float4 baseMap = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN ...

  7. Unity Shader实现PPT 30多种切换效果

    目录 原文 效果 Unity代码 00基础工具 Tools.cginc 01Fade 淡入淡出 02Push 推入 03Fade 擦除 04Split 分割 Unity工程 原文 原文 是用 GLSL ...

  8. unity shader 入门 全透明与半透明效果实现

    片元函数的fixed4类型的返回值的第4位即为阿尔法值,0代表完全不显示(透明),1代表完全显示.中间的数值代表半透明.但只修改这个值是不能直接修改透明度的,因为还要对队列等进行修改. 本文介绍透明度 ...

  9. 【Unity Shader】渲染纹理实现镜子效果

    1 基本概念 1.1 什么是渲染到纹理? 全称是Render To Texture,<入门精要>好像又把渲染目标纹理,即Render Target Texture也叫做RTT,但我认为&l ...

最新文章

  1. physx选择显卡还是cpu_工控机如何选购cpu,工控机cpu选择盒装好还是散装好
  2. 如何设置采购收货直接转到供应商库存?
  3. spring aop切面中获取代理bean的名字以及bean
  4. 初识前端——个人总结
  5. 以太网交换机与路由—Vecloud微云
  6. 技术开发人员适应其他部门提需求的一个经验
  7. QEventLoop的简单使用(一)
  8. Linux下最简单的修改文件名后缀的命令行技巧
  9. 揭秘 | 小米最新款12PRO智能动态刷新率技术原理
  10. Cloud一分钟 | Gartner发布2018年第二季度全球服务器市场报告;中信银行联合腾讯云推出手机银行智能语音产品...
  11. ArcGIS Engine开发:框架/结构+对象库
  12. 查看tensor的形状,行列大小
  13. php drive mssql,wamp下对MS SQLSERVER的连接配置,PHP+THINKPHP5通过
  14. [面试] 算法(七)—— 逆序输出链表
  15. Redis 6.0 源码阅读笔记(2) -- Redis 多线程原理
  16. C6678/C6657+ZYNQ/K7/A7 FPGA+AD+北斗的软硬件设计方案
  17. 手机PDF文档如何解密去除不能编辑的限制?
  18. Protobuf使用手册--中文版
  19. Zookeeper数据同步流程
  20. 噪音分贝测试软件在线,分贝测试(在线分贝测试仪)

热门文章

  1. Arcgis --- 坡向批处理
  2. 差分——(2)二维差分
  3. ardupilot更新油门组合值
  4. 一体化闸门控制机如何使用
  5. springsecurity投票器
  6. 鸿蒙手机如何录屏,安卓手机如何屏幕录制视屏?手机视频录制方法
  7. LVM逻辑卷组的管理
  8. (Loadrunner)Abnormal termination, caused by mdrv process termination.(转)
  9. 又谈SQL-to-SQL翻译器
  10. java application.xml_第4章 零XML配置的Spring Boot Application