在WPF中使用着色器
概念类比
| 范畴 | 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 HLSL编写与预览
- 首先,为了避免折腾和跟上b站的视频教程,下载
3DS Max,接着添加一个茶壶
只是教程用的是Direct9,我们现在用的是Direct11,语法有点差异

打开3DS Max,按下快捷键M,或者点击材质编辑器

然后切换模式,换成精简材质编辑器

点击物理材质切换自己写的shader

选择DirectX 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只支持像素着色器,不支持顶点着色器。那代码就简化许多了。
第二个问题是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
注意,wpf支持的directx版本比较老,这里只能用ps_3_0或ps_2_0
https://learn.microsoft.com/zh-cn/windows/win32/direct3dtools/dx-graphics-tools-fxc-syntax
之后把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);
}
}
}
}
最后看到像素着色器正常运行

总结
- 自定义
着色器类型很多,3ds max中能自定义完整的渲染管线,包括顶点着色器和像素着色器。但是wpf只支持像素着色器的自定义。 - 着色器编译入口
使用fxc.exe我们可以自及指定入口函数,但是使用Shazzam Shader Editor看起来已经在代码中固定了入口函数。
Shazzam Shader Editor使用Shazzam Shader Editor的好处是编译和预览方便 - 版本
Direct已经更新到11了,但wpf只支持Direct9
在WPF中使用着色器的更多相关文章
- 在CG/HLSL中访问着色器属性(Properties)
在CG/HLSL中访问着色器属性 Shader在Properties块中访问材质属性.如果你想在一个着色程序中访问一些属性,你需要声明一个Cg/HLSL具有相同的名称和一个匹配的类型的变量. Prop ...
- OpenGl中使用着色器的基本步骤及GLSL渲染简单示例
OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行过程是 ...
- three中的着色器示例
其实在3D引擎/库的帮助下,我们做webgl开发的难度已经很大大地降低了,熟悉相关API的话,开发一个简单的3D程序可以说是很轻松的事情. 在我看来,webgl的核心就是着色器(顶点着色器.片元着色器 ...
- 在CG/HLSL中访问着色器的内容
着色器在Properties代码块中声明 材质球的各种特性.如果你想要在着色器程序中使用这些特性,你需要在CG/HLSL中声明一个变量,这个变量需要与你要使用的特性拥有同样的名字和对的上号的类型.比如 ...
- WPF 像素着色器入门:使用 Shazzam Shader Editor 编写 HLSL 像素着色器代码
原文:WPF 像素着色器入门:使用 Shazzam Shader Editor 编写 HLSL 像素着色器代码 HLSL,High Level Shader Language,高级着色器语言,是 Di ...
- BGFX 渲染引擎中着色器代码的调试方法
在实时渲染的图形开发中,着色器代码(Shader)越来越复杂,于是单纯的靠经验和不断试错的开发和调试方法早已不能满足实际需求.使用调试工具进行调试,成为开发中重要的方法.Bgfx 是一款跨平台.抽象封 ...
- OpenGL学习脚印: uniform blocks在着色器中的使用 转自https://blog.csdn.net/wangdingqiaoit/article/details/52717963
写在前面 目前,我们在着色器中要传递多个uniform变量时,总是使用多个uniform,然后在主程序中设置这些变量的值:同时如果要在多个shader之间共享变量,例如投影矩阵projection和视 ...
- unity中使用的着色器语言
在unity中,着色器编程使用了一列列的HLSL语言变种(也叫作Cg,但是大部分实际上两者都是一样的). 目前,为了在不同平台下保持最好的跨平台性, 取样贴图时,最好使用DX9风格 的HLSL. 着色 ...
- WebGL 创建和初始化着色器过程
1.编译GLSL ES代码,创建和初始化着色器供WebGL使用.这些过程一般分为7个步骤: 创建着色器对象(gl.createBuffer()); 向着色器对象中填充着色器程序的源代码(gl.shad ...
- 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...
随机推荐
- 面试官:素有Java锁王称号的‘StampedLock’你知道吗?我:这什么鬼?
一.写在开头 我们在上一篇写ReentrantReadWriteLock读写锁的末尾留了一个小坑,那就是读写锁因为写锁的悲观性,会导致 "写饥饿",这样一来会大大的降低读写效率,而 ...
- 这几个好用的 Google 搜索技巧,让你飞起!
搜索能力是被绝大多数人低估一项基本素质,绝大部分做编程技术相关的朋友应该都知道如何使用 Google,但是并不知道如何利用它的潜力.其实不管是 Google 还是 百度,会搜索的人一样都可以查找到需要 ...
- gorm 关系一对一,一对多,多对多查询
gorm 关系一对一,一对多,多对多查询 gorm v2版本 Belongs To mysql表 CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_IN ...
- addEventListener添加事件监听
removeEventListener移除事件监听 window.addEventListener('mousedown', e => this.closeMenu(e)) window.add ...
- 数据库—安全性控制DCL
文章目录 授予数据库权限 授予用户能够授予其他用户的权限 收回权限 数据库的权限(特殊) 授予数据库权限 这里的用户是指数据库DBMS中创建的用户,而不是程序中的账户用户. 授予某个/多个表的某一个/ ...
- C 语言编程 — 高级数据类型 — 共用体
目录 文章目录 目录 前文列表 共用体 定义共用体 访问共用体成员 前文列表 <程序编译流程与 GCC 编译器> <C 语言编程 - 基本语法> <C 语言编程 - 基本 ...
- es命令大全,elasticsearch命令详解
参考链接 Relational DB Elasticsearch 数据库(database) 索引(indices) 表(tables) types 行(rows) documents 字段(colu ...
- 自研WPF插件系统(沙箱运行及热插拔)
前言 插件化的需求主要源于对软件架构灵活性的追求,特别是在开发大型.复杂或需要不断更新的软件系统时,插件化可以提高软件系统的可扩展性.可定制性.隔离性.安全性.可维护性.模块化.易于升级和更新以及支持 ...
- springboot使controller异步调用
调用controller方法,遇到操作时间很长的情况下,不希望前端一直等待操作,而希望前端立马接收到操作启动的反馈,而真正的操作在后端执行,需要用到异步调用的方法.实现步骤如下: 一.配置异步支持: ...
- 前端如何对cookie加密
在前端对 Cookie 进行加密时,你可以使用加密算法对 Cookie 的值进行加密,然后再将加密后的值存储到 Cookie 中.常用的加密算法包括对称加密算法(如 AES)和非对称加密算法(如 RS ...