程序纹理指的是由那些计算机生成的图像,我们通常使用一些特定的算法来创建个性化图案或非常真实的自然元素,例如木头、石子等。使用程序纹理的好处在于我们可以使用各种参数来控制纹理的外观,而这些属性不仅仅是那些颜色属性,甚至可以是完全不同类型的图案属性,这使得我们可以得到更加丰富的动画和视觉效果。本篇文章我们尝试用算法来实现一个简单的程序纹理和程序材质。

一、unity中实现简单的程序纹理

我们使用一个算法来生成一个波点纹理,如下图:

我们可以在脚本中调整一下参数,如背景颜色、波点颜色等,以控制最终生成的纹理外观。

实现:

1.首先创建一个材质,不用赋值任何纹理,因为要用脚本来生成程序纹理,创建工具脚本ProceduralTextureGeneration.cs。

2.为了让该脚本可以在编辑器模式下运行,我们首先在类的开头添加:

[ExecuteInEditMode]
public class ProceduralTextureGeneration : MonoBehaviour {

3.声明一个材质,这个材质将使用该脚本中生成的程序纹理:

public Material material = null;

4.然后声明该程序纹理使用的各种参数:

#region Material properties[SerializeField, SetProperty("textureWidth")]private int m_textureWidth = 512;public int textureWidth {get {return m_textureWidth;}set {m_textureWidth = value;_UpdateMaterial();}}[SerializeField, SetProperty("backgroundColor")]private Color m_backgroundColor = Color.white;public Color backgroundColor {get {return m_backgroundColor;}set {m_backgroundColor = value;_UpdateMaterial();}}[SerializeField, SetProperty("circleColor")]private Color m_circleColor = Color.yellow;public Color circleColor {get {return m_circleColor;}set {m_circleColor = value;_UpdateMaterial();}}[SerializeField, SetProperty("blurFactor")]private float m_blurFactor = 2.0f;public float blurFactor {get {return m_blurFactor;}set {m_blurFactor = value;_UpdateMaterial();}}#endregion

由于我们生成的纹理是由若干圆点构成的,因此在上面代码中声明了四个纹理属性:纹理的大小,通常是2的整数幂;纹理的背景颜色;圆点的颜色;模糊因子,这个参数是用来模糊圆形边界的。每个属性我们使用了get/set方法,为了在面板上修改属性时仍可以执行set函数,使用了一个开源插件SetProperty。这使得我们修改了材质属性时,可以执行_UpdateMaterial函数来使用新的属性重新生成程序纹理。

5.为了保存生成的程序纹理,声明一个Texture2D类型的纹理变量:

private Texture2D m_generatedTexture = null;

6.下面开始编写各个函数,首先需要在start函数中进行相应的检查,以得到需要使用该程序纹理的材质:

// Use this for initializationvoid Start () {if (material == null) {Renderer renderer = gameObject.GetComponent<Renderer>();if (renderer == null) {Debug.LogWarning("Cannot find a renderer.");return;}material = renderer.sharedMaterial;}_UpdateMaterial();}

如果material为空尝试从该物体上得到相应材质,检查完成后调用_UpdateMaterial函数来为其生成程序纹理。

7._UpdateMaterial函数代码:

private void _UpdateMaterial() {if (material != null) {m_generatedTexture = _GenerateProceduralTexture();material.SetTexture("_MainTex", m_generatedTexture);}}

调用_GenerateProceduralTexture()函数来生成一张程序纹理,并赋值给纹理变量最后赋值给材质中的纹理属性。

8._GenerateProceduralTexture()函数代码:

private Color _MixColor(Color color0, Color color1, float mixFactor) {Color mixColor = Color.white;mixColor.r = Mathf.Lerp(color0.r, color1.r, mixFactor);mixColor.g = Mathf.Lerp(color0.g, color1.g, mixFactor);mixColor.b = Mathf.Lerp(color0.b, color1.b, mixFactor);mixColor.a = Mathf.Lerp(color0.a, color1.a, mixFactor);return mixColor;}private Texture2D _GenerateProceduralTexture() {Texture2D proceduralTexture = new Texture2D(textureWidth, textureWidth);// The interval between circlesfloat circleInterval = textureWidth / 4.0f;// The radius of circlesfloat radius = textureWidth / 10.0f;// The blur factorfloat edgeBlur = 1.0f / blurFactor;for (int w = 0; w < textureWidth; w++) {for (int h = 0; h < textureWidth; h++) {// Initalize the pixel with background colorColor pixel = backgroundColor;// Draw nine circles one by onefor (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {// Compute the center of current circleVector2 circleCenter = new Vector2(circleInterval * (i + 1), circleInterval * (j + 1));// Compute the distance between the pixel and the centerfloat dist = Vector2.Distance(new Vector2(w, h), circleCenter) - radius;// Blur the edge of the circleColor color = _MixColor(circleColor, new Color(pixel.r, pixel.g, pixel.b, 0.0f), Mathf.SmoothStep(0f, 1.0f, dist * edgeBlur));// Mix the current color with the previous colorpixel = _MixColor(pixel, color, color.a);}}proceduralTexture.SetPixel(w, h, pixel);}}proceduralTexture.Apply();return proceduralTexture;}

代码首先初始化一张二维纹理,并且提前计算了一些生成纹理时需要的变量。然后使用了一个两层的嵌套循环遍历纹理中的每个像素,并在纹理上依次绘制9个圆形,最后利用Texture2D.Apply函数来强制把像素值写入纹理中,并返回该程序纹理。后面可以调整脚本面板中的参数来得到不同的程序纹理了。

二、unity的程序材质

在unity中有一类专门使用程序纹理的材质,叫程序材质,它们本质上和那些普通材质是一样的,不同的是它们使用的纹理不是普通纹理,而是程序纹理。程序材质和它使用的程序纹理不是在unity中创建的,而是使用了一个名为Substance Designer的软件在unity外部生成的。

Substance Designer是一个非常出色的纹理生成工具,很多3A游戏项目都使用了它生成的材质,后缀是.sbsar。当把这些文件导入unity后会生成一个程序纹理资源,程序纹理资源可以包含一个或多个程序材质,每个程序纹理都使用了不同的纹理参数,因此unity为他们生成了不同的程序纹理。

程序材质的使用和普通材质一样,拖拽到模型上即可,程序纹理的强大之处在于它的多变性,我们可以通过调整程序纹理的属性来控制程序纹理的外观。程序材质的自由度很高,他可以和shader配合得当非常出色的视觉效果,是一种非常强大的材质类型。

(十七)unity shader之——————高级纹理之程序纹理相关推荐

  1. Unity shader Note :高级纹理(CubeMap反射折射菲涅尔,Rendermap镜子玻璃,程序纹理)

    1.Cubemap–反射折射 使用脚本来创建Cubemap ①通过Camera.RenderToCubemap 把任意位置观察到的场景图制作成一张Cubemap之中 ②脚本使用自定义编译窗体的命令 – ...

  2. 【Unity Shader入门精要】普通纹理和高级纹理

    原作者博客链接:http://blog.csdn.net/candycat1992/article/  书籍链接:http://product.dangdang.com/23972910.html 纹 ...

  3. (十六)unity shader之——————高级纹理之渲染纹理(镜子、玻璃效果)

    在之前的学习中,一个摄像机的渲染结果会输出到颜色缓冲中,并显示到我们的屏幕上.现在的GPU允许我们把整个三维场景渲染到一个中间缓冲中,即渲染目标纹理(Render Target Texture,RTT ...

  4. 【unity shader】高级光照 --- 薄膜干涉

    -光照模型是shader编程的核心与基础. 一般的光照模型–不管是lambert还是phong–其实都是对现实光照的模拟. 但是现实中的光照效果要复杂得多.但就光的反射而言, 薄膜干涉就是一种非常常见 ...

  5. Real-Time Rendering——6.3 Procedural Texturing程序纹理

    Given a texture-space location, performing an image lookup is one way of generating texture values. ...

  6. Unity Shader总结(十)——Cubemap、镜子、玻璃、程序纹理

    文章目录 天空盒 创建立方体纹理 环境映射 反射 折射 菲涅尔反射 渲染纹理(RenderTexture) 镜子效果 玻璃效果 渲染纹理和GrabPass的不同 程序纹理 程序材质 Cubemap是环 ...

  7. 【Unity Shader】(八) ------ 高级纹理之立方体纹理及光线反射、折射的实现

    笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ----- ...

  8. 《Unity Shader入门精要》笔记:高级篇(3)以及扩展

    本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...

  9. Unity Shader入门精要第七章 基础纹理之遮罩纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.实践 参考 前言 遮罩纹理(mask texture)是本章要介绍的最后一种纹理,它非常有用,在很多商业游戏中 都可以见到它的身影. ...

最新文章

  1. Oracle后台进程
  2. 使用帆软finereport实现跳转的一点心得
  3. 同一公司代码下工厂间的库存转储 (轉載)
  4. mysql 使用 utf8mb4 编码
  5. [导入]用Javascript实现interface的类似功能
  6. C语言程序设计 | 模拟实现内存操作函数:strncpy, strncat, strncmp, memcpy, memmove
  7. 用Enterprise Library开发应用程序 --- Enterprise Library - January 2006 翻译 第二部分
  8. TODO-MVP-Loaders源码体验
  9. Bootstrap学习笔记01
  10. Information worker
  11. C++程序员必需的修养
  12. iTween 动画类型
  13. Leetcode动态规划:300.longest-increasing-subsequence(最长递增子序列)
  14. 【jQuery实例】Ajax登录页面
  15. mysql prepare语法_MySQL prepare语句的SQL语法
  16. 开源FTP 服务器 FileZilla Server
  17. 案例|工业物联网解决方案•工业互联网云平台
  18. cloudcompare:怎么换背景颜色
  19. 通过Java 画一个太极图
  20. 2019江西(南昌)安博会 数字冰雹“警视”即将惊艳亮相

热门文章

  1. 高速物理光学仿真概念简介
  2. python做ui界面_用python编写简单ui界面窗口
  3. 【81期分享】4款教学课件PPT模板免费下载
  4. ABP 命令添加模块
  5. 芒果TV广告投放的展现形式、优势介绍!
  6. webrtc的windows编译MDd或MD修改
  7. 用 K60 的 UART 串口通信改变程序中的参数值
  8. RFIC4463_F2B
  9. 业务问题:用java将加密的pdf文件转化为图片问题,支持png,jpg,pdf互转
  10. 前端项目自动化部署——超详细教程(Jenkins、Github Actions)(转发)