一日一Shader·手机版笔刷【SS_21】

之前用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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值