shader入门精要读书笔记24 高级纹理-程序纹理

一、前言

程序纹理就是指由计算机生成的图像,我们可以通过各种参数来控制纹理的外观,这些属性不仅仅是颜色属性,还可以是完全不同类型的图案属性,可以使我们得到更丰富的动画和视觉效果。

二、实现程序纹理

简单思想:先创建一个材质,然后给它使用之前学过的单张纹理Shader,因为我们没有纹理,所以在应用材质的模型身上挂载脚本-程序纹理来进行创建赋值。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[ExecuteInEditMode]   //允许代码在编辑器模式下运行
public class ProceduralTextureGeneration : MonoBehaviour {

	public Material material = null;   //声明材质

	#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

	private Texture2D m_generatedTexture = null;  //声明一个Texture2D纹理变量

	// Use this for initialization
	void Start () {
		if (material == null) {										//进行材质和render组件判断并使用	
			Renderer renderer = gameObject.GetComponent<Renderer>();
			if (renderer == null) {
				Debug.LogWarning("Cannot find a renderer.");
				return;
			}

			material = renderer.sharedMaterial;   //从物体组件上获取材质
		}

		_UpdateMaterial();
	}

	private void _UpdateMaterial() {		//这个函数可以在修改属性时进行更新纹理
		if (material != null) {
			m_generatedTexture = _GenerateProceduralTexture();   //函数用于生成程序纹理
			material.SetTexture("_MainTex", m_generatedTexture);    //材质中有_MainTex,将程序纹理赋值
		}
	}

	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);	//初始化一个2D纹理,

		float circleInterval = textureWidth / 4.0f;		//设置圆圈间距

		float radius = textureWidth / 10.0f;		//定义圆半径

		float edgeBlur = 1.0f / blurFactor;		//定义模糊系数

		for (int w = 0; w < textureWidth; w++) {		//两个for循环,循环遍历每个像素。
			for (int h = 0; h < textureWidth; h++) {

				Color pixel = backgroundColor;		//背景颜色像素

				for (int i = 0; i < 3; i++) {		//两个for循环用来画圆更新圆的像素颜色
					for (int j = 0; j < 3; j++) {
						
						Vector2 circleCenter = new Vector2(circleInterval * (i + 1), circleInterval * (j + 1));		//找到圆心

						float dist = Vector2.Distance(new Vector2(w, h), circleCenter) - radius;	//计算当前像素和圆心之间的像素

						Color color = _MixColor(circleColor, new Color(pixel.r, pixel.g, pixel.b, 0.0f), Mathf.SmoothStep(0f, 1.0f, dist * edgeBlur));	//将像素源颜色和圆的颜色混合

						pixel = _MixColor(pixel, color, color.a);	//更新像素颜色
					}
				}

				proceduralTexture.SetPixel(w, h, pixel);	//设置纹理颜色
			}
		}

		proceduralTexture.Apply();		//强制写入纹理

		return proceduralTexture;		//返回程序纹理
	}
}

三、Unity的程序材质

Unity的程序材质是一种专门使用程序纹理的,它和正常材质本质上一样,不同就在于它使用程序纹理,这个材质不是在Unity中创建的,它是通过一个外面的软件 Substance Designer ,在外部生成的。

Substance Designer是一个非常出色的纹理生成工具,很多3A游戏都有使用它来生成材质,在资源商店可以获取很多Substance的后缀为.sbsar的材质。

这些材质导入Unity后会生成一个程序纹理资源,这些程序纹理资源可以包含一个或多个程序材质,每个程序纹理会使用不同的参数,Unity也会为他们生成不同的程序纹理。

程序纹理强大在于它们的多变性,自由度高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值