效果图:点击地面产生坑!!!

总体思路:
1.用一张RT 标记人走过的痕迹
2.将痕迹映射到雪地上
3.雪地上痕迹凹陷 混合
4. 凹陷和突起,阴影,法线。。。。。。等(未做)

第一步:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Snow : MonoBehaviour
{public RenderTexture rt;// 为了混合 rt,但不能直接用rt,所以先用rt0接收中转RenderTexture rt0;// 画笔public Texture drawImg;// 清屏显示public Texture defaultImg;public Camera mainCam;// 用于混合rt和 画 的材质public Material drawMat;void Start(){mainCam = Camera.main.GetComponent<Camera>();GetComponent<Renderer>().material.mainTexture = rt;DrawDefault();rt0 = new RenderTexture(rt.width, rt.height, 32, rt.graphicsFormat);rt0.Create();}private void DrawDefault(){RenderTexture.active = rt;GL.PushMatrix();GL.LoadPixelMatrix(0, rt.width,  rt.height, 0);Rect rect = new Rect(0, 0, rt.width, rt.height);Graphics.DrawTexture(rect, defaultImg);GL.PopMatrix();RenderTexture.active = null;}private void Draw(int x,int y){Graphics.Blit(rt, rt0);RenderTexture.active = rt;GL.PushMatrix();// 屏幕空间的表现GL.LoadPixelMatrix(0, rt.width, rt.height, 0);// 绘制到中心点x -= (int)(drawImg.width * 0.5f);y -= (int)(drawImg.height * 0.5f);Rect rect = new Rect(x, y, drawImg.width, drawImg.height);Vector4 SourceUV = new Vector4();SourceUV.x = rect.x / rt.width;SourceUV.y = 1 - rect.y / rt.height;SourceUV.z = rect.width / rt.width;SourceUV.w = rect.height / rt.width;SourceUV.y -= SourceUV.w;drawMat.SetTexture("_SourceTex", rt0);drawMat.SetVector("_SourceUV", SourceUV);// 此处如果不用drawMat混合,产生的痕迹会被覆盖掉//Graphics.DrawTexture(rect, drawImg);Graphics.DrawTexture(rect, drawImg,drawMat);GL.PopMatrix();RenderTexture.active = null;}// Update is called once per framevoid Update(){if (Input.GetMouseButton(0)){Debug.LogError("按下");Ray ray = mainCam.ScreenPointToRay(Input.mousePosition);RaycastHit hit;//多加一个参数 限制射线检测的 距离//Physics.Raycast(ray, out hit,0.01f)if (Physics.Raycast(ray,out hit)){                int x = (int)(hit.textureCoord.x * rt.width);// (0,0)点在左上角, 变换到左下角  只变动yint y = (int)(rt.height -hit.textureCoord.y * rt.height);Debug.LogError("点击到" + hit.transform.name + " x="+ x+" y="+y);Draw(x, y);}}}
}

第二步:地面的shader,点击地面后,地面shader的顶点偏移,产生“凹陷”的效果
注意理解tex2Dlod函数的意义

Shader "Unlit/snow"
{Properties{_MainTex ("Texture", 2D) = "white" {}}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f{float2 uv : TEXCOORD0;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;v2f vert (appdata v){v2f o;o.uv = TRANSFORM_TEX(v.uv, _MainTex);// 此函数在 顶点着色器,片元着色器中  都能使用, v.vertex.xyz += tex2Dlod(_MainTex,float4(o.uv,0,0)).r * v.normal;o.vertex = UnityObjectToClipPos(v.vertex);               return o;}fixed4 frag (v2f i) : SV_Target{// sample the texturefixed4 col = tex2D(_MainTex, i.uv);return col;}ENDCG}}
}

第三步:能产生凹凸的效果,但是由于顶点数量有限,所以凹凸效果太突兀(可以用曲面细分来优化)。。。
画笔出的痕迹被自己覆盖,所以混合一下,保证是纯色

Shader "Unlit/draw"
{Properties{_MainTex ("Texture", 2D) = "white" {}_SourceTex("SourceTex", 2D) = "white" {}_SourceUV("SourceUV",Vector) = (0,0,0,0)}SubShader{Tags { "RenderType"="Transparent" }LOD 100Pass{ZWrite OffBlend SrcAlpha OneMinusSrcAlphaCGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;float4 vertex : SV_POSITION;float2 sourceUV : TEXCOORD1;};sampler2D _MainTex;float4 _MainTex_ST;sampler2D _SourceTex;float4 _SourceTex_ST;Vector _SourceUV;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.sourceUV = TRANSFORM_TEX(_SourceUV, _SourceTex);return o;}fixed4 frag (v2f i) : SV_Target{                fixed4 col = tex2D(_MainTex, i.uv);fixed4 sCol = tex2D(_SourceTex, i.sourceUV);fixed4 endCol = min(col, sCol);return endCol;}ENDCG}}
}

以上只是宏观上能实现效果,是这么个意思,(美术功底不好不会作图的请脑补一下==),阉割的不能再阉割了。。。。。。 迫于没有图片资源,就不上传效果动图了。
参考:
雪地脚印1

-------------------------分割线--------------------------------------------------------


升级版:

使用曲面细分效果:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;public class DrawWithMind : MonoBehaviour
{[SerializeField]public RenderTexture rt;private Camera mainCam;public Material drawMat;Material snowMat;[Range(0, 100)]public float _BrushStrength;[Range(0, 1000)]public float _BrushSize;void Start(){mainCam = Camera.main.GetComponent<Camera>();snowMat = GetComponent<MeshRenderer>().material;rt = new RenderTexture(1024, 1024, 0, GraphicsFormat.R32G32B32A32_SFloat);snowMat.SetTexture("_MaskTex", rt);}Vector4 vec = new Vector4();// Update is called once per framevoid Update(){if (Input.GetMouseButton(0)){Ray ray = mainCam.ScreenPointToRay(Input.mousePosition);if (Physics.Raycast(ray, out var hit)){vec.x = hit.textureCoord.x;vec.y = hit.textureCoord.y;Debug.LogError("hit name =" + hit.transform.name + " pos = " + hit.textureCoord.x + " , " + hit.textureCoord.y + " u=" + vec.x + " v=" + vec.y);drawMat.SetVector("_HitUV", vec);//drawMat.SetFloat("_Strength", _BrushStrength);//drawMat.SetFloat("_powSize", _BrushSize);RenderTexture temp = RenderTexture.GetTemporary(rt.width, rt.height, 0, rt.format);Graphics.Blit(rt, temp);Graphics.Blit(temp, rt, drawMat);RenderTexture.ReleaseTemporary(temp);}}}
}
Shader "Unlit/DrawLine"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Color("LineColor",Color) = (0,1,0,1)[hideIninspector]_HitUV("HitUV",vector) = (0,0,0,0)_powSize("pow size",Range(0,1000)) = 500_Strength("Strength",Range(0,60)) = 10}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f{float2 uv : TEXCOORD0;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float4 _Color;float _powSize;float _Strength;
vector _HitUV;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);float draw = pow(saturate(1 - distance(i.uv,_HitUV.xy)),500/_powSize);fixed4 drawCol = _Color * (draw * _Strength);//col *= draw;return drawCol+ col;}ENDCG}}
}
Shader "Unlit/SnowShader"
{Properties{_Color("Color", Color) = (1,1,1,1)_BaceTex ("BaceTex", 2D) = "white" {}_SnowColor("SnowColor", Color) = (1,1,1,1)_SnowTex("SnowTex", 2D) = "white" {}_MaskTex("mask tex",2D) = "white"{}_aaaa("TesselationNum",Range(0.1,100)) = 0.145299_Displacement("_Displacement",Range(0.1,100)) = 0.5}SubShader{Tags { "RenderType" = "Opaque" }LOD 100Pass{CGPROGRAM#pragma hull hull#pragma domain domain#pragma vertex tessvert#pragma fragment frag#include "UnityCG.cginc"
#include "Tessellation.cginc"
#pragma multi_compile_fwdbase_fullshadows
#pragma only_renderers d3d9 d3d11 glcore gles
#pragma target 4.6sampler2D _BaceTex,_SnowTex,_MaskTex;float4 _MaskTex_ST ;float _aaaa;float4 _Color, _SnowColor;float _Displacement;struct VertexInput{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;float4 tangent : TANGENT;};struct VertexOutput{float2 uv : TEXCOORD0;float4 pos : SV_POSITION;float3 normal_dir : TEXCOORD1;float2 uv_bace : TEXCOORD2;float2 uv_snow : TEXCOORD3;};VertexOutput vert(VertexInput v){VertexOutput o = (VertexInput)0;o.uv = v.uv;o.normal_dir = UnityObjectToWorldNormal(v.normal);float4 _MaskTex_var = tex2Dlod(_MaskTex, float4(o.uv, 0, 0));float4 _BaceTex_var = tex2Dlod(_BaceTex, float4(o.uv, 0, 0));v.vertex.xyz -= v.normal * (_BaceTex_var.r - 0.7 + _MaskTex_var.r) * _Displacement;o.pos = UnityObjectToClipPos(v.vertex);return o;}#ifdef UNITY_CAN_COMPILE_TESSELLATIONstruct TessVertex {float4 vertex : INTERNALTESSPOS;float3 normal : NORMAL;float4 tangent : TANGENT;float2 uv : TEXCOORD0;};struct OutputPatchConstant {float edge[3] : SV_TessFactor;float inside : SV_InsideTessFactor;float3 vTangent[4] : TANGENT;float2 vUV[4] : TEXCOORD;float3 vTanUCorner[4] : TANUCORNER;float3 vTanVCorner[4] : TANVCORNER;float3 vCWts :TANWELIGHTS;};//将顶点里的处理 传入到曲面细分中TessVertex tessvert(VertexInput v) {TessVertex o;o.vertex = v.vertex;o.normal = v.normal;o.tangent = v.tangent;o.uv = v.uv;return o;}// 曲面细分的  远近控制(近处细分,远处不细分)float4 Tessellation(TessVertex v, TessVertex v1, TessVertex v2) {float minDist = 1.0;float maxDist = 25.0;return UnityDistanceBasedTess(v.vertex, v1.vertex, v2.vertex, minDist, maxDist, _aaaa);}// 曲面细分的强度控制float Tessellation(TessVertex v){return _aaaa;}// InputPatch<TessVertex, 3> 表示输入的 patch 为3个 TessVertex 数据,对应三角形 patch 的3个顶点OutputPatchConstant hullconst(InputPatch<TessVertex, 3> v) {OutputPatchConstant o = (OutputPatchConstant)0;float4 ts = Tessellation(v[0], v[1], v[2]);// 每个边分成几段  o.edge[0] = ts.x;o.edge[1] = ts.y;o.edge[2] = ts.z;// 意味着在三角形内部加入三个新的顶点,但是这个函数并不会创建任何新的顶点,只是会计算出所有新的顶点的重心坐标。o.inside = ts.w;return o;}[domain("tri")] // 定义特性  输入进hull shader的图元是三角形[partitioning("fractional_odd")]// 决定分割方式[outputtopology("triangle_cw")]//决定图元的朝向[patchconstantfunc("hullconst")]// 补丁常量缓存函数名[outputcontrolpoints(3)]//决定三个控制点TessVertex hull(InputPatch<TessVertex, 3> v, uint id : SV_OutputControlPointID) {return v[id];}[domain("tri")]VertexOutput domain(OutputPatchConstant tessFactors, const OutputPatch<TessVertex, 3> vi, float3 bary : SV_DomainLocation){VertexInput v = (VertexInput)0;v.vertex = vi[0].vertex * bary.x + vi[1].vertex * bary.y + vi[2].vertex * bary.z;v.normal = vi[0].normal * bary.x + vi[1].normal * bary.y + vi[2].normal * bary.z;v.tangent = vi[0].tangent * bary.x + vi[1].tangent * bary.y + vi[2].tangent * bary.z;v.uv = vi[0].uv * bary.x + vi[1].uv * bary.y + vi[2].uv * bary.z;VertexOutput o = vert(v);return o;}
#endiffixed4 frag (VertexOutput i) : SV_Target{               float4 _MaskTex_var = tex2D(_MaskTex, TRANSFORM_TEX(i.uv,_MaskTex));float4 BaceTex_var = tex2D(_BaceTex, i.uv) * _Color;float4 SnowTex_var = tex2D(_SnowTex, i.uv) * _SnowColor;float4 c = lerp(BaceTex_var, SnowTex_var, _MaskTex_var.r);float3 finalColor = c.xyz;return fixed4(finalColor,1);}ENDCG}}
}

shader实现雪地中的脚印相关推荐

  1. UE | Shader | 在UE中添加全局Shader

    UE | Shader | 在UE中添加全局Shader .usf(Unreal Shader Files) 和.usf的使用 .usf文件编写 .usf文件绑定.cpp和.h文件 添加控制台变量 D ...

  2. 【Unity Shader】Unity中利用GrabPass实现玻璃效果

    <入门精要>中模拟玻璃是用了Unity里的一个特殊的Pass来实现的,这个Pass就是GrabPass,比起上一篇博客实现镜子的方法,这个方法我认为相对复杂,因此在实现之前需要对GrabP ...

  3. shader编程-二维空间中使用矩阵实现物体的旋转、缩放、平移变换(WebGL-Shader开发基础03)

    shader编程-二维空间中使用矩阵实现物体的旋转.缩放.平移变换 1. 变换前物体的绘制 2. 物体旋转的实现 3. 物体缩放的实现 4. 物体平移的实现 5. 平移与缩放另外一种实现方式 6. 所 ...

  4. shader graph_Shader Graph中的自定义照明:在2019年扩展图形

    shader graph With the release of Unity Editor 2019.1, the Shader Graph package officially came out o ...

  5. 【Unity Shader】Unity中阴影映射标准制作流程

    前半部分的基于图片的实时阴影技术是百人计划的前半部分总结,后面的Unity中的实现过程是<入门精要>中的实现. 1 基于图片的实时阴影技术 这里的"基于图片"指阴影生成 ...

  6. unity shader立方体纹理中的反射以及折射效果的实现

    反射: 如果不考虑反射效果的话,在场景中的问题的镜面表面的效果应该是用表面的法线对立方体纹理进行采样得到该点的颜色. 所以我们进行反射的计算的时候,只需要求得反射方向,再用反射的方向对立方体纹理进行采 ...

  7. 【Unity Shader】Unity中阴影走样的解决方案

    走样问题出现在两个地方: 初始采样:获得shadowmap的过程 重采样:从摄像机视角对Shadowmap进行重采样 这两个阶段都会产生走样问题. 1 初始采样-透视走样 1.1 形成原因 这里的情况 ...

  8. 学习笔记28(凹凸贴图,法线贴图,位移贴图)

    为突出物体表面细节的三个贴图:bump/Normal 和 displacement 对于前俩其实本质上是差不多的,一个是存储高度差信息,一个是存储法线信息,就算是高度差,也是经过计算得到高度变化后的法 ...

  9. unity 线程断点时卡机_Compute Shader在Unity和UE4中的应用

    该文档为学习文档,如有错误欢迎指正. 1. D3D11 Compute Shader概述 Compute Shader 是一个通用计算 Stage.它利用了GPU的并行处理器,实现大量线程并发执行.它 ...

最新文章

  1. 2022-2028年中国工业环保产业投资分析及前景预测报告
  2. CSS布局--head区的其他设置
  3. Java面试题之类的静态代码块和静态属性等的加载顺序
  4. 使用Yeoman定制前端脚手架
  5. 场景感知:CNN方法对三维重建/slam/实时定位的一些Base改进
  6. 轻而易举地激发变革:开放的方法
  7. STM32工作笔记0042---认识三极管的集电极,发射极,基极
  8. oracle中lag()函数和lead()函数的用法(图文)
  9. 关于计算机实验的英语作文,关于实验的英语作文
  10. oracle10gr2安装教程,Solaris10安装Oracle10gR2时的注意事项
  11. AS函数的一些特殊应用
  12. paip.日志中文编码原理问题本质解决python
  13. 2019年11月中华人民共和国县以上行政区划代码(用于身份证前六位判断户籍所在地)
  14. 数据分析——泰坦尼克号乘客数据集
  15. RFC2544性能测试简介
  16. IE浏览器无法打开网页
  17. mysql大于等于between比较_MySQL范围查询优化,Between与大于等于对比及优化
  18. 使用Apple设备的看过来,你的Apple账户为什么莫名其妙地被扣款!
  19. 数组的正负数分割排序
  20. 分享 75 个精选的 JavaSript 基础知识点(中)

热门文章

  1. Camtasia2020mac喀秋莎中文免费密钥
  2. 计算机控制技术第二章,计算机控制技术第二章习题答案整理及详解(修改版SK).doc...
  3. php防注入,表单提交值转义
  4. 【太湖美---无锡】
  5. 股票常识|股票基础知识
  6. 密码管理软件:Keepass2Android-1.09a-r3
  7. 推荐20位活跃在GitHub上的国内技术大牛
  8. 学习英语的好网站推荐
  9. Iframe嵌入页面大小边框和调整
  10. 人脸识别系列之人脸检测--训练基于肤色特征的检测