UNITY-仅更改 3D 模型颜色的某些部分 [英] UNITY-Changing ONLY certain part of 3D model's color

查看:32
本文介绍了UNITY-仅更改 3D 模型颜色的某些部分的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 unity3D 的新手,我想问一个问题我有一个具有分层骨骼结构的 3D 人体模型(默认的统一模型).

I'm really new with unity3D and I would like to ask a question I have a 3D human model ( a default unity model) which has a hierarchical bone structure.

我想在这里实现的是,当我按下某个触发器时,我想给它的一个肢体涂上不同的颜色(只是它的一个肢体).这是我想要实现的说明

What I want to achieve here is, when I press certain trigger, I want to color one of its limb with different color (just one of its limb). This is the illustration of what I want to achieve

我真的对此一无所知,因为我大约 3 个月前才开始学习 Unity,所以我真的需要你的帮助,如果有帮助,这是我的渲染器的属性

I'm really clueless about this, because I've just started learning Unity for about 3 months ago, so I really need your help, this is the property of my renderer if it's helping

推荐答案

我只想补充一点,使用 投影仪.这是 unity 中用于实时在网格表面上绘制各种效果的常用工具,例如弹孔.使用相同的原理,您可以突出显示网格的某些区域.您可以将投影仪视为手电筒,它的光线照射到的所有物体都会改变其纹理.标准资产/效果下有一些示例投影仪.您可能想从那里开始.

I just wanted to add that there may be an easier way to achieve what you want using projectors. This is the common tool in unity used to draw various effects on mesh surface in real time, such as bullet holes. Using the same principle you can highlight some area of the mesh. You can think of a projector as flashlight, that everything its light hits changes its texture. There are some example projectors under Standard Assets / Effects. You might want to start there.

要创建投影仪,请创建一个空游戏对象 => 添加组件 => 投影仪.

To create a projectror, create an empty game object => Add Component => Projector.

编辑

您可能想尝试的另一个想法是使用顶点颜色.除了坐标之外,网格的每个顶点还包含一个颜色参数,可通过着色器访问该参数.因此,您可以更改特定顶点集的颜色以突出显示它们.这里有2点你要注意:

Another idea you may want to try is to use vertex colors. Each vertex of a mesh contains, in addition to coordinates, a color parameter, which is accessible via shader. So, you can change the color of specific set of vertices in order to highlight them. There are 2 points here you have to pay attention to:

1) 大多数着色器选择忽略顶点颜色,精灵着色器除外.您将需要一个自定义着色器,例如 这个.

1) Most shaders choose to ignore vertex color, with exception of sprites shader. You will need a custom shader, such as this one.

2) 您需要以某种方式知道要突出显示哪些顶点.您可以做的是迭代 Mesh.boneWeights.例如,如果您想选择一个手臂,您需要的是手臂骨骼索引权重 > 1 的所有顶点.你如何找到手臂骨骼指数?该索引对应于 SkinnedMeshRenderer.bones 中的索引.或者只是选择一些您确定属于手臂的顶点并查看其骨骼权重以找到索引.

2) You need to know somehow which vertices exactly you want to highlight. What you can do is to iterate over Mesh.boneWeights. If you want to select an arm, for example, what you need is all vertices that have weight > 1 for arm bone index. How do you find the arm bone index? This index corresponds to the index in SkinnedMeshRenderer.bones. Or just pick some vertex you know for sure belongs to arm and see its bone weights to find the index.

这里是一个示例脚本,它根据选定的骨骼索引更改顶点颜色.将它附加到您的 SkinnedMeshRenderer(通常是一个二级层次结构对象):

Here a sample script that changes vertex colors based on selected bone index. Attach it to your SkinnedMeshRenderer (usually a second level hierarchy object):

using UnityEngine;
using System.Collections;

public class BoneHiglighter : MonoBehaviour {

    public Color32 highlightColor = Color.red;
    public Color32 regularColor = Color.white;

    public SkinnedMeshRenderer smr;

    // Just for sake of demonstration
    public Transform bone;
    private Transform prevBone;


    // Find bone index given bone transform
    int GetBoneIndex(Transform bone) {
        Debug.Assert(smr != null);
        var bones = smr.bones;

        for (int i = 0; i < bones.Length; ++i) {
            if (bones[i] == bone) return i;
        }

        return -1;
    }

    // Change vertex colors highlighting given bone
    void Highlight(Transform bone) {
        Debug.Assert(smr != null);
        var idx = GetBoneIndex(bone);
        var mesh = smr.sharedMesh;
        var weights = mesh.boneWeights;
        var colors = new Color32[weights.Length];

        for (int i = 0; i < colors.Length; ++i) {
            float sum = 0;
            if (weights[i].boneIndex0 == idx && weights[i].weight0 > 0)
                sum += weights[i].weight0;
            if (weights[i].boneIndex1 == idx && weights[i].weight1 > 0)
                sum += weights[i].weight1;
            if (weights[i].boneIndex2 == idx && weights[i].weight2 > 0)
                sum += weights[i].weight2;
            if (weights[i].boneIndex3 == idx && weights[i].weight3 > 0)
                sum += weights[i].weight3;

            colors[i] = Color32.Lerp(regularColor, highlightColor, sum);
        }

        mesh.colors32 = colors;

    }

    void Start() {
        // If not explicitly specified SkinnedMeshRenderer try to find one
        if (smr == null) smr = GetComponent<SkinnedMeshRenderer>();
        // SkinnedMeshRenderer has only shared mesh. We should not modify it.
        // So we make a copy on startup, and work with it.
        smr.sharedMesh = (Mesh)Instantiate(smr.sharedMesh);

        Highlight(bone);
    }

    void Update() {
        if (prevBone != bone) {
            // User selected different bone
            prevBone = bone;
            Highlight(bone);
        }
    }
}

查看示例项目:https://www.dropbox.com/s/yfoqo44bubcr48s/HighlightBone.zip?dl=0

演示:http://jolly-squirrel.droppages.com/bones/index.html - 点击身体部位以查看它们突出显示.

Demo: http://jolly-squirrel.droppages.com/bones/index.html - click on body parts to see them highlight.

这篇关于UNITY-仅更改 3D 模型颜色的某些部分的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆