原理,c#传入UV坐标,shader实现映射采样叠加原图。只实现基本功能,如果需要加法线等效果需要扩展。
C#代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MarkControl : MonoBehaviour
{
Material material;
// Start is called before the first frame update
void Start()
{
material = transform.GetComponent().material;
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.Mouse0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(ray,out hit, 1000))
{
Vector2 uv = hit.textureCoord;
float x = uv.x % 1;
if (x < 0)
x = 1 + x;
float y = uv.y % 1;
if (y < 0)
y = 1 + y;
material.SetVector("_MarkPos",new Vector4(x,y));
Debug.Log("x = " + x);
Debug.Log("y = " + y);
material.SetFloat("_MarkStrength",1);
}
}
}
}
shader代码如下:
Shader “Unlit/Mark”
{
Properties
{
_MainTex (“Texture”, 2D) = “white” {}
_MarkTex(“Mark”,2D) = “black” {}
_MarkPos(“MarkPos”,Vector)=(0,0,0,0)
_MarkStrength(“MarkStrength”,Range(0,1)) = 0
}
SubShader
{
Tags { “RenderType”=“Opaque” }
LOD 100
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;
float4 _MainTex_ST;
sampler2D _MarkTex;
fixed4 _MarkPos;
fixed _MarkStrength;
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);
fixed2 uRange = fixed2(_MarkPos.x - 0.1, _MarkPos.x + 0.1);
fixed2 vRange = fixed2(_MarkPos.y - 0.1, _MarkPos.y + 0.1);
fixed markU = (i.uv.x- uRange.x)/(0.2);
fixed markV = (i.uv.y - vRange.x)/(0.2);
fixed2 markUV = fixed2(markU,markV);
_MarkStrength *= (i.uv.x >= uRange.x);
_MarkStrength *= (i.uv.x <= uRange.y);
_MarkStrength *= (i.uv.y >= vRange.x);
_MarkStrength *= (i.uv.y <= vRange.y);
fixed4 markCol = tex2D(_MarkTex,markUV) * _MarkStrength;
return fixed4(col.rgb + markCol.rgb * markCol.a,col.a);
}
ENDCG
}
}
}