在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 ...
随机推荐
- .net 记录http请求
记录http请求 环境 .net7 一.过滤器(Filter) 这个过程用的的是操作过滤器(ActionFilter) 二. 2.1 继承IAsyncActionFilter 2.2 重写OnActi ...
- 【2023微博签到爬虫】用python爬上千条m端微博签到数据
一.爬取目标 大家好,我是 @马哥python说,一枚10年程序猿. 今天分享一期python爬虫案例,爬取目标是新浪微博的微博签到数据,字段包含: 页码,微博id,微博bid,微博作者,发布时间,微 ...
- 简说python之初连ORACLE数据库
目录 Python操作Oracle数据库 1.安装cx_Oracle模块 2.安装oracle客户端 3.python操作oracle示例 4.配置TNS 5.通过tns连接数据库的python 通过 ...
- rails byebug
Gemfile里添加 gem 'byebug' bundle install 在要打断点的地方写 byebug byebug -h #帮助 c 放行,入下走 n 单行调适 q 退出进行 启动异步任务推 ...
- vue安装tinyMCE
目录 [参考视频] [参考文章] 官网: https://www.tiny.cloud/auth/signup/ 资源下载 tinymce 官方为 vue 项目提供了一个组件tinymce-vue n ...
- List集合中获取重复元素
一.方法1 ## 测试数据 List<String> words = Arrays.asList("a", "b", "c", ...
- C数据结构:二叉树的基本操作
二叉树 树基本知识 二叉树的性质 满二叉树 完全二叉树 性质4.5的解释 顺序存储结构(利用性质4.5) 链式存储结构 结点结构体 建立二叉树 先序遍历 中序遍历 后序遍历 层次遍历 复制二叉树 计算 ...
- 30分钟带你搞定Dokcer部署Kafka集群
docker网络规划 docker network create kafka-net --subnet 172.20.0.0/16 docker network ls zookeeper1(172.2 ...
- java学习之旅(day.06)
switch多选择结构 多选择结构还有一个实现方式就是switch case switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支 switch(expression ...
- AIRIOT答疑第7期|如何快速提升物联网项目交付速度?
平台+模板,套上就能用!贼拉快! AIRIOT提供物联网低代码平台+多套行业案例模板,针对于有明确项目的服务商,用平台已经配置好的节点数.功能模块.流程,直接上手干项目! AIRIOT解答: 多套物联 ...