当前位置:网站首页>Unity 使用一张贴图来控制材质主贴图的透明度
Unity 使用一张贴图来控制材质主贴图的透明度
2022-07-17 08:44:00 【humilezr】
最近有个需求:通过一张贴图的颜色值来控制材质主贴图的透明度。
先做一个注明:用来控制主贴图透明度的贴图,我们暂且称之为“Alpha贴图”;主贴图就叫“主贴图”。
首先,我们需要解决的是将Alpha贴图的颜色值转化成透明度;经过多方测试,最终采用了以下方法:1)比较像素点的r、g、b;2)假设r最大,则float val = r*权重+g+b;3)alpha = val/(权重+2)
直接上代码:
Shader "Custom/MainTexAlphaCtrl"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}//主贴图纹理
_AlphaTex("AlphaTexture",2D) = "white"{}//Alpha纹理
_BaseColor("Base Color",Color) = (1, 1, 1, 1)
_Weight("Weight",float) = 0//Alpha计算时的权重
[Toggle(_Reverse)] _Reverse("Reverse", float) = 0//是否取反,用于主贴图的透明度计算
}
SubShader
{
Tags { "RenderType" = "Transparent"}
LOD 100
Cull Off
//如果使用Alpha混合,需要关闭深度缓冲写入
ZWrite Off
//添加混合命令
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
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;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
sampler2D _AlphaTex;
float4 _MainTex_ST;
float4 _BaseColor;
float _Weight;
float _Reverse;
//原理:
// 1. 前置条件:1)单通道渲染,Unity内置了参数unity_StereoEyeIndex作为渲染左右眼的标志,
// unity_StereoEyeIndex = 0:渲染左眼画面;=1:渲染右眼画面。
// 2)纹理包含左右双目画面,如果纹理是单目画面,此方法不适用。
// 2. 当渲染左眼画面时,取纹理的0~0.5f(包含0.5f)范围;渲染右眼画面时,取纹理的0.5f(不包含0.5f)~1范围。
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
//将颜色值转化成透明度
float color2Alpha(fixed3 col)
{
float a = 0;
float val = 0;
//比较r、g、b三个值,得到最大值,如果r最大,则val = 4*r+g+b;
if (col.r > col.g)
{
if (col.r > col.b)
{
val = _Weight * col.r + col.g + col.b;
}
else
{
val = _Weight * col.b + col.g + col.r;
}
}
else
{
if (col.g > col.b)
{
val = _Weight * col.g + col.r + col.b;
}
else
{
val = _Weight * col.b + col.g + col.r;
}
}
//然后val除以(权重+2),得到最终alpha值
return val / (_Weight+2);
//return (col.r + col.g + col.b)/3;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 main_col = tex2D(_MainTex, i.uv) * _BaseColor;
fixed3 alpha_col = tex2D(_AlphaTex, i.uv).rgb;
if (_Reverse == 0)
{
return fixed4(main_col.rgb, main_col.a * color2Alpha(alpha_col));
}
else
{
return fixed4(main_col.rgb, main_col.a * (1 - color2Alpha(alpha_col)));
}
}
ENDCG
}
}
}
边栏推荐
- 小说里的编程 【连载之十二】元宇宙里月亮弯弯
- 为什么别人游戏里的特效都非常柔和
- 6-9 vulnerability exploitation telnet login rights lifting
- 一文,教你实现单点登录
- Opportunities and challenges of Brazilian mobile game Investment Agency
- Use torch NN builds the simplest neural network framework
- instanceof的另类写法示例说明
- 【C语言-自定义类型】还能这样整?
- 使用arduino开发esp8266和esp32时首选项设置方法
- 2022年P气瓶充装考试练习题模拟考试平台操作
猜你喜欢
随机推荐
oop_ Reference type variable transfer value
Hausdorff loss function for semantic segmentation
MySQL读写分离
MySQL索引(三)
Redis
JSON under mysql8
QR decomposition for matrix inversion -- C engineering implementation
How to write a string field in MySQL if its value is not empty?
ARM计算新应用,违规垂钓“一网打尽”
2022 Guangdong Provincial Safety Officer a certificate, the third batch (main person in charge) exercise questions and mock examination
Stm32subeide (9) -- USART sends and receives via DMA
Solutions to license invalidation caused by MATLAB update
什么是内存溢出
JS learning notes 06-08: traversal of arrays and four methods of arrays
HCIP --- OSPF的综合实验
Authing 实践|制造业身份认证统一管理解决方案
Why are the special effects in others' games very soft
【虹科】GenICam协议入门
【LeetCode】通用操作总结
rosbridge









