在WPF中使用着色器

wpf · 浏览次数 : 3

小编点评

概念类比范畴:CPUGPU - 二进制文件(.exe、.cso)、机器码(CSO)、助记符汇编(SL)、高级语言(C#、HLSL)、文件(.cs.hlsl、.fx)、编译器(csc.exe、fxc.exe)、API(NET、DirectX API)、运行时环境(CLR)、调试工具(Visual Studio Debugger、RenderDoc)、着色器类型(着色器简称、着色器名)、解释(cs_4_0Compute Shader、ds_5_0Domain Shader、fx_2_0Effect Model、gs_4_0Geometry Shader、hs_5_0Hull Shader、ps_2_0Pixel Shader、tx_1_0Texture Shader、vs_1_1Vertex Shader) 1. 二进制文件:.exe(可执行文件)、.cso(缓存文件)、.ps(像素着色器文件) 2. 机器码(CSO):二进制指令集合,用于指导处理器执行任务 3. 助记符汇编(SL):一种高级语言,用于描述图形渲染过程 4. 高级语言:C#、HLSL(用于编写着色器) 5. 文件:.cs.hlsl(HLSL源文件)、.fx(效应文件) 6. 编译器:csc.exe(C#编译器)、fxc.exe(FX编译器) 7. API:NET(通用应用程序接口)、DirectX API 8. 运行时环境(CLR):用于执行程序的运行时环境 9. 调试工具:Visual Studio Debugger、RenderDoc 10. 着色器类型: - 着色器简称:着色器名称 - 着色器名:具体类型,如Compute Shader、Domain Shader、Effect Model、Geometry Shader、Hull Shader、Pixel Shader、Texture Shader、Vertex Shader 11. 解释:特定着色器模型的功能描述,如cs_4_0Compute Shader(用于处理非图形计算任务) 12. 编译器入口:使用fxc.exe工具进行编译,指定入口函数 13. WPF着色器:仅支持像素着色器,不支持顶点着色器 14. HLSL变量声明语法:使用``作为批注语法,但实际会被hlsl忽略 15. 指令集:DirectX SDK(June 2010)中的指令集,用于开发高性能图形应用程序

正文

概念类比

范畴 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,语法有点差异
    image
    打开3DS Max,按下快捷键M,或者点击材质编辑器
    image
    然后切换模式,换成精简材质编辑器
    image
    点击物理材质切换自己写的shader
    image
    选择DirectX Shader材质
    image
    点击确定
    image
    点击路径,可选择自定义材质
    image

可以事先在桌面上新建一个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();
    }
}

然后把这个材质拖到模型上
image
参数Solid Color是我们在代码中定义的组件,用来选材质颜色

float4 SolidColor
<
    string UIWidget = "Color";
    string UIName="Solid Color";
> = float4(1.0f, 1.0f, 1.0f, 1.0f);

image

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;
}
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);
            }
        }
    }
}

最后看到像素着色器正常运行
image

总结

  • 自定义
    着色器类型很多,3ds max中能自定义完整的渲染管线,包括顶点着色器和像素着色器。但是wpf只支持像素着色器的自定义。
  • 着色器编译入口
    使用fxc.exe我们可以自及指定入口函数,但是使用Shazzam Shader Editor 看起来已经在代码中固定了入口函数。
    Shazzam Shader Editor使用Shazzam Shader Editor 的好处是编译和预览方便
  • 版本
    Direct已经更新到11了,但wpf只支持Direct9

与在WPF中使用着色器相似的内容:

在WPF中使用着色器

概念类比 范畴 CPU GPU 二进制文件 .exe .cso / .ps 二进制指令 机器码 CSO(shader指令) 助记符 汇编 SL 高级语言 C# HLSL 高级语言文件 .cs .hlsl / .fx 高级语言编译器 csc.exe fxc.exe API .NET API Direc

[WPF]使用HLSL实现百叶窗动效

百叶窗动画是制作PPT时常用的动画之一,本文将通过实现百叶窗动画效果的例子介绍在WPF中如何使用ShaderEffect。ShaderEffect使用高级着色器语言(High Level Shading Language,HLSL)事先制作好并且已经编译过的效果。先看下百叶窗动画实现效果: ![im

在WPF中使用WriteableBitmap对接工业相机及常用操作

写作背景 写这篇文章主要是因为工业相机(海康、大恒等)提供的.NET开发文档和示例程序都是用WinForm项目来说明举例的,而在WPF项目中对图像的使用和处理与在WinForm项目中有很大不同。在WinForm中用System.Drawing.Bitmap来处理图像,而在WPF中是用System.W

Avalonia中的线性渐变画刷LinearGradientBrush

在WPF中使用Shape实现复杂线条动画后,尝试在Avalonia中也实现同样效果。尽管官方提供了从WPF到Avalonia的快速入门文档,但由于第一次使用Avalonia,体验过程中并不是很顺利,主要是卡在线性渐变画刷LinearGradientBrush的使用上。Avalonia中的线性渐变画刷

WPF/C#:实现导航功能

前言 在WPF中使用导航功能可以使用Frame控件,这是比较基础的一种方法。前几天分享了wpfui中NavigationView的基本用法,但是如果真正在项目中使用起来,基础的用法是无法满足的。今天通过wpfui中的mvvm例子来说明在wpfui中如何通过依赖注入与MVVM模式使用导航功能。实践起来

WPF使用Blazor的快速案例

下面我们将讲解在WPF中使用Blazor,并且使用Blazor做一些文件编辑操作,下面是需要用到的东西 - WPF - Blazor - Masa Blazor - Monaco ## 安装Masa Blazor模板 使用`CMD`指令安装模板 ```shell dotnet new install

WPF/C#:在WPF中如何实现依赖注入

本文先介绍依赖注入的概念,再解释为什么要进行依赖注入,最后通过 WPF Gallery 这个项目学习如何在WPF中使用依赖注入。

【炫丽】从0开始做一个WPF+Blazor对话小程序

大家好,我是沙漠尽头的狼。 .NET是免费,跨平台,开源,用于构建所有应用的开发人员平台。 本文演示如何在WPF中使用Blazor开发漂亮的UI,为客户端开发注入新活力。 注 要使WPF支持Blazor,.NET版本必须是 6.0 或更高版本,本文所有示例使用的.NET 7.0,版本要求见链接,截图

CefSharp自定义滚动条样式

在WinForm/WPF中使用CefSharp混合开发时,通常需要自定义滚动条样式,以保证应用的整体风格统一。本文将给出一个简单的示例介绍如何自定义CefSharp中滚动条的样式。 基本思路 在前端开发中,通过CSS来控制滚动条的样式是件寻常的事情。CefSharp也提供了功能强大的API方便开发人

使用.NET查询日出日落时间

在WPF中,通过资源文件实现主题切换是个常见的功能,有不少文章介绍了如何实现手动切换主题。那如何实现自动切换主题呢?通常有两种机制:一是跟随系统明暗主题切换,二是像手机操作系统那样根据日出日落时间自动切换。本文将以终为始,采用倒推法一步步介绍如何使用.NET免费获取日出日落时间。 获取日出日落时间