Unity、Ps、normalMap下,根据制作真实法线贴图(文中包含:偏振法线数据集、高度图)

文章不长,请耐心看完。会有收获~~~~~~~~~~~~~~~~~~~~~~~

简介:

SFM(Shape From Move),SFS(Shape from Shading),SFP(Shape From Polarization)等技术均是三维重建常用的方法,但是无论选择哪一种技术,在三维重建的过程中都无法避免法线。而为了更好的存储与纹理移植,法线贴图应运而生。

法线贴图存储法线的形式为:RGB通道分别存储法线的XYZ轴坐标,即将物体表面某一点的向量信息保存至图像通道中。


由于我是做SFP的,以下为三个具有代表意义的数据集:

文1提出了真实场景下环境的偏振数据集(含真实法线)

文1:export.arxiv.org/pdf/2112.11377.pdf

代码1:GitHub - ChenyangLEI/sfp-wild: [CVPR2022] Shape from Polarization for Complex Scenes in the Wild

数据集1:https://hkustconnect-my.sharepoint.com/:u:/g/personal/cqiaa_connect_ust_hk/EW7tfbO_I3dHjfp8H3ZsLikBwPaFL72ypZYMQTs_YifPwA?e=OFFk3e&download=1

文2提出利用深度学习解决偏振法线歧义性,并公布纹理较简单的小物体数据集(含真实法线)

文2:ecva.net/papers/eccv_2020/papers_ECCV/papers/123690545.pdf

代码2:GitHub - UCLA-VMG/DeepSfP
数据集2:https://drive.google.com/file/d/1EtjfMTfpanJotH92GFz300X_ZEmGXuqr/view

文3为清华大学团队公布的透明物体偏振数据集(含真实法线)

文3:arxiv.org/pdf/2208.11836.pdf

代码3:GitHub - shaomq2187/TransPIR: Repo for Polarimetric Inverse Rendering for Transparent Shapes Reconstruction

数据集3:https://cloud.tsinghua.edu.cn/f/2feaea15e9094941b4bd/?dl=1

那么,这些数据集中的法线贴图真实值是如何得到的呢?博主对网上现有的法线贴图获取方式进行了一个汇总。

法线贴图获取方式

网上现有的法线贴图获取方式,可分为以下四类:

1.一种说法,利用blender、3dmax等三维建模软件,进行高模、低模等操作,最后烘培出出法线贴图。如果你想尝试一下的话,可以参考以下贴。

Blender法线贴图(贴1)

(34条消息) blender烘焙法线贴图_blender 法线贴图_danad的博客-CSDN博客

3dmax法线贴图(贴2)

(34条消息) 什么是法线贴图 今天教你如何制作法线贴图_法线图_langgesanshiyi的博客-CSDN博客

但是,很可惜。贴1对法线贴图的制作描述的貌似不是很清晰,而贴2中有的图像看不到。

2.利用ps,对图像进行法线贴图操作,这种方法的效果更倾向于sobel边缘检测出来的结果(边缘轮廓特别明显,但是物体表面较平扁)。但是,Ps对于法线贴图的制作仍具有最高的兼容性,因为ps可打开多种格式。下图为Ps中的结果图,从左至右分别为高度图,高度结果法线图,强度图,强度结果法线图。

具体实现可参考以下贴(34条消息) Shader Graph2-使用PS生成正确的法线贴图_ps生成法线图_艺菲的博客-CSDN博客

(34条消息) 如何通过Photoshop根据纹理贴图轻松获得法线贴图_如何通过纹理生产人物法线_qq_21315789的博客-CSDN博客

3.利用normal在线生成法线贴图,这个网站的功能还是很强的。它可以根据高度图生成相应的法线贴图,但是经对比,它与真实值之间仍存在一定的差距。单不可否认,这个网站还是有很大的实用性。注意该网站支持的图像为高度图获取法线图,而输入强度图像时效果较差。下面是博主在该网站上进行测试的结果图

具体实现可参考以下贴:(34条消息) 一个免费在线法线贴图生成器(Normal Map Generator)_在线转法线_开发游戏的老王的博客-CSDN博客

4.经测试,unity在得到法线贴图时,其效果优于以上三种方法。它的具体操作步骤如下:
首先,我们输入的是强度图像,它是2d的。其次,我们将它拖拽至assets中并左键单击,可以在inspector(检查器)中找到texture type选择normal map 。最后,单击右下角apply。下面是输入为强度图像的结果图,从左至右分别为强度图,不选取gray,选取gray。

 下面是输入为高度图时的结果图,从左至右分别为强度图,不选取gray,选取gray,数据集中真实法线贴图(已mask)。

可以看出,当输入为高度图,且选择gray时,得到的法线贴图与数据集中的真实值最为相似。

最后,我们对于同一张高度图像,进行了ps、normal在线网站、unity之间的对比。可以看出,在unity中得到的法线贴图最符合物体表面,且结果具有表面突出信息。下面从左到右分别为高度图、ps结果图、normal在线网站结果图、unity结果图、数据集中真实法线图。

unity不支持将法线贴图直接导出为png格式,当我们直接对法线贴图进行截图时,得到的图像会被压缩,所以将纹理法线导出为png格式仍被需要。下面是利用C#联合unity实现将法线贴图导出为png格式的代码。

首先,我们需要在菜单栏下windows里面新增一个名为‘Normal Map Exporter ’的按钮。

实现这一功能的代码为

GUILayout.Label("Normal Map Exporter", EditorStyles.boldLabel); // 在编辑器窗口中显示标题

其次,点击此按钮会弹出如下界面。

将图像托至红框处,在点击‘Export as PNG’ 便可弹出对话框保存至本地。实现这个功能的代码如下

normalMapTexture = (Texture2D)EditorGUILayout.ObjectField("Normal Map Texture", normalMapTexture, typeof(Texture2D), false); // 在编辑器中创建一个字段,用于选择法线贴图纹理

if (GUILayout.Button("Export as PNG")) // 在编辑器中创建一个按钮,点击时触发导出操作
  。。。。。。。。。。

 在点击‘Export as PNG’时会进行,读取纹理法线的相关操作,代码如下

if (GUILayout.Button("Export as PNG")) // 在编辑器中创建一个按钮,点击时触发导出操作
        {
            if (normalMapTexture != null) // 检查是否已选择法线贴图
            {
                string texturePath = AssetDatabase.GetAssetPath(normalMapTexture); // 获取法线贴图在项目中的路径
                Debug.Log("Texture Path: " + texturePath);
                TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(texturePath); // 获取法线贴图的导入器

                // 检查纹理是否已设置为法线贴图类型
                if (textureImporter.textureType != TextureImporterType.NormalMap)
                {
                    textureImporter.textureType = TextureImporterType.NormalMap; // 将纹理类型设置为法线贴图
                    textureImporter.SaveAndReimport(); // 保存和重新导入纹理
                }

                // 将颜色空间设置为线性
                textureImporter.sRGBTexture = false;
                textureImporter.SaveAndReimport();

                // 创建一个临时的RenderTexture
                RenderTexture renderTexture = RenderTexture.GetTemporary(normalMapTexture.width, normalMapTexture.height, 0, RenderTextureFormat.Default, RenderTextureReadWrite.Linear);
                Graphics.DrawTexture(new Rect(0, 0, renderTexture.width, renderTexture.height), normalMapTexture);

                RenderTexture previous = RenderTexture.active;
                RenderTexture.active = renderTexture;

                // 创建一个Texture2D用于导出
                Texture2D exportTexture = new Texture2D(normalMapTexture.width, normalMapTexture.height, TextureFormat.RGBA32, false);
                exportTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
                Debug.LogWarning("exportTexture:"+ exportTexture); // 若未选择法线贴图,输出警告信息
                exportTexture.Apply();

                RenderTexture.active = previous;
                RenderTexture.ReleaseTemporary(renderTexture);

弹出的保存图像窗口为

注意,保存图像的路径应为Assets下。实现的相关代码为

// 将Texture2D保存为PNG
                byte[] bytes = exportTexture.EncodeToPNG();
                string path = EditorUtility.SaveFilePanel("Export Normal Map", "", "NormalMap.png", "png"); // 弹出文件保存对话框,选择保存路径和文件名
                if (!string.IsNullOrEmpty(path))
                {
                    System.IO.File.WriteAllBytes(path, bytes);
                    AssetDatabase.Refresh(); // 刷新资源数据库,使新的PNG文件在项目中可见
                    Debug.Log("Normal Map exported as PNG: " + path); // 在控制台输出导出路径

代码可在这里直接下载(35条消息) 【免费】unity中将法线贴图导出png格式的代码,可直接运行C#实现非截图!!!截图会压缩图像质量资源-CSDN文库

如有不正之处,欢迎指出。

同时欢迎关注,下一步尝试由三维模型的某一视角得出高度图。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Unity 是一款强大的游戏开发引擎,它具有丰富的功能和工具,可以用于制作各种类型的游戏和虚拟现实(VR)应用。其中一个令人兴奋的功能是它可以根据全景制作场景。 全景片是一种特殊的像,可以为用户提供一种身临其境的体验。全景片可以捕捉到整个场景的可视范围,使用户看到360度的视角。这种像通常由特殊的相机设备采集,也可以通过软件将多个像拼接在一起制作而成。 Unity 可以利用全景片创建一个虚拟环境。首先,我们需要导入全景片至 Unity 中。在导入后,Unity 将自动将其转化为一张强大的360度贴图。这张贴图将覆盖整个场景,包含墙壁、地板和天花板。在制作过程中,我们可以调整贴图的大小和位置来适应不同的场景需求。 一旦贴图被应用到场景中,我们可以添加其他元素来丰富用户的体验。通过在场景中添加物体、灯光和音效等资源,我们可以创建一个真实且与全景片相呼应的虚拟环境。用户可以通过虚拟现实设备或者移动设备来体验这个场景。 同时,Unity 还提供了用户交互的功能,使用户能够在虚拟环境中与元素进行互动。我们可以添加交互式按钮、触发事件和动画等功能,让用户能够与场景进行互动。 总的来说,Unity 可以根据全景制作出逼真且交互性强的虚拟场景。这为游戏和 VR 开发者提供了一个强大的工具,使他们能够创造出令人惊叹的虚拟世界。 ### 回答2: Unity 是一款多功能的游戏开发引擎,可以根据全景制作虚拟现实(VR)场景。全景片通常是由特殊相机拍摄的,在相机的覆盖范围内捕捉到所有方向的像,并将它们拼接在一起形成一个全景像。 使用Unity制作全景场景的步骤如下: 首先,导入全景片到Unity项目中。全景片应该是一个等角圆柱形投影或等角球形投影的像,以确保像的完整性。 接下来,创建一个新的空场景,并向其中添加一个全景球体或圆柱体网格。这个网格将充当全景像的容器。 然后,将全景片应用到球体或圆柱体的材质上。Unity中的材质是用于给游戏对象添加颜色、纹理和其他视觉效果的组件。 在材质上设置全景纹理的映射模式为360度,以确保全景像完全覆盖球体或圆柱体。 接下来,将全景球体或圆柱体调整到合适的大小和位置,以适应场景中的其他游戏对象。 最后,您可以为场景中添加其他游戏对象,如角色、物体、灯光等,以创建一个完整的虚拟现实场景。 Unity提供了丰富的工具和功能,使得制作全景场景变得简单而直观。通过使用Unity的自动化工具和预设物体,您可以轻松地导航和交互全景场景,使用户获得真实的虚拟现实体验。 总的来说,Unity是一款功能强大的引擎,通过其灵活的工具和功能,我们可以用全景制作出令人惊叹的虚拟现实场景。 ### 回答3: Unity是一款功能强大的游戏开发引擎,它具有丰富的功能和工具,其中包括制作全景片并将其转化为虚拟场景的能力。 全景片是一种通过摄影技术捕捉到的可以将观众完全包围的片。首先,在Unity制作全景片需要使用全景相机来拍摄相应的片。这个相机模拟了人眼对周围环境的感知方式,将周围的环境视为一个整体。 在拍摄全景片之后,需要将片导入Unity中并创建一个全景相机对象。然后,将全景片赋给这个相机对象的Skybox属性。Skybox是Unity中的一种用于呈现周围环境的材质,它将全景片投射到场景的上方、下方、前方、后方、左方和右方,从而营造出身临其境的效果。 接下来,可以为全景场景添加各种元素,比如建筑、道路、树木等。这可以通过在Unity中创建3D模型并放置在全景场景中来实现。此外,还可以添加灯光、雾效等来增强全景场景的真实感。 Unity还提供了一系列的开发工具,例如可视化编辑器界面和脚本系统,使开发者能够更加方便地编辑和场景中的物体进行脚本编写。这些工具可以帮助开发者提高效率,并且可以通过各种设置来调整全景场景的细节。 总的来说,Unity是一款非常适合制作全景场景的工具。它提供了全景相机、Skybox材质、3D模型编辑和脚本编写等功能,使开发者能够创建出逼真而又令人沉浸的全景场景。无论是制作虚拟现实游戏、全景漫游还是其他类型的项目,Unity都是一个非常好的选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值