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屏幕绘制, 这里主要是用来做函数生成纹理

备注

posted @ 2020-11-03 17:22  白袍小道  阅读(122)  评论(0编辑  收藏  举报

白袍小道 DaoZhang_XDZ@163.com - 创建于 8012

窥探道理