当前位置: 首页 > article >正文

C# shader 生成程序纹理

1、程序纹理是什么

程序纹理(Procedural Textures)就是通过程序代码生成的纹理

2、程序纹理如何生成

一般生成程序纹理由两种方式:

  • 通过C#脚本生成纹理后传递给Shader
  • 直接在Shader代码中自定义逻辑生成纹理

3、程序纹理的好处

程序纹理由于是由程序员写代码动态生成的,因此它具备以下优点:

  • 由于是动态生成,不需要存储大文件,可以在运行时生成任意分辨率的纹理
  • 可以根据需求调整自定义参数,实时的更改纹理外观
  • 通过适当的函数设计,可以生成无缝平铺的纹理

总体而言:程序纹理的最明显好处就是自由度高,可控性强

4、C# 程序生成

生成一个国际象棋棋盘网格,规则是:格子的行列编号同奇同偶则为白色,否则为黑色

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

/// <summary>
/// 生成一个国际象棋网格
/// </summary>
public class DynamicGenTex : MonoBehaviour
{
    public int textureWidth = 256;
    public int textureHeight = 256;
    public int tileCount = 8;
    private int pixelPerUnit;
    

    public Color Color1 = Color.white;
    public Color Color2 = Color.black;


    void Start()
    {
        UpdateTexture();
    }

    /// <summary>
    /// 更新纹理
    /// </summary>
    public void UpdateTexture() {
        pixelPerUnit = textureWidth / tileCount;
        Texture2D tex = new Texture2D(textureWidth, textureHeight);

        for (int y = 0; y < textureHeight; y++) {
            for (int x = 0; x < textureWidth; x++) {
                int row = x / pixelPerUnit;
                int col = y / pixelPerUnit;

                if (row % 2 == col % 2) 
                    tex.SetPixel(x, y, Color1);
                else
                    tex.SetPixel(x, y, Color2);
            }
        }
        // 应用像素的变化
        tex.Apply();

        Renderer renderer = this.GetComponent<Renderer>();
        if (renderer != null) {
            renderer.sharedMaterial.mainTexture = tex;
        }
    }
}

但是现在必须在运行时才能看见,所以可以通过自定义Inspector窗口调用函数

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

[CustomEditor(typeof(DynamicGenTex))]
public class DynamicGenTex_Editor : Editor
{
    public override void OnInspectorGUI() {
        base.OnInspectorGUI();

        // 获取目标脚本
        DynamicGenTex obj = (DynamicGenTex)target;
        if (GUILayout.Button("更新程序纹理")) {
            obj.UpdateTexture();
        }

    }
}

5、Shader 生成纹理

Shader "ShaderProj/7/DynamicGenTex"
{
    Properties
    {
       _TileCount ("TileCount", Float) = 8
       _Color1 ("Color1", Color) = (1,1,1,1)
       _Color2 ("Color2", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            float _TileCount;
            float4 _Color1;
            float4 _Color2;

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata_base v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.texcoord;

                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                float2 uv = i.uv * _TileCount;
                float2 posIndex = floor(uv);
                float value = (posIndex.x + posIndex.y) % 2;

                return lerp(_Color1, _Color2, value);
            }
            ENDCG
        }
    }
}


http://www.kler.cn/news/357825.html

相关文章:

  • 工厂函数与测试数据
  • 手机中的ip地址是什么意思?可以改手机ip地址吗
  • Ansible自动化运维项目实战指南
  • SLACC Simion-based Language Agnostic Code Clones
  • Java 中 String、StringBuffer 和StringBuilder的用法及区别
  • 轻松上手青龙面板:如何在本地Linux服务器中安装和使用
  • k8s权限控制RBAC中的clusterrole serviceaccount rolebinding 有什么作用
  • Django学习(三)
  • 用大模型或者预训练模型对图片进行OCR
  • Elasticsearch是做什么的?
  • python中堆的用法
  • C++学习路线(二十)
  • 大模型~合集14
  • vue3--自定义 dialog
  • 【重学 MySQL】六十七、解锁检查约束,守护数据完整性
  • 从零开始学PHP之安装开发环境
  • Android Jetpack 之再谈 ViewModel
  • 2024全国大学生软件测试大赛-校内练习题-京东、网易(功能)
  • 3d NMDS多样性分析图 R语言
  • 微信小程序中的文件查看方法