首页 > 解决方案 > 您可以在计算着色器中使用内置的导数函数吗?(伏尔甘)

问题描述

我想使用内置的衍生功能:

    vec3 dpdx = dFdx(p);
    vec3 dpdy = dFdy(p);

在计算着色器内部。但是我收到以下错误:

Message ID name: UNASSIGNED-CoreValidation-Shader-InconsistentSpirv
Message: Validation Error: [ UNASSIGNED-CoreValidation-Shader-InconsistentSpirv ] Object 0: handle = 0x5654380d4dd8, name = Logical device: GeForce GT 1030, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x6bbb14 | SPIR-V module not valid: OpEntryPoint Entry Point <id> '5[%main]'s callgraph contains function <id> 46[%BiplanarMapping_s21_vf3_vf3_f1_], which cannot be used with the current execution modes:
Derivative instructions require DerivativeGroupQuadsNV or DerivativeGroupLinearNV execution mode for GLCompute execution model: DPdx
Derivative instructions require DerivativeGroupQuadsNV or DerivativeGroupLinearNV execution mode for GLCompute execution model: DPdy

  %BiplanarMapping_s21_vf3_vf3_f1_ = OpFunction %v4float None %41

Severity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT

当我在网上搜索时,我似乎没有找到任何关于该主题的内容。

标签: graphicsglslshadervulkan

解决方案


衍生函数仅在片段着色器中起作用。导数基于正在渲染的图元中值的变化率。显然计算着色器不渲染图元,所以没有什么要计算的。

显然,NVIDIA 有一个扩展,为计算着色器提供了一些衍生计算能力。这就是奇怪的错误的来源。

片段着色器中的导数是通过从相邻调用中减去相同值来计算的。因此,您可以通过使用shared变量来模拟这一点。

首先,您必须确保空间上相邻的调用在同一个工作组中。因此,您的工作组大小需要是 2x2 调用的倍数。然后,您需要一个shared变量数组,您可以通过工作组内的调用对其进行索引。每个调用都应该将自己的值写入自己的索引。

要计算导数,请在将值写入变量后发出barrier(with )。取一个调用与同一个 2x2 四边形中相邻调用之间的差异。您应该确保同一个四边形中的所有调用都获得相同的值,方法是始终在四边形中的较低索引和较高索引之间进行减法。像这样的东西:memoryBarrierSharedshared

uvec2 quadIndex = gl_LocalInvocationID.xy / 2
/*type*/ derFdX = variable[quadIndex.x + 1][quadIndex.y + 0] - variable[quadIndex.x + 0][quadIndex.y + 0]
/*type*/ derFdY = variable[quadIndex.x + 0][quadIndex.y + 1] - variable[quadIndex.x + 0][quadIndex.y + 0]

NVIDIA 扩展基本上会为您执行此操作,尽管它可能更有效,因为它不需要该shared变量。


推荐阅读