卜若的代码笔记-unityshader系列-第十七章:Shader练习.遮罩(Shader采样Image的Sprite)
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)相关推荐
- 卜若的代码笔记-unityshader系列-第八章:复杂Mesh
这一章我们讲复杂的mesh为下一章的材质准备一些材料 8.1 创建一个矩形面片 本质就是绘制两个三角形面片,如图8-1.其代码有注释了就不做太多解释了. public virtual Mesh cre ...
- 卜若的代码笔记-webgl系列-第三章:几何渲染Rendering Geometry
1 在webgl里面表述几何体最关键的两种数据类型: 顶点和索引(vertices and indices.) 1.1 顶点是什么? 顶点定义了3D对象的角点,每一个顶点由三个元素组成x,y,z. 在 ...
- 卜若的代码笔记-数据结构系列-第三章:链表-最简单的线性表:单链表
1.一个最简单的线性表 1.1单链表的特征: a.链表无法通过索引获取链表元素,只能从头开始一个一个的后继去找. b.链表无法找到父节点 1.2结构: 1.3 实现 我们来讨论一下它的时间复杂度: 1 ...
- 卜若的代码笔记-数据结构系列-第十二章:栈三.链栈
1.太简单了,不介绍了,直接贴代码,有问题请看10,11,章 //测试代码public static void main(String[] args) throws IOException {Link ...
- 卜若的代码笔记-matlab系列-matlab基础教程-第二章:静态变量
persistent value; if isempty(value)value=20; endvalue=value+1;y=value; 注意,这段代码只允许定义在function里面
- 卜若的代码笔记-算法系列-第2个算法案例分析:HHM预测模型分析
1. 关于这个模型就去看 https://www.cnblogs.com/pinard/p/6991852.html 这篇博客吧...我主要是将这个它的那个案例画了一张图 案例代码: package ...
- 卜若的代码笔记-python系列-神经网络篇-第十四章:基于keras框架的男女性别识别
1.我们来看一下整个网络的实现构架 以下显示面板利用的是keras的summary函数 (None, 65536) (None, 512) ______________________________ ...
- 卜若的代码笔记-数据结构系列-第十章:栈一.顺序栈(数组栈)
1.栈有两种写法,一种是以数组为躯干的顺序栈,一种是以链表为躯干的链式栈. 1.1栈的操作 1.1.1 出栈pop()函数 允许栈出,栈出之后,顶数据有移除操作. 时间复杂度o(1) 1.1.2 入栈 ...
- 卜若的代码笔记系列-unity系列-第一章:json-5001
1.该系列算的上是unity的网络应用,嗯,不讲基础的,要基础的网上太多了. 2.服务器请参考本人的sringboot系列的讲解 3.正文: unity提供了一个类 JsonUtility 最常用的是 ...
最新文章
- 图解负载均衡 LVS、Nginx及HAProxy--云平台技术栈14
- 用互联网思维做产品的7个要…
- 王者归来!iPhone 13热销立功 苹果重夺销量全球第一
- 使用反射获得jar包中的类、方法、参数、返回值类型,然后动态加载jar包运行方法
- mac可以写linux的进程,macOS系统上读写Linux的ext4分区方法
- Crawler 爬虫
- cgroup的学习(一)——what cgroup?
- Python零基础福利来了!
- python统计图的三层结构设计_中大型LABVIEW软件三层设计架构(带图片目录完整版)...
- 中登TA、自TA、分TA
- Servlet-JSP-课堂笔记
- 短信验证码收不到了怎么办?
- JAVA网络协同办公自动化
- already opened by ClassLoader
- 南开大学教授“段子手式”简介,网友:笑着笑着突然“破防”了!
- 往word表中写数据
- Angular实现数据双向绑定
- 行转换html,块级、行内、行内元素相互转换
- JavaSwing_1.1: FlowLayout(流式布局)
- php实现抠图,如何使用php代码实现印章的抠图(代码)