unity在模型上绘画

原文:Unity插件开发 - 知乎 (zhihu.com)

前言

在我的上一篇文章【基于高度进行混合的shader】里面分享了如何利用高度图进行贴图的混合,里面使用了T4M插件来绘制控制混合的control贴图。

动图封面

像T4M这样直接在mesh上对贴图进行绘制的功能对于美术的同学肯定不陌生,很多建模工具都支持直接在模型上对贴图进行绘制,如C4D的bodypaint工具、allegorithmic公司推出的Substance Painter都支持直接在模型上进行绘制。

这里简单说一下如何在UNITY里实现这个在模型上绘画的功能。

准备工作

在unity中新建一个工程,创建所需要的一些文件夹

用来测试的几张地表贴图

一些用来做笔刷的PNG图(直接从T4M里面扒过来的)

新建一个scene,把测试用的模型拖到场景中,把模型的layer设为“ground”(如果没有就自己添加一个),给模型一个新的Material,并使用附件中的文件名为mya_T4M_4tex_blend_diffuse 的这个shader,并参考下图进行配置:


 

创建一个名为meshPainter的C#脚本,挂在这个模型上。

using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
[RequireComponent(typeof(MeshCollider))]
public class meshPainter : MonoBehaviour {

    void Start () {
    }
    void Update () {
    }
}

为了自定义脚本的Inspector显示,我们需要一个Style脚本,我们再创建一个meshPainterStyle.cs文件,放在Editor文件下

using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections;

[CustomEditor(typeof(meshPainter))]
[CanEditMultipleObjects]
public class meshPainterStyle : Editor
{
    public override void OnInspectorGUI()
    {
    }
}

生成控制混合的贴图

在模型上绘制需要shader和control贴图,所以首先判断当前模型的shader是否正确以及是否有control贴图,如果shader不正确或者control贴图不存在就会显示警告信息,并显示一个生成control贴图的按钮。

 string ContolTexName = "";
    public override void OnInspectorGUI()
    {
        if (Cheak())
        {
        }
    }
    //检查
    bool Cheak()
    {
        bool Cheak = false;
        Transform Select = Selection.activeTransform;
        Texture ControlTex = Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.GetTexture("_Control");
        if(Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.shader == Shader.Find("Mya/texBlend/mya_4tex_blend_diffuce") || Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.shader == Shader.Find("Mya/texBlend/mya_4tex_blend_normal"))
        {
            if(ControlTex == null)
            {
                EditorGUILayout.HelpBox("当前模型材质球中未找到Control贴图,绘制功能不可用!", MessageType.Error);
                if (GUILayout.Button("创建Control贴图"))
                {
                    creatContolTex();
                    //Select.gameObject.GetComponent<MeshRenderer>().sharedMaterial.SetTexture("_Control", creatContolTex());
                }
            }
            else
            {
                Cheak = true;
            }
        }
        else 
        {
            EditorGUILayout.HelpBox("当前模型shader错误!请更换!", MessageType.Error);
        }
        return Cheak;
    }

    //创建Contol贴图
    void creatContolTex()
    {

        //创建一个新的Contol贴图
        string ContolTexFolder = "Assets/MeshPaint/Controler/";
        Texture2D newMaskTex = new Texture2D(512, 512, TextureFormat.ARGB32, true);
        Color[] colorBase = new Color[512 * 512];
        for(int t = 0; t< colorBase.Length; t++)
        {
            colorBase[t] = new Color(1, 0, 0, 0);
        }
        newMaskTex.SetPixels(colorBase);

        //判断是否重名
        bool exporNameSuccess = true;
        for(int num = 1; exporNameSuccess; num++)
        {
            string Next = Selection.activeTransform.name +"_"+ num;
            if (!File.Exists(ContolTexFolder + Selection.activeTransform.name + ".png"))
            {
                ContolTexName = Selection.activeTransform.name;
                exporNameSuccess = false;
            }
            else if (!File.Exists(ContolTexFolder + Next + ".png"))
            {
                ContolTexName = Next;
                exporNameSuccess = false;
            }

        }

        string path = ContolTexFolder + ContolTexName + ".png";
        byte[] bytes = newMaskTex.EncodeToPNG();
        File.WriteAllBytes(path, bytes);//保存


        AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);//导入资源
        //Contol贴图的导入设置
        TextureImporter textureIm = AssetImporter.GetAtPath(path) as TextureImporter;
        textureIm.textureFormat = TextureImporterFormat.ARGB32;
        textureIm.isReadable = true;
        textureIm.anisoLevel = 9;
        textureIm.mipmapEnabled = false;
        textureIm.wrapMode = TextureWrapMode.Clamp;
        AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate);//刷新


        setContolTex(path);//设置Contol贴图

    }

    //设置Contol贴图
    void setContolTex(string peth)
    {
        Texture2D ControlTex = (Texture2D)AssetDatabase.LoadAssetAtPath(peth, typeof(Texture2D));
        Selection.activeTransform.gameObject.GetComponent<MeshRenderer>().sharedMaterial.SetTexture("_Control", ControlTex);
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值