一、ComposeTexture.shader
Shader "Custom/ComposeShader"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_SecondTex("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
LOD 100
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#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;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _SecondTex;
float4 _SecondTex_ST;
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);
fixed4 col2 = tex2D(_SecondTex, i.uv);
//step(a, x) 如果x<a,返回0;否则,返回1
//col2.a = step(0.95, col2.a);
col.rgb = col.rgba * (1 - col2.a) + col2.rgba * col2.a;
return col;
}
ENDCG
}
}
}
二、ComposeTexture.mat
三、ComposeTexture.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ComposeTexture : MonoBehaviour
{
[SerializeField]
private Texture2D m_MainTex;
[SerializeField]
private Texture2D m_SecondTex;
[SerializeField]
private Material m_ComposeMat;
[SerializeField]
private RawImage m_RawImage;
// Start is called before the first frame update
void Start()
{
RenderTexture destRT = RenderTexture.GetTemporary(1024, 1024, 0, RenderTextureFormat.ARGB32);
destRT.autoGenerateMips = false;
//覆盖目标纹理
//Graphics.ConvertTexture(m_Tex1, 0, destTex, 0);
//判断对Graphics.CopyTexture() API的支持情况
//Debug.LogFormat("SystemInfo.copyTextureSupport: {0}", SystemInfo.copyTextureSupport);
//注意:
//1、TextureFormat要一致才能复制,否则会报错
//Graphics.CopyTexture with a region will not copy readable texture data for compressed formats (source texture format 12)
//2、Mip Maps的个数要一致,或者都设为false,才能复制
//Graphics.CopyTexture called with mismatching mip counts (src 11 dst 1)
//3、尺寸要一致,否则报错
//Graphics.CopyTexture called with mismatching sizes (src 2048x1024 dst 1024x1024)
//Graphics.CopyTexture(m_Tex1, 0, destTex, 0);
//将m_SecondTex合成到m_MainTex上
m_ComposeMat.SetTexture("_SecondTex", m_SecondTex);
Graphics.Blit(m_MainTex, destRT, m_ComposeMat);
Texture2D destTex = ConvertTexture2D(destRT);
destRT.Release();
m_RawImage.texture = destTex;
}
//RenderTexture转Texture2D
private Texture2D ConvertTexture2D(RenderTexture renderTexture)
{
int width = renderTexture.width;
int height = renderTexture.height;
Texture2D texture2D = new Texture2D(width, height, TextureFormat.ARGB32, false);
RenderTexture.active = renderTexture;
texture2D.ReadPixels(new Rect(0, 0, width, height), 0, 0);
texture2D.Apply();
return texture2D;
}
}
四、创建RawImage
运行效果
示例:下面这个shader可以实现将第二贴图绘制到主贴图的指定位置
//笔刷
Shader "Custom/BrushShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BrushTex("Texture", 2D) = "white" {}
//要绘制的位置(归一化坐标)
_Position("Position", Vector) = (0, 0, 0, 0)
//画笔尺寸/_MainTex尺寸
_Scale("Scale", Vector) = (0, 0, 0, 0)
}
SubShader
{
Tags { "Queue" = "Transparent" "RenderType" = "Transparent" }
LOD 100
Pass
{
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#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;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _BrushTex;
float4 _BrushTex_ST;
fixed4 _Position;
fixed4 _Scale;
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);
if (i.uv.x >= _Position.x && i.uv.x <= _Position.z && i.uv.y >= _Position.y && i.uv.y <= _Position.w)
{
fixed2 uv2 = fixed2( (1 - (_Position.x - i.uv.x) * _Scale.x) , (1 - (_Position.y - i.uv.y) * _Scale.y));
fixed4 col2 = tex2D(_BrushTex, uv2);
col.rgba = col2.rgba * col2.a + col.rgba * (1 - col2.a);
}
return col;
}
ENDCG
}
}
}