3D 纹理

您所在的位置:网站首页 3dmax预览动画为什么会有条状纹理 3D 纹理

3D 纹理

2024-07-17 20:07| 来源: 网络整理| 查看: 265

Unity User Manual 2021.3 (LTS) 图形 纹理 3D 纹理 电影纹理 (Movie Textures) 纹理数组 3D 纹理

3D 纹理是位图图像,其中包含三维信息,而不是标准的二维信息。3D 纹理通常用于仿真诸如雾或烟的体积效果,模拟体积 3D 网格,或存储动画纹理并在这些动画纹理之间平滑混合。

3D 纹理大小

3D 纹理的最大分辨率为 2048 x 2048 x 2048。

Be aware that the size of a 3D texture in memory and on disk increases quickly as its resolution increases. An RGBA32 3D texture with no mipmaps and a resolution of 16 x 16 x 16 has a size of 128KB, but with a resolution of 256 x 256 x 256 it has a size of 512MB.

导入 3D 纹理

您可以从划分成单元格的源纹理文件导入 3D 纹理。这些被称为翻页纹理。为此需要执行以下操作:

将源纹理导入您的 Unity 项目。 在您的项目视图中,选择生成的纹理资源。Unity 将在 Inspector 中显示纹理导入设置。 在 Inspector 中,将 Texture Shape 设置为 3D。Unity 显示 Columns 和 Rows 属性。 将 Columns 和 Rows 设置为适用于翻页纹理的值。 单击 Apply。

有关更多信息,请参阅纹理导入设置。

作为 3D 形状的翻页图像 从脚本创建 3D 纹理

Unity 使用 Texture3D 类来表示 3D 纹理。使用此类可以在 C# 脚本中与 3D 纹理进行交互。

下面的示例是一个编辑器脚本,该脚本创建一个 Texture3D 类的实例,用颜色数据填充该实例,然后作为序列化资源文件保存到项目中。

using UnityEditor; using UnityEngine; public class ExampleEditorScript : MonoBehaviour { [MenuItem("CreateExamples/3DTexture")] static void CreateTexture3D() { // 配置纹理 int size = 32; TextureFormat format = TextureFormat.RGBA32; TextureWrapMode wrapMode = TextureWrapMode.Clamp; // 创建纹理并应用配置 Texture3D texture = new Texture3D(size, size, size, format, false); texture.wrapMode = wrapMode; // 创建 3 维数组以存储颜色数据 Color[] colors = new Color[size * size * size]; // 填充数组,使纹理的 x、y 和 z 值映射为红色、蓝色和绿色 float inverseResolution = 1.0f / (size - 1.0f); for (int z = 0; z < size; z++) { int zOffset = z * size * size; for (int y = 0; y < size; y++) { int yOffset = y * size; for (int x = 0; x < size; x++) { colors[x + yOffset + zOffset] = new Color(x * inverseResolution, y * inverseResolution, z * inverseResolution, 1.0f); } } } // 将颜色值复制到纹理 texture.SetPixels(colors); // 将更改应用到纹理,然后将更新的纹理上传到 GPU texture.Apply(); // 将纹理保存到 Unity 项目 AssetDatabase.CreateAsset(texture, "Assets/Example3DTexture.asset"); } } 预览 3D 纹理

Unity 编辑器具有三种不同的可视化模式,可用于预览 3D 纹理:

体积可视化模式将 3D 纹理渲染为半透明立方体 切片可视化模式渲染 3D 纹理的三个轴中每个轴的单个切片 SDF可视化模式将纹理渲染为 3D 空间中的有向距离场

您可以在 Inspector 中预览 3D 纹理,或者编写脚本以使用 Handles API 在 Scene 视图中预览。使用 Inspector 既快捷又方便,但不允许使用自定义渐变。Handles API 允许您根据您的确切需求来配置预览,并允许使用自定义渐变。

使用 Inspector

要在 Inspector 窗口中预览 3D 纹理:

在您的 Project 窗口中,选择 Texture Asset。Inspector 现在显示此纹理资源的纹理资源导入器,Unity 会在 Inspector 底部渲染 3D 纹理的预览。 导航到 3D 纹理预览上方的工具栏。 使用工具栏右侧的按钮在体积、切片和 SDF 可视化模式之间进行选择。预览图像和工具栏上的按钮会根据预览模式而变化。 体积

在此可视化模式中,Unity 将 3D 纹理渲染为半透明立方体。

工具栏中会显示以下控件:

控件: 功能: Ramp 启用和禁用颜色渐变可视化。如果图像包含很多细微的细节,请启用 Ramp 使这些细节更容易看到。 Quality 设置每纹理像素样本数。该值越高渲染质量越好。 Alpha 控制可视化的不透明度。值为 1 表示完全不透明,值为 0 表示完全透明。调整以查看内部像素。 切片

在这种可视化模式下,Unity 渲染 3D 纹理的每个轴平面的切片。

工具栏中会显示以下控件:

控件: 功能: Ramp 启用和禁用颜色渐变可视化。如果图像包含很多细微的细节,请启用 Ramp 使这些细节更容易看到。 X 设置 x 轴上的切片位置,以纹理像素为单位。调整以查看特定切片。 Y 设置 y 轴上的切片位置,以纹理像素为单位。调整以查看特定切片。 Z 设置 z 轴上的切片位置,以纹理像素为单位。调整以查看特定切片。 SDF

在这种可视化模式下,Unity 在 3D 空间中使用有向距离场渲染模式来渲染 3D 纹理。 请注意,此可视化模式仅支持非定向的有向距离场。

工具栏中会显示以下控件:

控件: 功能: Scale 与射线步长相乘的数字。射线步长是两个相邻像素之间的距离。

如果可视化的远处部分被截断,请尝试增加该值。如果根本没有渲染可视化,请尝试减少该值。

Offset 渲染表面的像素强度。当此值为正时,Unity 将扩展渲染表面。当此值为负时,Unity 会将空白空间渲染为曲面,将曲面渲染为空白空间。 使用 Handles API

有关使用 Handles API 预览 3D 纹理及代码示例的信息,请参阅以下文档:

Handles.DrawTexture3DVolume Handles.DrawTexture3DSlice Handles.DrawTexture3DSDF 在着色器中使用 3D 纹理

下面是一个使用 3D 纹理来可视化体积的简单光线追踪 (Raymarching) 着色器示例。

Shader "Unlit/VolumeShader" { Properties { _MainTex ("Texture", 3D) = "white" {} _Alpha ("Alpha", float) = 0.02 _StepSize ("Step Size", float) = 0.01 } SubShader { Tags { "Queue" = "Transparent" "RenderType" = "Transparent" } Blend One OneMinusSrcAlpha LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" // 最大光线追踪样本数 #define MAX_STEP_COUNT 128 // 允许的浮点数误差 #define EPSILON 0.00001f struct appdata { float4 vertex : POSITION; }; struct v2f { float4 vertex : SV_POSITION; float3 objectVertex : TEXCOORD0; float3 vectorToSurface : TEXCOORD1; }; sampler3D _MainTex; float4 _MainTex_ST; float _Alpha; float _StepSize; v2f vert (appdata v) { v2f o; // 对象空间中的顶点将成为光线追踪的起点 o.objectVertex = v.vertex; // 计算世界空间中从摄像机到顶点的矢量 float3 worldVertex = mul(unity_ObjectToWorld, v.vertex).xyz; o.vectorToSurface = worldVertex - _WorldSpaceCameraPos; o.vertex = UnityObjectToClipPos(v.vertex); return o; } float4 BlendUnder(float4 color, float4 newColor) { color.rgb += (1.0 - color.a) * newColor.a * newColor.rgb; color.a += (1.0 - color.a) * newColor.a; return color; } fixed4 frag(v2f i) : SV_Target { // 开始在对象的正面进行光线追踪 float3 rayOrigin = i.objectVertex; // 使用摄像机到对象表面的矢量获取射线方向 float3 rayDirection = mul(unity_WorldToObject, float4(normalize(i.vectorToSurface), 1)); float4 color = float4(0, 0, 0, 0); float3 samplePosition = rayOrigin; // 穿过对象空间进行光线追踪 for (int i = 0; i < MAX_STEP_COUNT; i++) { // 仅在单位立方体边界内累积颜色 if(max(abs(samplePosition.x), max(abs(samplePosition.y), abs(samplePosition.z))) < 0.5f + EPSILON) { float4 sampledColor = tex3D(_MainTex, samplePosition + float3(0.5f, 0.5f, 0.5f)); sampledColor.a *= _Alpha; color = BlendUnder(color, sampledColor); samplePosition += rayDirection * _StepSize; } } return color; } ENDCG } } }

如果将此着色器用于在页面顶部的示例中创建的 3D 纹理,则结果将如下所示:

电影纹理 (Movie Textures) 纹理数组


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3