• unity官方教程 -- Hi Shader学习笔记 Chapter 1


    最近unity开了一个shader的入门教程,感觉还是蛮不错的,趁着这个机会写一个学习笔记吧。

    教程链接:Hi Shader - Unity中文课堂

    一、一个Gameobject的基本属性

    1.MeshFilter 网格过滤器与Mesh 网格

    Mesh 是指模型的网格,建模就是建网格。细看Mesh,可以知道Mesh的主要属性内容包括顶点坐标法线纹理坐标三角形绘制序列等其他有用属性和功能。

    而MeshFilter中包含Mesh属性,感觉可以理解为是一个Mesh的控制器,我们输入的Mesh数据最终是通过MeshFilter去选择并呈现出来的。如上图,我们可以在MeshFilter的Mesh属性中选择其他类型的Mesh,最终模型会呈现出不同的形状。

    可进一步参考:

    Unity中Mesh Filter、Mesh Renderer的作用_穿行高原的博客-CSDN博客_meshfilter

    一个Mesh通常会包含以下几种属性。

    1)Vertices 顶点数组 Vector3[]

    2)Topology 拓扑类型:可以理解为它是图形表面排列结构的组成方式,Unity给我们提供了5种拓扑类型,三角面、四边形、线条、虚线、点阵,最常用的则是三角面。往往由Index data 索引数据的个数决定是什么类型。

    3)Indices 索引数组 int[]:它是每个三角面顶点 的索引,可以理解为他存储了构网格三角面所用到的顶点索引。

    5)Normal 法线 Vector3[]

    6)Tangent 切线 Vector3[]

    7)UV 纹理坐标 Vector2[]:上面所说的UV坐标其实就是它,U增长的方向就是切线的方向,它和三维空间的X, Y, Z较为类似,它是一个二维的坐标系统,模型网格除了有三维空间的xyz坐标外,还有一个二维的UV坐标,在UV坐标中,U和V分别代表顶点在Texture水平和垂直方向上的采样坐标,这些坐标通常位于(0,0)和(1,1)之间,(0,0)代表最左下角,而(1,1)代表最右上角。这就跟平时装修房子贴墙纸一样,可以理解为它是Texture映射到模型表面的依据,模型顶点 会依据UV坐标对Texture进行采样。

    8)Index data 索引数据:这个数据取决于拓扑类型,如果是三角面他储存的就是[0,1,2],四边形储存的就是[0,1,2,3],这个索引数值对应的就是顶点数组的下标。

    2.MeshRenderer 网格渲染器与Material 材质球

    可以说MeshFilter 网格过滤器与Mesh 网格决定了这个物体是什么形状的,而MeshRenderer与Material决定这个gameobject会呈现出怎么样的色彩变化,Mesh是骨骼,Material是皮肤。

    与MeshFilter跟Mesh的关系类似。MeshRenderer 可以理解为是一个Material 的控制器,我们输入的Material 数据最终是通过MeshRenderer 去选择并呈现出来的。

    二、用脚本构建出一个正方体

    将下面的代码附在一个plane上,便可以看到通过脚本创建的正方体了。

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class CH1 : MonoBehaviour
    5. {
    6. // 顶点数组 模型空间顶点坐标
    7. Vector3[] vertices =
    8. {
    9. // Front
    10. // point[1]
    11. new Vector3(-2.0f, 5.0f, -2.0f),//[0]
    12. // point[2]
    13. new Vector3(-2.0f, 0.0f, -2.0f),//[1]
    14. // point[3]
    15. new Vector3(2.0f, 0.0f, -2.0f),//[2]
    16. // point[4]
    17. new Vector3(2.0f, 5.0f, -2.0f),//[3]
    18. // Left
    19. new Vector3(-2.0f, 5.0f, -2.0f),//[4]
    20. new Vector3(-2.0f, 0.0f, -2.0f),//[5]
    21. new Vector3(-2.0f, 0.0f, 2.0f),//[6]
    22. new Vector3(-2.0f, 5.0f, 2.0f),//[7]
    23. // Back
    24. new Vector3(-2.0f, 5.0f, 2.0f),//[8]
    25. new Vector3(-2.0f, 0.0f, 2.0f),//[9]
    26. new Vector3(2.0f, 0.0f, 2.0f),//[10]
    27. new Vector3(2.0f, 5.0f, 2.0f),//[11]
    28. // Right
    29. new Vector3(2.0f, 5.0f, 2.0f),//[12]
    30. new Vector3(2.0f, 0.0f, 2.0f),//[13]
    31. new Vector3(2.0f, 0.0f, -2.0f),//[14]
    32. new Vector3(2.0f, 5.0f, -2.0f),//[15]
    33. // Top
    34. new Vector3(-2.0f, 5.0f, 2.0f),//[16]
    35. new Vector3(2.0f, 5.0f, 2.0f),//[17]
    36. new Vector3(2.0f, 5.0f, -2.0f),//[18]
    37. new Vector3(-2.0f, 5.0f, -2.0f),//[19]
    38. // Bottom
    39. new Vector3(-2.0f, 0.0f, 2.0f),//[20]
    40. new Vector3(2.0f, 0.0f, 2.0f),//[21]
    41. new Vector3(2.0f, 0.0f, -2.0f),//[22]
    42. new Vector3(-2.0f, 0.0f, -2.0f),//[23]
    43. };
    44. // 索引数组
    45. int[] triangles =
    46. {
    47. // Front
    48. 2,1,0,
    49. 0,3,2,
    50. // Left
    51. 4,5,6,
    52. 4,6,7,
    53. // Back
    54. 9,11,8,
    55. 9,10,11,
    56. // Right
    57. 12,13,14,
    58. 12,14,15,
    59. // Top
    60. 16,17,18,
    61. 16,18,19,
    62. // Buttom
    63. 21,23,22,
    64. 21,20,23,
    65. };
    66. // UV数组
    67. Vector2[] uvs =
    68. {
    69. // point[1]
    70. new Vector2(0.0f, 1.0f),
    71. // point[2]
    72. new Vector2(0.0f, 0.0f),
    73. // point[3]
    74. new Vector2(1.0f, 0.0f),
    75. // point[4]
    76. new Vector2(1.0f, 1.0f),
    77. // Left
    78. new Vector2(1.0f, 1.0f),
    79. new Vector2(1.0f, 0.0f),
    80. new Vector2(0.0f, 0.0f),
    81. new Vector2(0.0f, 1.0f),
    82. // Back
    83. new Vector2(1.0f, 1.0f),
    84. new Vector2(1.0f, 0.0f),
    85. new Vector2(0.0f, 0.0f),
    86. new Vector2(0.0f, 1.0f),
    87. // Right
    88. new Vector2(1.0f, 1.0f),
    89. new Vector2(1.0f, 0.0f),
    90. new Vector2(0.0f, 0.0f),
    91. new Vector2(0.0f, 1.0f),
    92. // Top
    93. new Vector2(0.0f, 1.0f),
    94. new Vector2(1.0f, 1.0f),
    95. new Vector2(1.0f, 0.0f),
    96. new Vector2(0.0f, 0.0f),
    97. // Bottom
    98. new Vector2(0.0f, 0.0f),
    99. new Vector2(1.0f, 0.0f),
    100. new Vector2(1.0f, 1.0f),
    101. new Vector2(0.0f, 1.0f),
    102. };
    103. // Start is called before the first frame update
    104. void Start()
    105. {
    106. GameObject g = new GameObject("MyCube");
    107. g.AddComponent();
    108. g.AddComponent();
    109. // 新建一个Mesh
    110. Mesh mesh = new Mesh();
    111. // 用构建的数据初始Mesh
    112. mesh.vertices = vertices;
    113. mesh.triangles = triangles;
    114. mesh.uv = uvs;
    115. // 法线是根据顶点数据计算出来的,所以在修改完顶点后,需要更新一下法线
    116. mesh.RecalculateNormals();
    117. // 将构建好的Mesh替换上
    118. g.GetComponent().mesh = mesh;
    119. g.GetComponent().material = gameObject.GetComponent().material;
    120. }
    121. }

  • 相关阅读:
    深度学习项目部署遇到的错误【记录】
    高数_第3章重积分_二重积分_极坐标形式来计算
    C语言编译与链接
    如何看待程序员不写注释
    Discord OAuth2授权以及机器人监听群事件
    计算机毕业设计Java进出口食品安全信息管理系统(源码+系统+mysql数据库+lw文档)
    钡铼R40边缘计算网关与华为云合作,促进物联网传感器数据共享与应用
    记录一个 Hudi HBase 依赖冲突问题及解决方案
    后端接入层技术的一些思考
    解决js代码中加入alert就成功执行请求接口,不加就不执行的问题
  • 原文地址:https://blog.csdn.net/qq_42987967/article/details/126614682