之前用GL方式制作的笔刷在手机端用不了,于是只能根据最早的笔刷进行改进。
其中最关键的地方是如何更换刷头。我用的是遮罩的方式,只让当前刷头显示出来,挡住其他刷头。
Shader "MyShader/SS_21"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}//不可略,否则 Graphics.Blit无法赋值
_Detail ("Detail", 2D) = "white" {}
_Mask ("Mask", 2D) = "white" {}
_PosX("PosX",float)=0//位置
_PosY("PosY",float)=0
_OffestX("OffestX",float)=0//决定detail编号
_OffestY("OffestY",float)=0
_Color("Color",color)=(1,1,1,1)
_DetailSize("DetailSize",float)=1.1
_MaskSize("MaskSize",float)=1.1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
};
struct v2f
{
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
fixed4 _MainTex_ST;
sampler2D _Mask;
fixed4 _Mask_ST;
sampler2D _Detail;
fixed4 _Detail_ST;
fixed4 _Color;
fixed _PosX;
fixed _PosY;
fixed _OffestX;
fixed _OffestY;
fixed _DetailSize;
fixed _MaskSize;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);//不可略,因为每次RT赋值时uv都需要重置
fixed _X=_OffestX*_MaskSize-_PosX-(_DetailSize-1);
fixed _Y=_OffestY*_MaskSize-_PosY-(_DetailSize-1);
o.uv1 = TRANSFORM_TEX(v.uv1, _Detail)/_DetailSize;
o.uv1=fixed2(o.uv1.x+_X/_DetailSize,o.uv1.y+_Y/_DetailSize);
o.uv2 = TRANSFORM_TEX(v.uv2,_Mask)/_MaskSize/_DetailSize;
o.uv2=fixed2(o.uv2.x+(_X)/_MaskSize/_DetailSize-_OffestX,o.uv2.y+(_Y)/_MaskSize/_DetailSize-_OffestY);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col=tex2D(_MainTex,i.uv);
fixed4 col1=tex2D(_Detail,i.uv1);
fixed4 col2=tex2D(_Mask,i.uv2)*col1*_Color;
return col2.a<0.1?col:col2;
}
ENDCG
}
}
}
控制脚本:
using UnityEngine;
public class SS_21: MonoBehaviour,IShaderConnect
{
RenderTexture temp;
public RenderTexture render;
public Material mat;//处理叠加
[HideInInspector]
public Vector2 pos;//传入0-size的值
public Vector2 offest;
public RenderTexture Temp
{
get
{
if (temp == null)
{
temp = new RenderTexture(render);
}
return temp;
}
set
{
temp = value;
}
}
void Start()
{
Graphics.Blit(mat.GetTexture("_MainTex"),render);
}
[ContextMenu("Draw")]
public void Draw()
{
mat.SetFloat("_PosX", pos.x );
mat.SetFloat("_PosY", pos.y);
mat.SetFloat("_OffestY", Random.Range(0,4));
mat.SetFloat("_OffestY", Random.Range(0, 4));
Graphics.Blit(render, Temp, mat);//将当前图片传入mat中进行处理,结果放入temp
Graphics.Blit(Temp, render);//将temp再传回render
}
private void Update()
{
if (Input.GetMouseButton(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//碰撞器要用MeshCollider
var _hit = new RaycastHit();
if (Physics.Raycast(ray, out _hit, 100f))
{
pos.Set((_hit.textureCoord.x- offest.x), (_hit.textureCoord.y- offest.y));
//Debug.Log(_hit.textureCoord);
Draw();
}
}
}
[ContextMenu("Reset")]
public void ResetRT()
{
Graphics.Blit(mat.GetTexture("_MainTex"), render);
}
public void ResetParam()
{
ResetRT();
}
}
返回目录:https://blog.csdn.net/yzy1987523/article/details/106676451