在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 ...
随机推荐
- B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能
B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能 @ 目录 B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa ...
- JAVA下唯一一款搞定OLTP+OLAP的强类型查询这就是最好用的ORM相见恨晚
JAVA下唯一一款搞定OLTP+OLAP的强类型查询这就是最好用的ORM相见恨晚 介绍 首先非常感谢 FreeSQL 提供的部分源码,让我借鉴了不少功能点,整体设计并没有参考FreeSQL(因为jav ...
- uiautomator2环境搭建+元素定位(安卓)
一.环境搭建 1.安装uiautomator2 在终端使用pip安装即可 pip install uiautomator2 2.安装adb 可参考:https://www.cnblogs.com/li ...
- vim 使用black 格式化python代码
vim 使用black 格式化代码 github black 的github https://github.com/psf/black 安装 pip3 install black 使用 black f ...
- 利用python爬取某壳的房产数据
以无锡的某壳为例进行数据爬取,现在房子的价格起伏很快,买房是人生一个大事,了解本地的房价走势来判断是否应该入手. (建议是近2年不买,本人在21年高位抛了一套房,基本是通过贝壳数据判断房价已经到顶,希 ...
- 校园圈子系统前后端安装开发app小程序h5
四川掌上时代开发公司,作为一家专注于提供高质量软件解决方案的企业,在信息技术领域已经积累了丰富的经验和良好的声誉.位于中国四川省成都市,该公司不仅服务于本地市场,还将业务拓展到了全国乃至国际市场,与多 ...
- 基于Node.js+MySQL开发的开源微信小程序商城(微信小程序)部署环境
在网上搜到小程序设计的项目,下载前辈的代码到本地环境,接下来需要如何部署代码到本地,并能够看到完整的效果展示. 服务器端: https://github.com/tumobi/nideshop Nid ...
- Python OpenCV #1 - OpenCV介绍
一.OpenCV介绍 1.1 OpenCV-Python教程简介 OpenCV由 Gary Bradsky 于1999年在英特尔创立,第一个版本于2000年发布. Vadim Pisarevsky 加 ...
- 论GNU、Linux和GNU/Linux之间的关系
相信很多人看到了这个标题就会产生疑问,这篇文章到底要讲什么东西?在回答这个问题之前,我先提出几个问题? 1. 什么是Linux? 2. 什么是GNU? 3. GNU/Linux是什么玩意儿? 在回答了 ...
- 在Rainbond上部署高可用Apollo集群
一.背景信息 当前文档描述如何通过云原生应用管理平台 Rainbond 一键安装高可用 Apollo 集群.这种方式适合给不太了解 Kubernetes.容器化等复杂技术的用户使用,降低了在 Kube ...