zoukankan      html  css  js  c++  java
  • XDRender-EditorTool-ShaderGenTextureEditor 利用Shader生成纹理

    XDRender-EditorTool-ShaderGenTextureEditor 利用Shader生成纹理

    @Author: 白袍小道

    DaoZhang_XDZ@163.com

    image-20201103165642846

    image-20201103165715647

    前言


    这里是XDRender-Unity-Editor部分(Unreal部分是在另外一个分支)

    也属于程序化部分的编辑器部分, 程序化还包括运行时候(这部分需要有很多Feature比如程序化地形,动态曲线、纹理,骨骼动画等等)

    1、XDRender是个人Studio使用,那啥绕过.

    2、本来是在实现IBLut和一些纹理的烘培, 突然有这个Require就简单实现了

    如有错误, 以后再改 哈哈

    正文


    首先我们明确下我们要做的需求:

    1、Shader源文件的属性遍历和收集

    2、绘制Material在屏幕或者说对应的View下, 这里View为一个GUITexture(Unreal的话为widget或者C++(引擎层分配的Android/IOS给到的一个RT)

    理论


    实现


    1、收集Shader属性集, 由于这里是在UnityC#中, 所以我们先写一个简单的

    上层业务封装ShaderProperty便于业务使用

    public class XDShaderProperty
        {
            public int index;
            public ShaderPropertyType propertyType;
    
            public string ProName;
    
            public Color colorValue;
            public Vector4 vecValue;
            public float floatValue;
            public Texture texValue;
        }
    

    然后我们的目标就变成如何去构造数据

    public static void GetProperty(Shader pShader, out System.Collections.Generic.List<XDShaderProperty> protype)
            {
                protype = new List<XDShaderProperty>();
                int lenpro = pShader.GetPropertyCount();
                for (int i = 0; i < lenpro; i++)
                {
                    XDShaderProperty vProperty = new XDShaderProperty();
                    vProperty.index = i;
                    vProperty.ProName = pShader.GetPropertyName(i);
                    vProperty.propertyType = pShader.GetPropertyType(i);
                    protype.Add(vProperty);
                }
            }
    

    2、Material绘制

    ​ 利用CommandBuffer(这里为_buffer),

    ​ 2.1 设置TargetRT和需要用来擦除的背景数据

    ​ ( Depth设置1.0)

    ​ _buffer.SetRenderTarget(_rt);
    ​ _buffer.ClearRenderTarget(true, true, Color.black, 1.0f);

    ​ 2.2 设置ViewMatrix, ProjMatrix.

    ​ 由于这里我直接设置两个屏幕三角形的顶点坐标, 就不转矩阵了.

    _buffer.SetRenderTarget(_rt);
                _buffer.ClearRenderTarget(true, true, Color.black, 1.0f);
    
                for (int i = 0; i < protype.Count; i++)
                {
                    XDEngine_ShaderPropertyHelp.SetShaderProperty(protype[i],_mat);
                }
                _buffer.DrawMesh(_mesh, Matrix4x4.identity, _mat, 0);
                Graphics.ExecuteCommandBuffer(_buffer);
                _buffer.Clear();
    

    ​ 这里还有可以将Handle模式, 将Case后要做的存为具柄, 然后单独去执行. 这样会更好.

    void SetShaderProperty(XDShaderProperty pShaderProperty, Material pMat)
            {
                switch (pShaderProperty.propertyType)
                {
                    case ShaderPropertyType.Color:
                        pMat.SetColor(pShaderProperty.ProName, pShaderProperty.colorValue);
                        break;
    
                    case ShaderPropertyType.Float:
                        pMat.SetFloat(pShaderProperty.ProName, pShaderProperty.floatValue);
                        break;
    
                    case ShaderPropertyType.Vector:
                        pMat.SetVector(pShaderProperty.ProName, pShaderProperty.vecValue);
                        break;
    
                    case ShaderPropertyType.Texture:
                        pMat.SetTexture(pShaderProperty.ProName, pShaderProperty.texValue);
                        break;
                }
            }
    
           private void DrawMaterial()
            {
    
                _buffer.SetRenderTarget(_rt);
                _buffer.ClearRenderTarget(true, true, Color.black, 1.0f);
    
                for (int i = 0; i < protype.Count; i++)
                {
                    XDEngine_ShaderPropertyHelp.SetShaderProperty(protype[i],_mat);
                }
                _buffer.DrawMesh(_mesh, Matrix4x4.identity, _mat, 0);
                Graphics.ExecuteCommandBuffer(_buffer);
                _buffer.Clear();
            }
    

    3、编辑器的UI绘制部分

    void DrawShaderProperty(XDShaderProperty pShaderProperty)
            {
                switch (pShaderProperty.propertyType)
                {
                    case ShaderPropertyType.Color:
                        pShaderProperty.colorValue = EditorGUILayout.ColorField(pShaderProperty.ProName, pShaderProperty.colorValue);
                        break;
    
                    case ShaderPropertyType.Float:
                        pShaderProperty.floatValue = EditorGUILayout.FloatField(pShaderProperty.ProName, pShaderProperty.floatValue);
                        break;
    
                    case ShaderPropertyType.Vector:
                        pShaderProperty.vecValue = EditorGUILayout.Vector4Field(pShaderProperty.ProName, pShaderProperty.vecValue);
                        break;
    
                    case ShaderPropertyType.Texture:
                        pShaderProperty.texValue = (Texture)EditorGUILayout.ObjectField(pShaderProperty.texValue, typeof(Texture), false);
                        break;
                }
            }
          void OnGUI()
            {
                ///..........
                for (int i = 0; i < protype.Count; i++)
                {
                    XDEngine_ShaderPropertyEditorHelp.DrawShaderProperty(protype[i]);
                }
    
                _ShowRect.y = ((protype == null)? 20.0f: 30.0f + protype.Count * 30.0f);
                GUILayout.Label("----------------------------");
                GUI.DrawTexture(_ShowRect, _rt);
                ///..........
            }
            
    

    简单完成,大体就是这样了

    总结


    1、动态收集部分 抽取GamePlay的Editor模式业务工具,

    2、Shader屏幕绘制, 这里主要是用来做函数生成纹理

    备注

    人生当苦,笑着看看
  • 相关阅读:
    雨天的尾巴「线段树合并+树上差分」
    硬币购物「容斥+背包」
    消失之物「分治+背包」
    最小距离「多源最短路」
    任务分配「最短路+DP」
    LCA「树链剖分+线段树」
    组合计数基础
    SPOJ-QTREE4 Query on a tree IV
    K-D tree 区域查询复杂度证明
    bitset 求解高维偏序
  • 原文地址:https://www.cnblogs.com/BaiPao-XD/p/13921420.html
Copyright © 2011-2022 走看看