Пример шейдера:
Синтаксис:
Используется csharp
Shader "Plane/DrawGrab" {
Properties {
_MainTex ("RGBA", 2D) = "white" {}
[Toggle]
_Channal_R ("Channal R", float) = 1
[Toggle]
_Channal_G ("Channal G", float) = 1
[Toggle]
_Channal_B ("Channal B", float) = 1
[Toggle]
_Channal_A ("Channal A", float) = 1
}
SubShader {
Tags
{
"Queue" = "Transparent"
"RenderType" = "Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
GrabPass { }
Pass {
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex ComputeVertex
#pragma fragment ComputeFragment
sampler2D _MainTex;
sampler2D _GrabTexture;
half _Channal_R;
half _Channal_G;
half _Channal_B;
half _Channal_A;
struct VertexInput
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct VertexOutput
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
float4 screenPos : TEXCOORD1;
};
VertexOutput ComputeVertex (VertexInput vertexInput)
{
VertexOutput vertexOutput;
vertexOutput.vertex = UnityObjectToClipPos(vertexInput.vertex);
vertexOutput.screenPos = vertexOutput.vertex;
vertexOutput.texcoord = vertexInput.texcoord;
vertexOutput.color = vertexInput.color;
return vertexOutput;
}
fixed4 ComputeFragment (VertexOutput vertexOutput) : SV_Target
{
half4 a = tex2D(_MainTex, vertexOutput.texcoord);
float2 grabTexcoord = vertexOutput.screenPos.xy / vertexOutput.screenPos.w;
grabTexcoord.x = (grabTexcoord.x + 1.0) * .5;
grabTexcoord.y = (grabTexcoord.y + 1.0) * .5;
#if UNITY_UV_STARTS_AT_TOP
grabTexcoord.y = 1.0 - grabTexcoord.y;
#endif
fixed4 b = tex2D(_GrabTexture, grabTexcoord);
if (_Channal_R != 1) a.r = b.r;
if (_Channal_G != 1) a.g = b.g;
if (_Channal_B != 1) a.b = b.b;
if (_Channal_A != 1) a.a = b.a;
return float4(a.r, a.g, a.b, a.a);
}
ENDCG
}
}
}
Properties {
_MainTex ("RGBA", 2D) = "white" {}
[Toggle]
_Channal_R ("Channal R", float) = 1
[Toggle]
_Channal_G ("Channal G", float) = 1
[Toggle]
_Channal_B ("Channal B", float) = 1
[Toggle]
_Channal_A ("Channal A", float) = 1
}
SubShader {
Tags
{
"Queue" = "Transparent"
"RenderType" = "Transparent"
}
Blend SrcAlpha OneMinusSrcAlpha
GrabPass { }
Pass {
CGPROGRAM
#include "UnityCG.cginc"
#pragma vertex ComputeVertex
#pragma fragment ComputeFragment
sampler2D _MainTex;
sampler2D _GrabTexture;
half _Channal_R;
half _Channal_G;
half _Channal_B;
half _Channal_A;
struct VertexInput
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct VertexOutput
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
float4 screenPos : TEXCOORD1;
};
VertexOutput ComputeVertex (VertexInput vertexInput)
{
VertexOutput vertexOutput;
vertexOutput.vertex = UnityObjectToClipPos(vertexInput.vertex);
vertexOutput.screenPos = vertexOutput.vertex;
vertexOutput.texcoord = vertexInput.texcoord;
vertexOutput.color = vertexInput.color;
return vertexOutput;
}
fixed4 ComputeFragment (VertexOutput vertexOutput) : SV_Target
{
half4 a = tex2D(_MainTex, vertexOutput.texcoord);
float2 grabTexcoord = vertexOutput.screenPos.xy / vertexOutput.screenPos.w;
grabTexcoord.x = (grabTexcoord.x + 1.0) * .5;
grabTexcoord.y = (grabTexcoord.y + 1.0) * .5;
#if UNITY_UV_STARTS_AT_TOP
grabTexcoord.y = 1.0 - grabTexcoord.y;
#endif
fixed4 b = tex2D(_GrabTexture, grabTexcoord);
if (_Channal_R != 1) a.r = b.r;
if (_Channal_G != 1) a.g = b.g;
if (_Channal_B != 1) a.b = b.b;
if (_Channal_A != 1) a.a = b.a;
return float4(a.r, a.g, a.b, a.a);
}
ENDCG
}
}
}
Возможно есть другие способы быстрой замены каналов в текстурах, пописельно переписывать текстуру конечно не вариант. Подскажите, помогите.