这次我们学习一下texture3d(又名三维纹理贴图、三向纹理贴图、3d纹理贴图等)。
      照例先上官方:
      百度百科
      UnityManual
      MicrosoftDocs
      官方的标准释义还是更好的,我们阅读才能最准确的了解texture3d,然后再拿过来用。
      常见的texture2d是两个维度的纹理,一张二维平面的纹理,通过uv(float2)进行颜色采样。texture3d则是三个维度的纹理,可能有人会把texture3d想象成texturecube(立体纹理贴图),但却是完全不一样的概念。texturecube可以看做6个texture2d贴到cube六个面,再通过viewpos到centerpos的reflect计算进行采样。
      而texture3d就像一个三维实体的切片纹理组成的集合,按照百度百科说的人体切片就很形象(实际上真有人体切片,我在很早的科教频道中看过死亡的人体进行冰冻后按照0.2mm的厚度进行切片用于科学研究,造业)。texture3d主要应用在体绘制技术中,不同于我们常见的表面绘制(表面绘制就是只绘制表面,我们平时建模建个表面网格再通过texture2d mapping附贴图,穿模就露馅了),体绘制就是三维实体绘制,认为计算机渲染中三维物体和真实世界三维物体一样,则需要通过xyz三个维度进行纹理采样和映射,才能给体绘制的三维物体着色。这类技术我以前在物理仿真、几何构型等计算机技术方向看过,而某些游戏中也有类似的应用,比如物体随机破碎(当然物体破碎也不一定是体绘制,也可以做模型切割补面后再映射新texture2d)。
      那么texture3d怎么用呢?先来看看unity的用法:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;public class EditorCreateTexture3DTest : Editor
{[MenuItem("GameTools/CreateTexture3D")]static void CreateTexture3D(){// Configure the textureint size = 128;TextureFormat format = TextureFormat.RGBA32;TextureWrapMode wrapMode = TextureWrapMode.Clamp;// Create the texture and apply the configurationTexture3D texture = new Texture3D(size, size, size, format, false);texture.wrapMode = wrapMode;// Create a 3-dimensional array to store color dataColor[] colors = new Color[size * size * size];// Populate the array so that the x, y, and z values of the texture will map to red, blue, and green colorsfloat 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);}}}// Copy the color values to the texturetexture.SetPixels(colors);// Apply the changes to the texture and upload the updated texture to the GPUtexture.Apply();// Save the texture to your Unity ProjectAssetDatabase.CreateAsset(texture, "Assets/Texture3DApply/testtexture3d.asset");}
}

创建的texture3d如下:

      可以看得出来texture3d的表现形式(虽然unity显示球体,但实际上是立方体),同时容量超过同分辨率的texture2d一个分辨率倍,81024/64=128,可以想象成128个128128的texture2d叠放成立方体。
      接下来我们使用一下:
      首先创建一个可以改变z轴的长方体,如下:
      cs代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class TestCubeMeshCreate : MonoBehaviour
{public float dimenLength = 5f;[Range(0.1f, 5f)]public float zDimen = 1f;public Material tex3dMat;private MeshFilter meshFilter;private MeshRenderer meshRender;private Mesh mesh;private float oldZDimen = 0f;void Start(){meshFilter = GetComponent<MeshFilter>();meshRender = GetComponent<MeshRenderer>();meshRender.material = tex3dMat;}void Update(){if (oldZDimen != zDimen){UpdateMesh(zDimen);oldZDimen = zDimen;}}private void UpdateMesh(float zdimen){if (mesh != null){mesh.Clear();}mesh = new Mesh();mesh.vertices = new Vector3[]{new Vector3(0,dimenLength,0),new Vector3(dimenLength,dimenLength,0),new Vector3(dimenLength,0,0),new Vector3(0,0,0),new Vector3(0,dimenLength,zDimen),new Vector3(dimenLength,dimenLength,zDimen),new Vector3(dimenLength,0,zDimen),new Vector3(0,0,zDimen),};//因为vector2的uv维度不够,所以只能用normals做三维纹理映射float nz = zdimen / dimenLength;mesh.normals = new Vector3[]{new Vector3(0,1,0),new Vector3(1,1,0),new Vector3(1,0,0),new Vector3(0,0,0),new Vector3(0,1,nz),new Vector3(1,1,nz),new Vector3(1,0,nz),new Vector3(0,0,nz),};mesh.triangles = new int[]{0,1,2,0,2,3,0,4,5,0,5,1,1,5,6,1,6,2,2,6,7,2,7,3,3,7,4,3,4,0,5,4,7,5,7,6};meshFilter.sharedMesh = mesh;}
}

再写个shader进行三维uvw采样:

Shader "Texture3DApply/Texture3DMappingShader"
{Properties{_3DTex ("Texture3D", 3D) = "white" {}}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float3 normal : NORMAL;};struct v2f{float3 normal : NORMAL;float4 vertex : SV_POSITION;};sampler3D _3DTex;float4 _3DTex_ST;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.normal = v.normal;return o;}fixed4 frag (v2f i) : SV_Target{fixed4 col = tex3D(_3DTex, i.normal);return col;}ENDCG}}
}

效果如下:

      gif工具的压缩率还是挺恐怖的,渐变色都压缩成马赛克块了,实际采样是这样:
      可以看得出来,我们使用三个维度的采样计算后,就可以将体绘制表现出来。
      好,以后有时间聊聊texture3d的应用,刚好有个需求有应用到。

入门图形学:Texture3D相关推荐

  1. 入门图形学:平直着色和平滑着色

    真是在老家关得有点郁闷了,不晓得这疫情什么时候结束.虽然我个人非常喜欢放假,因为有更多时间学习.玩游戏和搞自己的事情.不过这次疫情时间掐得太准了,刚好是放年假回老家拜年的时间,直接把我关在老家四十天, ...

  2. 入门图形学:透明原理

    因为我们后面要大量使用透明效果(或者说透明效果是实现我们需要的着色特效的基础部分),所以这里就来非常通俗详细说一下透明的原理. 先来从最简单易懂的二维层面来讲解. 我猜大家使用最常见的透明效果就是在u ...

  3. 入门图形学:图形学原理(三)

    紧接上一篇:https://blog.csdn.net/yinhun2012/article/details/79984729 之前我们了解了计算机图形显示所需要的两个重要硬件(显示器和GPU),现在 ...

  4. 入门图形学:图形学原理(一)

    前面我们闲聊谈到作为一个准备长期坚持在研发道路上的程序员,怎么样才能保证自己所学的知识属于持久长存的,而不至于在新老交替的时候淘汰掉.那么什么知识属于保质期长久的呢?其中就谈到了理论,也就是也就是原理 ...

  5. 入门图形学:屏幕波爆特效

    最近bilibili看了黑神话悟空的UE5演示视频,感觉是真牛逼,地址:黑神花悟空UE5实机演示视频 遥想我也算是国内第一批用ue4的开发者了,15年开始用ue4.7源码版,做了一年多就又用回u3d了 ...

  6. 入门图形学:光照模型(四)

    紧接上一篇:https://blog.csdn.net/yinhun2012/article/details/80924102 上一篇我们用cg中比较常见的vertex fragment函数去实现了通 ...

  7. 入门图形学:光照模型(二)

    转载自: https://blog.csdn.net/yinhun2012/article/details/80912620 前面我们谈到了光照作用最终表面颜色公式,如下: 查看全文 http://w ...

  8. 入门图形学:武器光波特效

    再次安利一下这个视频,黑神话悟空 这里面战斗都太秀了,难度我凭观看感觉和黑魂血源有的一拼,我感觉我是打不过的,黑魂3的古达就把我虐死二三十次,血源更不说了,小怪我都打不赢,所以还是来实现一下其中的特效 ...

  9. 入门图形学:VR畸变后处理

    最近真的忙,项目需求大改,晚上还要复习成人英语考试.       新增了"一键生成VR"需求,在现有框架上预编译同步普通键鼠和VR手柄的操作.同步PC和VR的各种接口使用等,业务开 ...

  10. 入门图形学:图像二值化

    最近工程做图像处理和网格处理,顺便来记几篇博客.       二值化处理       在图像处理上,一般的图像(彩图)携带信息过多,用于计算处理方面就不适合,需要将图像进行灰度化->二值化.   ...

最新文章

  1. GeoIP的使用 - PHP版
  2. 共识机制-权益证明 PoS
  3. python获取文本框里输入的值_如何从Tkinter文本框小工具获取输入?
  4. Python:eval的妙用和滥用
  5. react-native-Cocoapods-Swift-Project
  6. 如何用一套引擎搞定机器学习全流程?
  7. WordPress:如何判断登录用户的角色
  8. 在IIS上部署ASP.NET Core Web API
  9. python快速入门及进阶
  10. 端口映射器与端口映射软件的区别及内网发布网站到外网的使用
  11. 【项目实战】Python基于决策树多分类模型实现水色图像的水质评价
  12. vue实例的参数说明
  13. java rxtx version_RXTX Version mismatch
  14. 什么是CIF/4CIF/QCIF/D1?
  15. 对龙果支付系统的简单了解
  16. mui框架从0到1【webapp开发教程】
  17. C 语言之父,UNIX 系统之父 Dennis Ritchie (丹尼斯 里奇)于 10 月 9 日去世,享年 70 岁
  18. 小胜凭智,大胜靠德|北京
  19. 如何让手机自带路由器,24小时wifi跟着你!知道后你就是大神!
  20. Spark的调度流程(任务调度+资源调度)

热门文章

  1. Reducer类——hadoop
  2. dll加壳c语言,使用VC自己动手编写加壳程序
  3. 自动化脚本开发,真香.....
  4. uniapp密码输入框
  5. 推荐!十个好用的百度网盘搜索引擎
  6. 【FinalIK】Full Body Biped IK
  7. 2014年总结——回眸过去
  8. oracle虚拟用户和密码,创建 Virtual Private Catalog(虚拟用户目录)(Oracle 11g)
  9. osgearth各版本源码下载
  10. 实验: 写一个.msstyles皮肤测试程序