在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 ...
随机推荐
- C/C++如何写调试宏
1. 调试宏以及测试 在写代码时,不可避免需要打印提示.警告.错误等信息,且要灵活控制打印信息的级别.另外,还有可能需要使用宏来控制代码段(主要是调试代码段)是否执行.为此,本文提供一种调试宏定义方案 ...
- blazor中的PageTitle输出keywords和description,自定义组件
在blazor的PageTitle中不具备输出keywords和description的功能,而如果直接使用<mate>标签,输出中文时会变成乱码,所以我给大家推介下面的代码解君愁: 1 ...
- Ubuntu虚拟机ROS的安装与使用
ROS安装 直达链接 安装ROS2 使用鱼香ROS的一键安装: wget http://fishros.com/install -O fishros && bash fishros 进 ...
- cesium介绍和国内主要学习网站汇总
Cesium官方网站 建议大家将Cesium官网的博客都读一遍,博客大概分为三类,主要是技术类,比如性能优化,调度算法等,一类是定期的新版本特性,能够了解Cesium新功能和新特性,还有一类是大事记, ...
- Selenium4自动化测试3--元素定位By.NAME,By.LINK_TEXT 和通过链接部分文本定位,By.PARTIAL_LINK_TEXT,css_selector定位,By.CSS_SELECTOR
4-通过名称定位,By.NAME name属性为表单中客户端提交数据的标识,一个网页中name值可能不是唯一的.所以要根据实际情况进行判断 import time from selenium impo ...
- MySQL日志文件简记
日志文件 binlog binlog主要记录了MySQL数据库执行了更改的所有操作,主要用来做主从复制,数据恢复 记录模式: Statement模式:每一条回修改数据的sql都会被记录在日志中 Row ...
- linux文件权限管理:文件权限类型,文件权限影响,设定文件权限,取消文件权限
目录 一.关于文件权限 二.查看文件权限 三.linux下常见文件类型 四.linux下常见的文件权限 五.权限对文件和目录的影响 六.文件的用户分类 七.更改文件的属主和属组 八.一个文件取消所有权 ...
- Android 12(S) MultiMedia Learning(十)ACodec & OMX
这一节的学习分为三块内容,omx hidl service用法.OMX架构.ACodec中的buffer分配. 1.omx hidl service system可以借助vndbinder来访问ven ...
- WPF开发快速入门【6】下拉框与枚举类型
概述 本文讲述下拉框和枚举类型进行绑定的一些操作. 下拉框的基本操作 设计部分: <ComboBox ItemsSource="{Binding Fruits}" Selec ...
- 智影AI故事转视频创作神器!快速开启AI绘画小说推文之旅
1.前言 1.1 生成内容形式 生成内容形式主要包含三种,PGC(Professionally Generated Content).UGC(User Generated Content).AIGC( ...