XDRender-EditorTool-ShaderGenTextureEditor 利用Shader生成纹理
@Author: 白袍小道
DaoZhang_XDZ@163.com
前言
这里是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屏幕绘制, 这里主要是用来做函数生成纹理