前几天有人问我,看能不能实现笔刷效果。于是花了点时间研究了一下,找到了一个最简单的方案。
原理很简单,核心方法就是使用Graphics.Blit,将图传入shader中,叠加上detial,再保存该结果为RT,下次加入detial时将该结果迭代。
我实现了大部分功能,还有一些细节可以根据需要进行修改。比如笔刷的力度、边缘过渡、颜色渐变等。
如果还有其它的shader制作需求也可以留言,我会酌情实现。
代码:
using UnityEngine;
public class SS_15 : MonoBehaviour
{
RenderTexture temp;
public RenderTexture render;
public Material mat;//处理叠加
public Material targetMat;//将叠加的图片传入另一个材质中
public int size=8;
public float length=10;//10是plane的size
[HideInInspector]
public Vector2 pos;//传入0-size的值
public float speed = 0.5f;
float unit = 0;
public RenderTexture Temp
{
get
{
if (temp == null)
{
temp = new RenderTexture(render);
}
return temp;
}
set
{
temp = value;
}
}
void Start()
{
Graphics.Blit((Texture2D)mat.GetTexture("_MainTex"),render);
unit = length / size;
Draw();
}
[ContextMenu("Draw")]
public void Draw()
{
transform.position = new Vector3((pos.x+0.5f)* unit, 0,(pos.y + 0.5f )* unit);
mat.SetFloat("_PosX", pos.x/size);
mat.SetFloat("_PosY", pos.y/ size);
Graphics.Blit(render, Temp, mat);//将当前图片传入mat中进行处理,结果放入temp
Graphics.Blit(Temp, render);//将temp再传回render
//targetMat.SetTexture("_Mask",render);//将遮罩图传入目标材质中
}
private void Update()
{
if (Input.GetKey(KeyCode.W))
{
pos.y+= speed;
Draw();
}
if (Input.GetKey(KeyCode.S))
{
pos.y-= speed;
Draw();
}
if (Input.GetKey(KeyCode.A))
{
pos.x-= speed;
Draw();
}
if (Input.GetKey(KeyCode.D))
{
pos.x+= speed;
Draw();
}
}
}
Shader "Unlit/SS_15_0"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}//不可略,否则 Graphics.Blit无法赋值
_Detail ("Detail", 2D) = "white" {}
_PosX("PosX",float)=0
_PosY("PosY",float)=0
}
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;
};
struct v2f
{
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
fixed4 _MainTex_ST;
sampler2D _Detail;
fixed4 _Detail_ST;
fixed _PosX;
fixed _PosY;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);//不可略,因为每次RT赋值时uv都需要重置
o.uv1 = TRANSFORM_TEX(v.uv1, _Detail);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col=tex2D(_MainTex,i.uv);
fixed2 _uv=fixed2(i.uv1.x-_PosX*_Detail_ST.x,i.uv1.y-_PosY*_Detail_ST.y); // _Detail_ST可以获取Tiling值
fixed4 col1=tex2D(_Detail,_uv);
return col1*col;
}
ENDCG
}
}
}
返回目录:https://blog.csdn.net/yzy1987523/article/details/106676451