Model painting case sharing (full original code)

This article is a case of UV smearing of the model. According to the usual practice, let’s start with the picture above:
insert image description here
insert image description here
Alright, let’s start to explain:
1. In order to allow rays to detect the surface of the model, we need to add a MeshCollider to the model, and the model material uses ordinary Standard preparation materials That's it.
insert image description here
2. Prepare the brush material. If you don’t need the target texture, just don’t assign a value. The following is the material code.
insert image description here
Brush Shader original code:

Shader "Giraffe/SingleBursh"
{
	Properties
	{
		_TargetTex("目标图形",2D) = "white" {}
		_BrushTex("刷子形状",2D) = "white" {}
		_Color("Color",Color) = (1,1,1,1)
		_UV("UV",Vector) = (0,0,0,0)
		_SizeX("SizeX",Range(1,100)) = 1
		_SizeY("SizeY",Range(1,100)) = 1
		_Alpha("刷子权重",Range(0,1)) = 0.2
	}
	SubShader
	{
		Tags { "RenderType" = "Transparent" }
		LOD 100
		ZTest Always Cull Off ZWrite Off Fog{ Mode Off }
		Blend SrcAlpha OneMinusSrcAlpha
		//Blend One DstColor
		Pass
		{
			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 _BrushTex;
			sampler2D _TargetTex;
			float4 _TargetTex_ST;
			fixed4 _UV;
			float _SizeX;
			float _SizeY;
			fixed4 _Color;
			float _Alpha;

			v2f vert(appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _TargetTex);
				return o;
			}

			fixed4 frag(v2f i) : SV_Target
			{
				float2 _Size = float2(_SizeX,_SizeY);
				float2 uv = i.uv + (0.5f / _Size);
				uv = uv - _UV.xy;
				uv *= _Size;
				fixed4 col = tex2D(_BrushTex, uv);
				
				col.rgb = 1;
				fixed4 col2 = tex2D(_TargetTex, i.uv);
				col *= _Color;

				half4 RGB = col* col2;

				return half4(RGB.rgb, RGB.a*_Alpha);
			}
			ENDCG
		}
	}
}

3. The following is the mouse click part. The UV of the clicked position is detected by emitting rays. The code is as follows:

    RaycastHit hit;
	Ray ray;
    ray = Camera.main.ScreenPointToRay(Input.mousePosition);                //摄像机发射射线到屏幕点。
    Debug.DrawRay(ray.origin, ray.direction * 100, Color.red, 0.1f);		//可以在Screen窗口看到射线轨迹
    if (Physics.Raycast(ray, out hit, 100f))
    {
    
    
	    Vector2 pixelUV = hit.textureCoord;									//得到点击位置所在UV值
	    BrushHandle(pixelUV);
	}

Fourth, the main logic part, this can be directly hung up with MonoBehaviour.

	public RenderTexture m_renderTex;                                  //渲染图
    public Texture m_texOriginal;                                      //起始模型图
    public Texture m_texTarget;                                        //笔刷纹理图
    public Material m_matMain;                                         //星球材质
    public Material m_matBrush;                                        //刷子材质

	 private void ReadyBrushObj()
    {
    
    
        //创建渲染纹理
        m_renderTex = RenderTexture.GetTemporary(2048, 2048, 24);
        //将默认图片赋值给渲染纹理
        Graphics.Blit(m_texOriginal, m_renderTex);
        //将默渲染纹理赋值给模型材质主图
        m_matMain.SetTexture("_MainTex", m_renderTex);
        //将笔刷纹理赋值给纹理图(可选)
        m_matBrush.SetTexture("_TargetTex", m_texTarget);
    }
            
	private void __BrushHandle(Vector2 minUv)
    {
    
    
    	m_matBrush.SetVector("_UV", minUv);
		Graphics.Blit(m_renderTex, m_renderTex, m_matBrush);
    }

The above is the complete content.
The following is the project demo, if you have any questions, you can private message me:
https://download.csdn.net/download/ww1351646544/21043484?spm=1001.2014.3001.5503

Guess you like

Origin blog.csdn.net/ww1351646544/article/details/119633337