Vulkan 高级着色语言对比

虽然 Vulkan 本身使用一种名为 SPIR-V 的二进制格式的着色器,但着色器通常使用高级语言编写。本节提供了与 Vulkan 一起使用的最常见着色器功能之间的映射:GLSL 和 HLSL。这主要面向想要从一种高级着色语言迁移到另一种高级着色语言的人。它旨在作为一个起点,而不是一个从一种语言到另一种语言的完整移植指南

有关在 Vulkan 中使用 HLSL 的更多详细信息,请访问本章

以下列表绝非完整,并且可能缺少较新扩展的映射。另请注意,GLSL 和 HLSL 之间的概念并非始终 1:1 映射。例如,GLSL 中没有语义,而一些较新的 GLSL 功能可能(尚未)在 HLSL 中可用。

扩展

在 GLSL 中,需要使用 #extension 指令显式启用扩展。这在 HLSL 中是不需要的。编译器将根据着色器隐式选择合适的 SPIR-V 扩展。如果需要,可以使用 -fspv-extension 参数显式选择扩展。

数据类型

类型在 GLSL 和 HLSL 中的工作方式类似。但是,GLSL 例如具有显式的向量或矩阵类型,而 HLSL 使用基本类型。另一方面,HLSL 提供了高级类型功能,如 C++ 模板。本段包含一个基本摘要,并附带一些示例,以显示两种语言之间的类型差异。

GLSL HLSL 示例

vecn

floatn

vec4 → float4

ivecn

intn

ivec3 -→ int3

matnxm 或简写 matn

floatnxm

mat4 → float4x4

类型转换的语法也不同

GLSL

mat4x3 mat = mat4x3(ubo.view);

HLSL

float4x3 mat = (float4x3)(ubo.view);

一个重要的区别:GLSL 中的矩阵是列主序的,而 HLSL 中的矩阵是行主序的。这会影响诸如矩阵构造之类的事情。

隐式 vk 命名空间

对于 DirectX 中不可用的 Vulkan 概念,已添加一个隐式命名空间,用于标记 Vulkan 特定功能。

SPIR-V 宏

当使用 DXC 将 HLSL 编译为 SPIR-V 时,可以使用 __spirv__ 宏来表示 Vulkan 特定代码。如果 HLSL 着色器需要同时使用 Vulkan 和 D3D,这很有用

#ifdef __spirv__
[[vk::binding(0, 1)]]
#endif
ConstantBuffer<Node> node : register(b0, space1);

SPIR-V 内置函数

DXC 支持具有 GL_EXT_spirv_intrinsics 扩展的 SPIR-V 内置函数。这增加了对在 GLSL 中间嵌入任意 SPIR-V 的支持,以实现 DirectX 中不可用的功能。为此,向 vk 命名空间添加了新的关键字,用于映射 SPIR-V 操作码,包括 vk::ext_extensionvk::ext_capabilityvk::ext_builtin_inputvk::ext_execution_modevk::ext_instruction

在 HLSL 中使用模板导出 SPIR-V 扩展的示例

[[vk::ext_capability(/* StencilExportEXT */ 5013)]]
[[vk::ext_extension("SPV_EXT_shader_stencil_export")]]
vk::ext_execution_mode(/* StencilRefReplacingEXT */ 5027);

设置内置函数以访问光线追踪中顶点位置的示例

[[vk::ext_extension("SPV_KHR_ray_tracing_position_fetch")]]
[[vk::ext_capability(RayTracingPositionFetchKHR)]]
[[vk::ext_builtin_input(HitTriangleVertexPositionsKHR)]]
const static float3 gl_HitTriangleVertexPositions[3];

内置函数与语义

虽然 GLSL 大量使用内置于语言中的输入和输出变量(称为“内置变量”),但在 HLSL 中没有这样的概念。HLSL 而是使用语义,即附加到输入或包含有关该变量预期用途信息的字符串。它们以 SV_ 为前缀。对于 HLSL,输入值是主入口点的显式参数,并且着色器需要显式返回输出。

示例

从顶点着色器写入位置

GLSL

layout (location = 0) in vec4 inPos;

void main() {
    // The vertex output position is written to the gl_Position built-in
    gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * inPos.xyz;
}

HLSL

struct VSOutput
{
    // The SV_POSITION semantic declares the Pos member as the vertex output position
    float4 Pos : SV_POSITION;
};

VSOutput main(VSInput input)
{
    VSOutput output = (VSOutput)0;
    output.Pos = mul(ubo.projectionMatrix, mul(ubo.viewMatrix, mul(ubo.modelMatrix, input.Pos)));
    return output;
}

读取顶点索引

GLSL

void main()
{
    // The vertex index is stored in the gl_VertexIndex built-in
    outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
}

HLSL

struct VSInput
{
    // The SV_VertexID semantic declares the VertexIndex member as the vertex index input
    uint VertexIndex : SV_VertexID
};

VSOutput main(VSInput input)
{
    VSOutput output = (VSOutput)0;
    output.UV = float2((input.VertexIndex << 1) & 2, input.VertexIndex & 2);
    return output;
}

着色器接口

GLSL 和 HLSL 之间的着色器接口差异很大。

描述符绑定

GLSL

layout (set = <set-index>, binding = <binding-index>) uniform <type> <name>

在使用 Vulkan 时,有两种选项可以在 HLSL 中定义描述符集和绑定索引。

HLSL 方式

<type> <name> : register(<register-type><binding-index>, space<set-index>)

使用此语法,描述符集和绑定索引将从集合和绑定索引隐式分配。

Vulkan 命名空间

[[vk::binding(binding-index, set-index)]]
<type> <name>

使用此选项,描述符集和绑定索引使用 vk::binding 显式设置。

可以对一个描述符同时使用 vk::binding[]register() 语法。如果着色器同时用于 Vulkan 和 DirectX,这可能会很有用。

示例

GLSL
layout (set = 1, binding = 0) uniform Node {
    mat4 matrix;
} node;
HLSL
struct Node {
    float4x4 transform;
};

// HLSL style
ConstantBuffer<Node> node : register(b0, space1);

// Vulkan style
[[vk::binding(0, 1)]]
ConstantBuffer<Node> node;

// Combined
[[vk::binding(0, 1)]]
ConstantBuffer<Node> node : register(b0, space1);

Uniform 变量

GLSL

layout (set = <set-index>, binding = <binding-index>) uniform <type> <name>

示例

// Uniform buffer
layout (set = 0, binding = 0) uniform UBO
{
    mat4 projection;
} ubo;

// Combined image sampler
layout (set = 0, binding = 1) uniform sampler2D samplerColor;

HLSL

<type> <name> : register(<register-type><binding-index>, space<set-index>)

[[vk::binding(binding-index, set-index)]]
<type> <name>

示例

// Uniform buffer
struct UBO
{
    float4x4 projection;
};
ConstantBuffer<UBO> ubo : register(b0, space0);

// Combined image sampler
Texture2D textureColor : register(t1);
SamplerState samplerColor : register(s1);

如果使用 HLSL 描述符绑定语法,则 <register type> 可以是

类型 寄存器描述 Vulkan 资源

b

常量缓冲区

Uniform 缓冲区

t

纹理和纹理缓冲区

Uniform 纹理元素缓冲区和只读着色器存储缓冲区

c

缓冲区偏移

layout(offset = N)

s

采样器

相同

u

无序访问视图

着色器存储缓冲区、存储图像和存储纹理元素缓冲区

着色器输入

GLSL

layout (location = <location-index>) in <type> <name>;

示例

layout (location = 0) in vec3 inPos;
layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec2 inUV0;
layout (location = 3) in vec2 inUV1;

HLSL

[[vk::location(<location-index>)]] <type> <name> : <semantic-type>;

示例

struct VSInput
{
[[vk::location(0)]] float3 Pos : POSITION;
[[vk::location(1)]] float3 Normal : NORMAL;
[[vk::location(2)]] float2 UV0 : TEXCOORD0;
[[vk::location(3)]] float2 UV1 : TEXCOORD1;
};

VSOutput main(VSInput input) {
}

<semantic type> 可以是

语义 描述 类型

BINORMAL[n]

副法线

float4

BLENDINDICES[n]

混合索引

uint

BLENDWEIGHT[n]

混合权重

float

COLOR[n]

漫反射和镜面反射颜色

float4

NORMAL[n]

法线向量

float4

POSITION[n]

对象空间中的顶点位置。

float4

POSITIONT

转换后的顶点位置

float4

PSIZE[n]

点大小

float

TANGENT[n]

切线

float4

TEXCOORD[n]

纹理坐标

float4

n 是一个可选整数,介于 0 和支持的资源数量之间。(来源

着色器输出

在阶段之间传递数据

例如,对于顶点着色器和细分着色器。

GLSL
layout (location = <location-index>) out/in <type> <name>;

示例

layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec3 outColor;
layout (location = 2) out vec2 outUV;
layout (location = 3) out vec3 outViewVec;

void main() {
    gl_Position = vec4(inPos, 1.0);
    outNormal = inNormal;
}
HLSL
[[vk::location(<location-index>)]] <type> <name> : <semantic-type>;

示例

struct VSOutput
{
                    float4 Pos : SV_POSITION;
[[vk::location(0)]] float3 Normal : NORMAL;
[[vk::location(1)]] float3 Color : COLOR;
[[vk::location(2)]] float2 UV : TEXCOORD0;
[[vk::location(3)]] float3 ViewVec : TEXCOORD1;
}

VSOutput main(VSInput input) {
    VSOutput output = (VSOutput)0;
    output.Pos = float4(input.Pos.xyz, 1.0);
    output.Normal = input.Normal;
    return output;
}

写入附件

对于片段着色器。

GLSL
layout (location = <attachment-index>) out/in <type> <name>;

示例

layout (location = 0) out vec4 outPosition;
layout (location = 1) out vec4 outNormal;
layout (location = 2) out vec4 outAlbedo;

void main() {
    outPosition = ...
    outNormal = ...
    outAlbedo = ...
}
HLSL
<type> <name> : SV_TARGET<attachment-index>;

示例

struct FSOutput
{
    float4 Position : SV_TARGET0;
    float4 Normal : SV_TARGET1;
    float4 Albedo : SV_TARGET2;
};

FSOutput main(VSOutput input) {
    output.Position = ...
    output.Normal = ...
    output.Albedo = ...
    return output;
}

推送常量

推送常量必须通过 D3D 中的根签名来处理。

GLSL

layout (push_constant) uniform <structure-type> { <members> } <name>

示例

layout (push_constant) uniform PushConsts {
    mat4 matrix;
} pushConsts;

HLSL

[[vk::push_constant]] <structure-type> <name>;
struct PushConsts {
    float4x4 matrix;
};
[[vk::push_constant]] PushConsts pushConsts;

特化常量

特化常量仅在 Vulkan 中可用,D3D 不提供任何类似的东西。

GLSL

layout (constant_id = <specialization-constant-index>) const int <name> = <default-value>;

示例

layout (constant_id = 0) const int SPEC_CONST = 0;

HLSL

[[vk::constant_id(<specialization-constant-index>)]] const int <name> = <default-value>;

示例

[[vk::constant_id(0)]] const int SPEC_CONST = 0;

子过程

GLSL

layout (input_attachment_index = <input-attachment-index>, binding = <binding-index>) uniform subpassInput <name>;

示例

layout (input_attachment_index = 0, binding = 0) uniform subpassInput input0;

HLSL

[[vk::input_attachment_index(<input-attachment-index>)]][[vk::binding(<binding-index>)]] SubpassInput <name>;

示例

[[vk::input_attachment_index(0)]][[vk::binding(0)]] SubpassInput input0;

纹理读取

当 GLSL 使用全局函数访问图像时,HLSL 使用纹理对象的成员函数。

示例

GLSL

layout (binding = 0, set = 0) uniform sampler2D sampler0;

void main() {
    vec4 color = texture(sampler0, inUV);
}

HLSL

Texture2D texture0 : register(t0, space0);
SamplerState sampler0 : register(s0, space0);

float4 main(VSOutput input) : SV_TARGET {
    float4 color = texture0.Sample(sampler0, input.UV);
}
GLSL HLSL

texture

Sample

textureGrad

SampleGrad

textureLod

SampleLevel

textureSize

GetDimensions

textureProj

不适用,需要手动透视除法

texelFetch

Load

sparseTexelsResidentARB

CheckAccessFullyMapped

图像格式

GLSL

layout (set = <set-index>, binding = <image-binding-index>, <image-format>) uniform <memory-qualifier> <image-type> <name>;

示例

layout (set = 0, binding = 0, rgba8) uniform writeonly image2D outputImage;

HLSL

[[vk::image_format(<image-format>)]]
RWTexture2D<image-components> <name> : register(<register-type><binding-index>, space<set-index>);

示例

[[vk::image_format("rgba8")]]
RWTexture2D<float4> resultImage : register(u0, space0);

内置变量和函数映射

缓冲区设备地址

目前,HLSL 仅支持 VK_KHR_buffer_device_address子集

GLSL

示例

layout(push_constant) uniform PushConstants {
    uint64_t bufferAddress;
} pushConstants;

layout(buffer_reference, scalar) buffer Data {vec4 f[]; };

void main() {
    Data data = Data(pushConstants.bufferAddress);
}

HLSL

示例

struct PushConstants {
    uint64_t bufferAddress;
};
[[vk::push_constant]] PushConstants pushConstants;

void main() {
    float4 data = vk::RawBufferLoad<float4>(pushConstants.bufferAddress);
}

光线追踪

着色器阶段选择

当 GLSL 通过文件扩展名(或通过编译器参数显式)隐式检测着色器阶段(用于光线追踪)时,对于 HLSL 光线追踪着色器,需要使用 [shader("stage")] 语义进行标记

示例

[shader("closesthit")]
void main(inout RayPayload rayPayload, in float2 attribs) {
}

阶段名称与 GLSL 匹配:raygenerationintersectionanyhitclosesthitmisscallable

着色器记录缓冲区

GLSL

示例

layout(shaderRecordEXT, std430) buffer SBT {
    float data;
};

HLSL

示例

struct SBT {
    float data;
};
[[vk::shader_record_ext]]
ConstantBuffer<SBT> sbt;

内置变量

GLSL HLSL 注意

accelerationStructureEXT

RaytracingAccelerationStructure

executeCallableEXT

CallShader

ignoreIntersectionEXT

IgnoreHit

reportIntersectionEXT

ReportHit

terminateRayEXT

AcceptHitAndEndSearch

traceRayEXT

TraceRay

rayPayloadEXT (存储限定符)

TraceRay 的最后一个参数

rayPayloadInEXT (存储限定符)

任何命中、最近命中和未命中阶段的主要入口的第一个参数

hitAttributeEXT (存储限定符)

ReportHit 的最后一个参数

callableDataEXT (存储限定符)

CallShader 的最后一个参数

callableDataInEXT (存储限定符)

可调用阶段的主要入口的第一个参数

gl_LaunchIDEXT

DispatchRaysIndex

gl_LaunchSizeEXT

DispatchRaysDimensions

gl_PrimitiveID

PrimitiveIndex

gl_InstanceID

InstanceIndex

gl_InstanceCustomIndexEXT

InstanceID

gl_GeometryIndexEXT

GeometryIndex

gl_VertexIndex

SV_VertexID

gl_WorldRayOriginEXT

WorldRayOrigin

gl_WorldRayDirectionEXT

WorldRayDirection

gl_ObjectRayOriginEXT

ObjectRayOrigin

gl_ObjectRayDirectionEXT

ObjectRayDirection

gl_RayTminEXT

RayTMin

gl_RayTmaxEXT

RayTCurrent

gl_IncomingRayFlagsEXT

RayFlags

gl_HitTEXT

RayTCurrent

gl_HitKindEXT

HitKind

gl_ObjectToWorldEXT

ObjectToWorld4x3

gl_WorldToObjectEXT

WorldToObject4x3

gl_WorldToObject3x4EXT

WorldToObject3x4

gl_ObjectToWorld3x4EXT

ObjectToWorld3x4

gl_RayFlagsNoneEXT

RAY_FLAG_NONE

gl_RayFlagsOpaqueEXT

RAY_FLAG_FORCE_OPAQUE

gl_RayFlagsNoOpaqueEXT

AY_FLAG_FORCE_NON_OPAQUE

gl_RayFlagsTerminateOnFirstHitEXT

RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH

gl_RayFlagsSkipClosestHitShaderEXT

RAY_FLAG_SKIP_CLOSEST_HIT_SHADER

gl_RayFlagsCullBackFacingTrianglesEXT

RAY_FLAG_CULL_BACK_FACING_TRIANGLES

gl_RayFlagsCullFrontFacingTrianglesEXT

RAY_FLAG_CULL_FRONT_FACING_TRIANGLES

gl_RayFlagsCullOpaqueEXT

RAY_FLAG_CULL_OPAQUE

gl_RayFlagsCullNoOpaqueEXT

RAY_FLAG_CULL_NON_OPAQUE

需要 GL_EXT_ray_flags_primitive_culling

gl_RayFlagsSkipTrianglesEXT

RAY_FLAG_SKIP_TRIANGLES

需要 GL_EXT_ray_flags_primitive_culling

gl_RayFlagsSkipAABBEXT

RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES

gl_HitKindFrontFacingTriangleEXT

HIT_KIND_TRIANGLE_FRONT_FACE

gl_HitKindBackFacingTriangleEXT

HIT_KIND_TRIANGLE_BACK_FACE

gl_HitTriangleVertexPositionsEXT

[[vk::ext_extension("SPV_KHR_ray_tracing_position_fetch")]]
[[vk::ext_capability(RayTracingPositionFetchKHR)]]
[[vk::ext_builtin_input(HitTriangleVertexPositionsKHR)]]

需要 GL_EXT_ray_tracing_position_fetch

计算

本地工作组大小

GLSL
layout (local_size_x = <local-size-x>, local_size_y = <local-size-y>, local_size_z = <local-size-z>) in;

示例

layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
HLSL
[numthreads(<local-size-x>, <local-size-y>, <local-size-z>)]

示例

[numthreads(1, 1, 1)]
void main() {}

共享内存

GLSL

示例

shared vec4 sharedData[1024];
HLSL

示例

groupshared float4 sharedData[1024];

内置变量

GLSL HLSL

gl_GlobalInvocationID

SV_DispatchThreadID

gl_LocalInvocationID

SV_GroupThreadID

gl_WorkGroupID

SV_GroupID

gl_LocalInvocationIndex

SV_GroupIndex

gl_NumWorkGroups

不适用

gl_WorkGroupSize

不适用

屏障

GLSL 和 HLSL 之间的屏障差异很大。除一个例外,没有直接的映射。要在 GLSL 中匹配 HLSL,通常需要在 glsl 中调用多个不同的屏障类型。

示例

GLSL

groupMemoryBarrier();
barrier();
for (int j = 0; j < 256; j++) {
    doSomething;
}
groupMemoryBarrier();
barrier();

HLSL

GroupMemoryBarrierWithGroupSync();
for (int j = 0; j < 256; j++) {
    doSomething;
}
GroupMemoryBarrierWithGroupSync();

GLSL

HLSL

groupMemoryBarrier

GroupMemoryBarrier

groupMemoryBarrier + barrier

GroupMemoryBarrierWithGroupSync

memoryBarrier + memoryBarrierImage + memoryBarrierImage

DeviceMemoryBarrier

memoryBarrier + memoryBarrierImage + memoryBarrierImage + barrier

DeviceMemoryBarrierWithGroupSync

以上所有屏障 + barrier

AllMemoryBarrierWithGroupSync

以上所有屏障

AllMemoryBarrier

memoryBarrierShared(仅限)

不适用

网格、任务(放大)和几何着色器

这些着色器阶段共享多个函数和内置变量

GLSL HLSL

EmitMeshTasksEXT

DispatchMesh

SetMeshOutputsEXT

SetMeshOutputCounts

EmitVertex

StreamType<Name>.Append(例如,{TriangleStream<MSOutput>})

EndPrimitive

StreamType<Name>.RestartStrip

gl_PrimitiveShadingRateEXT

SV_ShadingRate

gl_CullPrimitiveEXT

SV_CullPrimitive

gl_in

主入口的数组参数(例如,{triangle VSInput input[3]})

细分着色器

GLSL HLSL

gl_InvocationID

SV_OutputControlPointID

gl_TessLevelInner

SV_InsideTessFactor

gl_TessLevelOuter

SV_TessFactor

gl_TessCoord

SV_DomainLocation

子组

GLSL HLSL

gl_HelperInvocation

WaveIsHelperLane

不适用

WaveOnce

readFirstInvocationARB

WaveReadFirstLane

readInvocationARB

WaveReadLaneAt

anyInvocationARB

WaveAnyTrue

allInvocationsARB

WaveAllTrue

allInvocationsEqualARB

WaveAllEqual

ballotARB

WaveBallot

gl_NumSubgroups

NumSubgroups 修饰的 OpVariable

gl_SubgroupID

SubgroupId 修饰的 OpVariable

gl_SubgroupSize

WaveGetLaneCount

gl_SubgroupInvocationID

WaveGetLaneIndex

gl_SubgroupEqMask

不适用

gl_SubgroupGeMask

不适用

gl_SubgroupGtMask

不适用

gl_SubgroupLeMask

不适用

gl_SubgroupLtMask

SubgroupLtMask 修饰的 OpVariable

subgroupElect

WaveIsFirstLane

subgroupAny

WaveActiveAnyTrue

subgroupAll

WaveActiveAllTrue

subgroupBallot

WaveActiveBallot

subgroupAllEqual

WaveActiveAllEqual

subgroupBallotBitCount

WaveActiveCountBits

subgroupAnd

WaveActiveBitAdd

subgroupOr

WaveActiveBitOr

subgroupXor

WaveActiveBitXor

subgroupAdd

WaveActiveSum

subgroupMul

WaveActiveProduct

subgroupMin

WaveActiveMin

subgroupMax

WaveActiveMax

subgroupExclusiveAdd

WavePrefixSum

subgroupExclusiveMul

WavePrefixProduct

subgroupBallotExclusiveBitCount

WavePrefixCountBits

subgroupBroadcast

WaveReadLaneAt

subgroupBroadcastFirst

WaveReadLaneFirst

subgroupQuadSwapHorizontal

QuadReadAcrossX

subgroupQuadSwapVertical

QuadReadAcrossY

subgroupQuadSwapDiagonal

QuadReadAcrossDiagonal

subgroupQuadBroadcast

QuadReadLaneAt

其他

GLSL HLSL 注意

gl_PointSize

[[vk::builtin("PointSize")]]

仅限 Vulkan,没有直接的 HLSL 等效项

gl_BaseVertexARB

[[vk::builtin("BaseVertex")]]

仅限 Vulkan,没有直接的 HLSL 等效项

gl_BaseInstanceARB

[[vk::builtin("BaseInstance")]]

仅限 Vulkan,没有直接的 HLSL 等效项

gl_DrawID

[[vk::builtin("DrawIndex")]]

仅限 Vulkan,没有直接的 HLSL 等效项

gl_DeviceIndex

[[vk::builtin("DeviceIndex")]]

仅限 Vulkan,没有直接的 HLSL 等效项

gl_ViewportMask

[[vk::builtin("ViewportMaskNV")]]

仅限 Vulkan,没有直接的 HLSL 等效项

gl_FragCoord

SV_Position

gl_FragDepth

SV_Depth

gl_FrontFacing

SV_IsFrontFace

gl_InstanceIndex

SV_InstanceID

gl_ViewIndex

SV_ViewID

gl_ClipDistance

SV_ClipDistance

gl_CullDistance

SV_CullDistance

gl_PointCoord

SV_Position

gl_Position

SV_Position

gl_PrimitiveID

SV_PrimitiveID

gl_ViewportIndex

SV_ViewportArrayIndex

gl_Layer

SV_RenderTargetArrayIndex

gl_SampleID

SV_SampleIndex

gl_SamplePosition

EvaluateAttributeAtSample

subpassLoad

<SubPassInput>.SubpassLoad

imageLoad

RWTexture1D/2D/3D<T>[]

imageStore

RWTexture1D/2D/3D<T>[]

atomicAdd

InterlockedAdd

atomicCompSwap

InterlockedCompareExchange

imageAtomicExchange

InterlockedExchange

nonuniformEXT

NonUniformResourceIndex

gl_BaryCoordEXT

SV_Barycentrics

gl_BaryCoordNoPerspEXT

带有 noperspective 的 SV_Barycentrics

函数

大多数 GLSL 函数在 HLSL 中也可用,反之亦然。本章列出名称不同的函数。具有 1:1 对应关系的函数(例如,isNan)未列出。

GLSL HLSL

dFdx

ddx

dFdxCoarse

ddx_coarse

dFdxFine

ddx_fine

dFdy

ddy

dFdyCoarse

ddy_coarse

dFdyFine

ddy_fine

fma

mad

fract

frac

mix

lerp