当前位置:   article > 正文

Shader学习的基础知识(十五)程序纹理_mixcolor:white

mixcolor:white

程序纹理指的是指那些用计算生的成的图像,通常使用一些特定的算法来创建个性化图案。其实就是把图像计算完成后再过赋予材质做显示。下面用一个简单的例子来说明,程序计算生成一个主图后赋予_MainTex直接以漫反射形式显示。

CS部分代码:

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. [ExecuteInEditMode]
  5. public class ProceduralTextureGeneration : MonoBehaviour {
  6. public Material material = null;
  7. #region Material properties
  8. [SerializeField, SetProperty("textureWidth")]
  9. private int m_textureWidth = 512;
  10. public int textureWidth {
  11. get {
  12. return m_textureWidth;
  13. }
  14. set {
  15. m_textureWidth = value;
  16. _UpdateMaterial();
  17. }
  18. }
  19. [SerializeField, SetProperty("backgroundColor")]
  20. private Color m_backgroundColor = Color.white;
  21. public Color backgroundColor {
  22. get {
  23. return m_backgroundColor;
  24. }
  25. set {
  26. m_backgroundColor = value;
  27. _UpdateMaterial();
  28. }
  29. }
  30. [SerializeField, SetProperty("circleColor")]
  31. private Color m_circleColor = Color.yellow;
  32. public Color circleColor {
  33. get {
  34. return m_circleColor;
  35. }
  36. set {
  37. m_circleColor = value;
  38. _UpdateMaterial();
  39. }
  40. }
  41. [SerializeField, SetProperty("blurFactor")]
  42. private float m_blurFactor = 2.0f;
  43. public float blurFactor {
  44. get {
  45. return m_blurFactor;
  46. }
  47. set {
  48. m_blurFactor = value;
  49. _UpdateMaterial();
  50. }
  51. }
  52. #endregion
  53. private Texture2D m_generatedTexture = null;
  54. // Use this for initialization
  55. void Start () {
  56. if (material == null) {
  57. Renderer renderer = gameObject.GetComponent<Renderer>();
  58. if (renderer == null) {
  59. Debug.LogWarning("Cannot find a renderer.");
  60. return;
  61. }
  62. material = renderer.sharedMaterial;
  63. }
  64. _UpdateMaterial();
  65. }
  66. private void _UpdateMaterial() {
  67. if (material != null) {
  68. m_generatedTexture = _GenerateProceduralTexture();
  69. material.SetTexture("_MainTex", m_generatedTexture);
  70. }
  71. }
  72. private Color _MixColor(Color color0, Color color1, float mixFactor) {
  73. Color mixColor = Color.white;
  74. mixColor.r = Mathf.Lerp(color0.r, color1.r, mixFactor);
  75. mixColor.g = Mathf.Lerp(color0.g, color1.g, mixFactor);
  76. mixColor.b = Mathf.Lerp(color0.b, color1.b, mixFactor);
  77. mixColor.a = Mathf.Lerp(color0.a, color1.a, mixFactor);
  78. return mixColor;
  79. }
  80. private Texture2D _GenerateProceduralTexture() {
  81. Texture2D proceduralTexture = new Texture2D(textureWidth, textureWidth);
  82. // The interval between circles
  83. float circleInterval = textureWidth / 4.0f;
  84. // The radius of circles
  85. float radius = textureWidth / 10.0f;
  86. // The blur factor
  87. float edgeBlur = 1.0f / blurFactor;
  88. for (int w = 0; w < textureWidth; w++) {
  89. for (int h = 0; h < textureWidth; h++) {
  90. // Initalize the pixel with background color
  91. Color pixel = backgroundColor;
  92. // Draw nine circles one by one
  93. for (int i = 0; i < 3; i++) {
  94. for (int j = 0; j < 3; j++) {
  95. // Compute the center of current circle
  96. Vector2 circleCenter = new Vector2(circleInterval * (i + 1), circleInterval * (j + 1));
  97. // Compute the distance between the pixel and the center
  98. float dist = Vector2.Distance(new Vector2(w, h), circleCenter) - radius;
  99. // Blur the edge of the circle
  100. Color color = _MixColor(circleColor, new Color(pixel.r, pixel.g, pixel.b, 0.0f), Mathf.SmoothStep(0f, 1.0f, dist * edgeBlur));
  101. // Mix the current color with the previous color
  102. pixel = _MixColor(pixel, color, color.a);
  103. }
  104. }
  105. proceduralTexture.SetPixel(w, h, pixel);
  106. }
  107. }
  108. proceduralTexture.Apply();
  109. return proceduralTexture;
  110. }
  111. }

Shader部分代码:

  1. Shader "Custom/TestShader23" {
  2. Properties {
  3. _Color ("Color Tint", Color) = (1, 1, 1, 1)
  4. _MainTex ("Main Tex", 2D) = "white" {}
  5. _Specular ("Specular", Color) = (1, 1, 1, 1)
  6. _Gloss ("Gloss", Range(8.0, 256)) = 20
  7. }
  8. SubShader {
  9. Pass {
  10. Tags { "LightMode"="ForwardBase" }
  11. CGPROGRAM
  12. #pragma vertex vert
  13. #pragma fragment frag
  14. #include "Lighting.cginc"
  15. fixed4 _Color;
  16. sampler2D _MainTex;
  17. float4 _MainTex_ST;
  18. fixed4 _Specular;
  19. float _Gloss;
  20. struct a2v {
  21. float4 vertex : POSITION;
  22. float3 normal : NORMAL;
  23. float4 texcoord : TEXCOORD0;
  24. };
  25. struct v2f {
  26. float4 pos : SV_POSITION;
  27. float3 worldNormal : TEXCOORD0;
  28. float3 worldPos : TEXCOORD1;
  29. float2 uv : TEXCOORD2;
  30. };
  31. v2f vert(a2v v) {
  32. v2f o;
  33. o.pos = UnityObjectToClipPos(v.vertex);
  34. o.worldNormal = UnityObjectToWorldNormal(v.normal);
  35. o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
  36. o.uv = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
  37. // Or just call the built-in function
  38. // o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
  39. return o;
  40. }
  41. fixed4 frag(v2f i) : SV_Target {
  42. fixed3 worldNormal = normalize(i.worldNormal);
  43. fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
  44. // Use the texture to sample the diffuse color
  45. fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;
  46. fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
  47. fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(worldNormal, worldLightDir));
  48. fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
  49. fixed3 halfDir = normalize(worldLightDir + viewDir);
  50. fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);
  51. return fixed4(ambient + diffuse + specular, 1.0);
  52. }
  53. ENDCG
  54. }
  55. }
  56. FallBack "Specular"
  57. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/108318
推荐阅读
相关标签
  

闽ICP备14008679号