动作穿模是 传统3D游戏常见的一个小问题并且默认心态是没必要完全解决或反复修动作,但我打算违背这种传统通过渲染来解决问题.因为我们是FPS动作动态过度和混合的情况极其多样 上千个动作组合情况.衣服又很多 挨个反复调工作量非常巨大.

防穿模实现

因为一般都不用渲染解决这问题所以我无从参考.直接参考了现实生活,穿了一件衣服不会让肉穿出来是因为 物理的约束作用,所以 穿了衣服应该改变身体本身的尺寸这点需要实现.实现结果如下 咯吱窝那里的穿面得到解决

对应的身边变形为 下图演示,其实一般项目的需求 不需要做变形 直接做discard 内部像素绘制即可效果不错.但缩小效果会更好些 比如我们采用镂空时 游泳的镜头下, 盯裆猫用户与瞄人缝玩家 都发现 短裙里没有肉.

这样实现后用了2年多极大节省了动作组的工作量.

作用区域实现

穿上外套A,让身体或衬衣 的哪些区域缩小或不绘制呢?这就需要一张低分辨率的mask图.但是 如何让同一个mask的 比如左上角 都表示 扣除的是同一个部位呢?(这里有点绕)就需要 所有衬衣和身体的 uv保持一致.和美术沟通后这是好实现的 且会浪费空间.所以最后采用的做法是 让所有衬衣和身体 uv1保持一致(就是第二套uv 反正他们都不需要烘焙).

2个mesh的uv映射

目前这部分uv1是手工匹配,因我只对3d美术工具中级水平的了解,所以没问到有这样的软件.最后决定花30分钟开发一下,我叫他 2个mesh的uv映射.思路很简单就算 用射线缠(馋)她的身子!

每个衣服顶点做一堆360度射线碰撞找到最近碰撞点的uv 写回mesh(这里只有身体加了meshCollider),更好的做法 用球坐标的射线(角度均匀)这里误差不大就直接用均等位移产生出的 非均匀角度.

身体与短 袖 映射前uv不同 ,对某个外套无法用通用mask

工具映射后uv一致 ,所以一套抠区域的mask可通用,同像素代表同位置

以下是uv映射工具的代码(但我还是相信这个功能有第三方成熟工具 知道的大佬请留言 多谢)

using System.Collections ;

using System.Collections.Generic ;

using UnityEngine ;

public class UVRamp : MonoBehaviour

[ContextMenu("makeUV")]

void makeUV

var mesh = GetComponent<SkinnedMeshRenderer>.sharedMesh;

var vers = mesh.vertices;

var uvs = mesh.uv;

float dirStep = 0.1f ; //越小越精确 需要超级精确会很慢,需要想办法用gpu来计算或用相机一次次拍摄深度图代替射线查找最近点

RaycastHit hitInfo;

for ( int i = 0 , len = vers.Length; i < len; i++)

Vector3 v = vers[i];

float minDis = float .MaxValue;

Vector2 minUV = uvs[i];

for ( float x = - 1 ; x < 1 ; x += dirStep)

for ( float y = - 1 ; y < 1 ; y += dirStep)

for ( float z = - 1 ; z < 1 ; z += dirStep)

if (Physics.Raycast(transform.localToWorldMatrix.MultiplyPoint(v), Vector3.Normalize( new Vector3(x, y, z)), out hitInfo))

if (hitInfo.distance < minDis)

minDis = hitInfo.distance;

minUV = hitInfo.textureCoord;

uvs[i] = minUV;

//var pt=GameObject.CreatePrimitive(PrimitiveType.Cube);

//pt.transform.position=transform.localToWorldMatrix.MultiplyPoint(v);

//pt.transform.localScale = Vector3.one * 0.01f;

mesh.uv = uvs;

来源知乎专栏:游戏技术轮子 返回搜狐,查看更多

责任编辑:

声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。