1.遮罩的意义,就是让某个颜色的部分透明,其他的不透明。

实现思路很简单,但如果你是从这个系列一步一步上学过来的,那肯定很简单啦

1.1我们先定义一个标准Shader,然后慢慢改

Shader "Custom/Mask001" {Properties {_Color ("Color", Color) = (1,1,1,1)_MainTex ("Albedo (RGB)", 2D) = "white" {}_Glossiness ("Smoothness", Range(0,1)) = 0.5_Metallic ("Metallic", Range(0,1)) = 0.0}SubShader {Tags { "RenderType"="Opaque" }LOD 200CGPROGRAM// Physically based Standard lighting model, and enable shadows on all light types#pragma surface surf Standard fullforwardshadows// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0sampler2D _MainTex;struct Input {float2 uv_MainTex;};half _Glossiness;half _Metallic;fixed4 _Color;// 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)void surf (Input IN, inout SurfaceOutputStandard o) {// Albedo comes from a texture tinted by colorfixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;o.Albedo = c.rgb;// Metallic and smoothness come from slider variableso.Metallic = _Metallic;o.Smoothness = _Glossiness;o.Alpha = c.a;}ENDCG}FallBack "Diffuse"
}

关于surf函数,起点,和终点的问题,在前面有过介绍。但是这里我们不喜欢用这玩意。删掉。我们还是两个过程

1.顶点着色

2.片元着色

1.2 我们先改出一个简单的渲染流水线。

Shader "Custom/Mask001" {Properties {//遮罩图_MainTex ("Albedo (RGB)", 2D) = "white" {}}SubShader{Tags { "RenderType" = "Opaque" }LOD 200Pass{CGPROGRAM//定义顶点着色器#pragma vertex vertex//定义片元着色器#pragma fragment fragment// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0#include "UnityCG.cginc"#include "Lighting.cginc"//CG变量的遮罩图,你可以调用这个变量的数据,并通过前面章节提供的函数进行采样sampler2D _MainTex;//来自于cpu的数据模型struct fromCpu {//传入的mesh的基本组成:顶点和UV};//来自顶点着色器的数据模型struct v2f {//传入的mesh的基本组成:顶点和UV};//运行顶点着色器,输入data数据,输出计算后的数据。注意流水线v2f vertex(fromCpu data) {}//运行片元着色器,返回最终计算出来的颜色数据,输入是顶点着色器的输出。fixed4 fragment(v2f data) : SV_Target{}ENDCG}}FallBack "Diffuse"
}

1.3我们改出了这个流水线后,直接返回一个简单的颜色作为测试

1.我们得思考从缓存中将什么数据丢到流水线里面?

mesh的顶点

mesh的uv

Shader "Custom/Mask001" {Properties {//遮罩图_MainTex ("Albedo (RGB)", 2D) = "white" {}}SubShader{Tags { "RenderType" = "Opaque" }LOD 200Pass{CGPROGRAM//定义顶点着色器#pragma vertex vertex//定义片元着色器#pragma fragment fragment// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0#include "UnityCG.cginc"#include "Lighting.cginc"//CG变量的遮罩图,你可以调用这个变量的数据,并通过前面章节提供的函数进行采样sampler2D _MainTex;//来自于cpu的数据模型struct fromCpu {//传入的mesh的基本组成:顶点和UVfixed4 vertex : POSITION;float2 uv:TEXCOORD0;};//来自顶点着色器的数据模型struct v2f {//传入的mesh的基本组成:顶点和UVfixed4 vertex : POSITION;float2 uv:TEXCOORD0;};//运行顶点着色器,输入data数据,输出计算后的数据。注意流水线v2f vertex(fromCpu data) {v2f o;//转到世界坐标o.vertex = UnityObjectToClipPos(data.vertex);return o;}//运行片元着色器,返回最终计算出来的颜色数据,输入是顶点着色器的输出。fixed4 fragment(v2f data) : SV_Target{return fixed4(0,1,0,1);}ENDCG}}FallBack "Diffuse"
}

此时的效果如下:

1.4 我们希望采样一张图片

既然是采样图片,那你就得有uv,uv存放在哪?存放在内存里,也就是vertex着色操作里面输入的fromCpu的结构体。

你得把它传过来!!!,然后用tex2D(_MainTex,data.uv)进行采样,返回就可以啦!

Shader "Custom/Mask001" {Properties {//遮罩图_MainTex("Texture", 2D) = "white" {}}SubShader{Tags { "RenderType" = "Opaque" }LOD 200Pass{CGPROGRAM//定义顶点着色器#pragma vertex vertex//定义片元着色器#pragma fragment fragment// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0#include "UnityCG.cginc"#include "Lighting.cginc"//CG变量的遮罩图,你可以调用这个变量的数据,并通过前面章节提供的函数进行采样sampler2D _MainTex;//来自于cpu的数据模型struct fromCpu {//传入的mesh的基本组成:顶点和UVfixed4 vertex : POSITION;float2 uv:TEXCOORD0;};//来自顶点着色器的数据模型struct v2f {//传入的mesh的基本组成:顶点和UVfixed4 vertex : POSITION;float2 uv:TEXCOORD0;};//运行顶点着色器,输入data数据,输出计算后的数据。注意流水线v2f vertex(fromCpu data) {v2f o;//转到世界坐标o.vertex = UnityObjectToClipPos(data.vertex);o.uv = data.uv;return o;}half4 c1;//运行片元着色器,返回最终计算出来的颜色数据,输入是顶点着色器的输出。fixed4 fragment(v2f data) : SV_Target{c1 = tex2D(_MainTex,data.uv);return c1;}ENDCG}}FallBack "Diffuse"
}

现在展示的效果如下:

1.5 现在,问题来了,我们要采样的数据是UI的Image的Sprite数据

我们定义的片元操作如下:

我们给_MainTex赋值的贴图如下:

此时Mesh显示出来的效果居然是UI的Image的Sprite

也就是:

按道理不应该是,比如一个cube这种:

但是,如果我将Image的Sprite设置为空,显示效果如下:

然后经过我们种种测试之后,真相只有一个:

在Image的材质的2D采样中,当你对名称为“_MainTex”进行采样时,采样数据优先采样Image的Sprite!

就是上面这个。

然后,我们来验证,此时的效果

当我定义名称为_MainTex的属性后,我们的UI效果:

当我定义_MainTex1的属性后:

结果则:

所以,我们可以采样到当前UI的Sprite的图像 。

而能够采样到这个图像,那么你在片元里面就能够修饰这个图像的数据,也就是最终的遮罩!

代码如下:

Shader "Custom/Mask001" {Properties {_MainTex("ts", 2D) = "white" {}_Mask("Mask",2D) = "white"{}}SubShader{Tags {"Queue" = "Transparent" }LOD 200Pass{//开启混合Blend SrcAlpha OneMinusSrcAlphaCGPROGRAM//定义顶点着色器#pragma vertex vertex//定义片元着色器#pragma fragment fragment// Use shader model 3.0 target, to get nicer looking lighting#pragma target 3.0#include "UnityCG.cginc"#include "Lighting.cginc"//CG变量的遮罩图,你可以调用这个变量的数据,并通过前面章节提供的函数进行采样sampler2D _Mask;sampler2D _MainTex;//来自于cpu的数据模型struct fromCpu {//传入的mesh的基本组成:顶点和UVfixed4 vertex : POSITION;float2 uv:TEXCOORD0;float4 color : COLOR;};//来自顶点着色器的数据模型struct v2f {//传入的mesh的基本组成:顶点和UVfixed4 vertex : POSITION;float2 uv:TEXCOORD0;float4 color : COLOR;};//运行顶点着色器,输入data数据,输出计算后的数据。注意流水线v2f vertex(fromCpu data) {v2f o;//转到世界坐标o.vertex = UnityObjectToClipPos(data.vertex);o.uv = data.uv;//o.color = data.color;return o;}half4 c1;half4 c2;//运行片元着色器,返回最终计算出来的颜色数据,输入是顶点着色器的输出。fixed4 fragment(v2f data) : SV_Target{c1 = tex2D(_MainTex,data.uv);c2 = tex2D(_Mask, data.uv);c2.a = c2.r;return c1*c2;}ENDCG}}FallBack "Diffuse"
}

遮罩图如下:

对于ts来说本身是没有意义的,所以,我们可以隐藏掉。可以使用

[PerRendererData]

关键字:

然后,贴图选项里面:

就只有遮罩图了。

卜若的代码笔记-unityshader系列-第十七章:Shader练习.遮罩(Shader采样Image的Sprite)相关推荐

  1. 卜若的代码笔记-unityshader系列-第八章:复杂Mesh

    这一章我们讲复杂的mesh为下一章的材质准备一些材料 8.1 创建一个矩形面片 本质就是绘制两个三角形面片,如图8-1.其代码有注释了就不做太多解释了. public virtual Mesh cre ...

  2. 卜若的代码笔记-webgl系列-第三章:几何渲染Rendering Geometry

    1 在webgl里面表述几何体最关键的两种数据类型: 顶点和索引(vertices and indices.) 1.1 顶点是什么? 顶点定义了3D对象的角点,每一个顶点由三个元素组成x,y,z. 在 ...

  3. 卜若的代码笔记-数据结构系列-第三章:链表-最简单的线性表:单链表

    1.一个最简单的线性表 1.1单链表的特征: a.链表无法通过索引获取链表元素,只能从头开始一个一个的后继去找. b.链表无法找到父节点 1.2结构: 1.3 实现 我们来讨论一下它的时间复杂度: 1 ...

  4. 卜若的代码笔记-数据结构系列-第十二章:栈三.链栈

    1.太简单了,不介绍了,直接贴代码,有问题请看10,11,章 //测试代码public static void main(String[] args) throws IOException {Link ...

  5. 卜若的代码笔记-matlab系列-matlab基础教程-第二章:静态变量

    persistent value; if isempty(value)value=20; endvalue=value+1;y=value; 注意,这段代码只允许定义在function里面

  6. 卜若的代码笔记-算法系列-第2个算法案例分析:HHM预测模型分析

    1. 关于这个模型就去看 https://www.cnblogs.com/pinard/p/6991852.html 这篇博客吧...我主要是将这个它的那个案例画了一张图 案例代码: package ...

  7. 卜若的代码笔记-python系列-神经网络篇-第十四章:基于keras框架的男女性别识别

    1.我们来看一下整个网络的实现构架 以下显示面板利用的是keras的summary函数 (None, 65536) (None, 512) ______________________________ ...

  8. 卜若的代码笔记-数据结构系列-第十章:栈一.顺序栈(数组栈)

    1.栈有两种写法,一种是以数组为躯干的顺序栈,一种是以链表为躯干的链式栈. 1.1栈的操作 1.1.1 出栈pop()函数 允许栈出,栈出之后,顶数据有移除操作. 时间复杂度o(1) 1.1.2 入栈 ...

  9. 卜若的代码笔记系列-unity系列-第一章:json-5001

    1.该系列算的上是unity的网络应用,嗯,不讲基础的,要基础的网上太多了. 2.服务器请参考本人的sringboot系列的讲解 3.正文: unity提供了一个类 JsonUtility 最常用的是 ...

最新文章

  1. 图解负载均衡 LVS、Nginx及HAProxy--云平台技术栈14
  2. 用互联网思维做产品的7个要…
  3. 王者归来!iPhone 13热销立功 苹果重夺销量全球第一
  4. 使用反射获得jar包中的类、方法、参数、返回值类型,然后动态加载jar包运行方法
  5. mac可以写linux的进程,macOS系统上读写Linux的ext4分区方法
  6. Crawler 爬虫
  7. cgroup的学习(一)——what cgroup?
  8. Python零基础福利来了!
  9. python统计图的三层结构设计_中大型LABVIEW软件三层设计架构(带图片目录完整版)...
  10. 中登TA、自TA、分TA
  11. Servlet-JSP-课堂笔记
  12. 短信验证码收不到了怎么办?
  13. JAVA网络协同办公自动化
  14. already opened by ClassLoader
  15. 南开大学教授“段子手式”简介,网友:笑着笑着突然“破防”了!
  16. 往word表中写数据
  17. Angular实现数据双向绑定
  18. 行转换html,块级、行内、行内元素相互转换
  19. JavaSwing_1.1: FlowLayout(流式布局)
  20. php实现抠图,如何使用php代码实现印章的抠图(代码)

热门文章

  1. 基于工业5G路由器的智慧公厕无线联网解决方案
  2. 杭电计算机考研失败,2020杭电计算机考研感想
  3. 触摸屏GT9xx移植
  4. cad画不规则实体_cad画不规则曲线的方法步骤图
  5. csp计算机专业,中国计算机学会推出CSP非专业级别认证
  6. 2022年初级经济师考试测试题及答案
  7. ubuntu18.04安装英伟达驱动
  8. 【百度地图】城市中心点坐标
  9. c51语言1秒延时程序,KeilC51程序设计中几种精确延时方法
  10. 2012北京航空航天大学考研机试真题