范畴 | CPU | GPU |
---|---|---|
二进制文件 | .exe | .cso / .ps |
二进制指令 | 机器码 | CSO(shader指令) |
助记符 | 汇编 | SL |
高级语言 | C# | HLSL |
高级语言文件 | .cs | .hlsl / .fx |
高级语言编译器 | csc.exe | fxc.exe |
API | .NET API | DirectX API |
运行时环境 | CLR | DirectX |
调试工具 | Visual Studio Debugger | RenderDoc |
着色器简称 | 着色器名 | 解释 |
---|---|---|
cs_4_0 | Compute Shader model 4.0 | 计算着色器,用于处理非图形计算任务 |
ds_5_0 | Domain Shader model 5.0 | 域着色器,用于曲面细分技术中,生成顶点后处理顶点数据 |
fx_2_0 | Effect model 2.0 | 效果文件,用于组合多个渲染状态和着色器程序,方便管理和使用 |
gs_4_0 | Geometry Shader model 4.0 | 几何着色器,能接收一些图形形状作为输入,并输出其他形状,用于生成新顶点和图形 |
hs_5_0 | Hull Shader model 5.0 | 曲面控制着色器,用于图形的曲面细分 |
ps_2_0 | Pixel Shader model 2.0 | 像素着色器,用于计算像素颜色 |
tx_1_0 | Texture Shader model 1.0 (software) | 纹理着色器,主要用于处理纹理映射 |
vs_1_1 | Vertex Shader model 1.1 | 顶点着色器,用于处理每个顶点数据 |
3DS Max
,接着添加一个茶壶Direct9
,我们现在用的是Direct11
,语法有点差异3DS Max
,按下快捷键M
,或者点击材质编辑器物理材质
切换自己写的shaderDirectX Shader
材质可以事先在桌面上新建一个txt文件,然后把扩展名改为.fx,可以使用vscode或者visualStudio下载HLSL扩展进行编辑
这列我提供一个Direct11的最简单的纯色着色器效果文件solidColor.fx
// solidColor.fx
//世界投影矩阵
//用来将顶点从模型空间转换到最终的裁剪空间
float4x4 WorldViewProjection : WorldViewProjection < string UIWidget="None"; >;
//UI面板项目
float4 SolidColor
<
string UIWidget = "Color";
string UIName="Solid Color";
> = float4(1.0f, 1.0f, 1.0f, 1.0f);
struct VertexShaderInput
{
//顶点着色器输入用这个语义
//表示顶点的位置信息
//模型空间(或世界空间)中定义的
float4 Position : POSITION;
};
struct VertexShaderOutput
{
//顶点着色器输出用这个语义
//表示顶点在裁剪空间(Clip Space)中的位置
//用来决定顶点在屏幕上位置的空间
float4 Position : SV_Position;
};
struct PixelShaderOutput
{
float4 Color : SV_TARGET;
};
//================== 简单的顶点着色器函数
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
// 计算最终的顶点位置
output.Position = mul(input.Position, WorldViewProjection);
return output;
}
//=============== 基本像素着色器函数
PixelShaderOutput PixelShaderFunction()
{
PixelShaderOutput output;
// 设置像素颜色为 SolidColor 定义的颜色
output.Color = SolidColor;
return output;
}
// 定义渲染效果
//Direct9写technique
//Direct10写technique10
//Direct11写technique11
technique11 SolidColorTechnique
{
pass P0
{
// 基本顶点着色器
VertexShader = compile vs_5_0 VertexShaderFunction();
// 基本像素着色器
PixelShader = compile ps_5_0 PixelShaderFunction();
}
}
然后把这个材质拖到模型上
参数Solid Color
是我们在代码中定义的组件,用来选材质颜色
float4 SolidColor
<
string UIWidget = "Color";
string UIName="Solid Color";
> = float4(1.0f, 1.0f, 1.0f, 1.0f);
看了下,似乎wpf只支持像素着色器,不支持顶点着色器。那代码就简化许多了。
第二个问题是wpf中没有通过HLSL生成UI控件,怎么调整SolidColor?
我看了下HLSL变量声明语法,原来<DataType名称 = 值;... ;>
是批注语法效果框架能识别,但会被hlsl忽略
https://learn.microsoft.com/zh-cn/windows/win32/direct3dhlsl/dx-graphics-hlsl-variable-syntax
[Storage_Class] [Type_Modifier] Type Name[Index] [: Semantic] [: Packoffset] [: Register]; [Annotations] [= Initial_Value]
wpf中使用的则是Register
可选部分,从寄存器读取输入
wpfSolidColor.fx
struct PixelShaderOutput
{
float4 Color : SV_TARGET;
};
float4 SolidColor : register(c0) = float4(1.0f, 1.0f, 1.0f, 1.0f);
//=============== 基本像素着色器函数
PixelShaderOutput PixelShaderFunction()
{
PixelShaderOutput output;
// 设置像素颜色为 SolidColor 定义的颜色
output.Color = SolidColor;
return output;
}
fxc.exe
编译这个文件./fxc /T ps_3_0 /E PixelShaderFunction /Fo TextEffect2.ps wpfSolidColor.fx
ps_3_0
或ps_2_0
TextEffect2.ps
拷贝到项目,把生成方式改为资源namespace 你的命名空间
{
public class SolidShader:ShaderEffect
{
public static readonly DependencyProperty SolidColorProperty = DependencyProperty.Register("SolidColor", typeof(Color), typeof(SolidShader), new UIPropertyMetadata(Color.FromArgb(255, 0, 0, 0), PixelShaderConstantCallback(1)));
public SolidShader()
{
PixelShader pixelShader = new PixelShader();
pixelShader.UriSource = new Uri("pack://application:,,,/程序集命名空间;component/路径/TextEffect2.ps", UriKind.Absolute);
this.PixelShader = pixelShader;
this.UpdateShaderValue(SolidColorProperty);
}
public Color SolidColor
{
get
{
return ((Color)(this.GetValue(SolidColorProperty)));
}
set
{
this.SetValue(SolidColorProperty, value);
}
}
}
}
最后看到像素着色器正常运行
fxc.exe
我们可以自及指定入口函数,但是使用Shazzam Shader Editor
看起来已经在代码中固定了入口函数。Shazzam Shader Editor
的好处是编译和预览方便