0

我在使用着色器时遇到了一些问题,而且我不断收到这个让我发疯的奇怪编译错误!

以下像素着色器代码片段:

            DirectionVector = normalize(f3LightPosition[i] - PixelPos);
            LightVec = PixelNormal - DirectionVector;

            // Get the light strenght factor
            LightStrFactor = float(abs((LightVec.x + LightVec.y + LightVec.z) / 3.0f));

            // TEST!!!
            LightStrFactor = 1.0f;

            // Add this light to the total light on this pixel
            LightVal += f4Light[i] * LightStrFactor;

效果很好,但只要我删除“LightStrFactor = 1.0f;” 行,即让'LightStrFactor'值作为上面计算的结果,它无法编译着色器。

LightStrFactor 是一个浮点数 LightVal & f4Light[i] 是 float4 其余的都是 float3。

我的问题是,除了为什么它不编译之外,DX 编译器是如何关心浮点值的?即使我的值不正确,它不应该是运行时的吗?着色器编译代码是这样的:

/* Compile the bitch */
if (FAILED(D3DXCompileShaderFromFile(fileName, NULL, NULL, "PS_MAIN", "ps_2_0", 0, &this->m_pCode, NULL, &this->m_constantTable)))
    GraphicException("Failed to compile pixel shader!");  // <-- gets here :(

if (FAILED(g_D3dDevice->CreatePixelShader( (DWORD*)this->m_pCode->GetBufferPointer(), &this->m_hPixelShader )))
    GraphicException("Failed to create pixel shader!");

this->m_fLoaded = true;

任何帮助表示感谢谢谢!!!:]

4

3 回答 3

0

像素着色器不支持 C++ 风格的强制转换——在你的例子中是float(...。)由于它完全多余,你可以摆脱它,但如果你想要一个演员,(float)在 C 中使用

于 2010-03-22T19:29:40.430 回答
0

不要忘记着色器在编译时会得到很多优化。这可能是硬编码值时它不会失败的原因。

当您在分配一个方程式后立即对一个值进行硬编码时,整个方程式会得到优化,而您只会被最终分配所遗漏。

于 2010-03-22T18:28:04.137 回答
0

从您的着色器片段中,看起来您正在迭代多个灯光,并累积它们的贡献。

我的猜测是,当编译器使用您的实际光着色计算展开循环时,编译后的着色器使用的算术指令槽比 ps_2_0 配置文件支持的更多(最多 64 条指令)。

当您将计算替换为 LightStrFactor=1 时,编译器会完全优化掉它前面的三个代码行,这会导致您的测试着色器显着缩短,因此适合分配的 64 条指令。

如果您的应用程序硬件目标可能,简单地调整着色器配置文件版本将允许您的着色器使用更多指令槽,并且编译时不会出错。ps_3_0 / ps_2_a / ps_2_b 中的任何一个都应该能够编译您的着色器。(2_a/b 配置文件有点混蛋,但官方支持,NV/ATI 对基本 2_0 配置文件的扩展)

(正如另一个回复中提到的,花时间捕获和打印编译错误将非常值得您花时间。)

于 2010-03-25T10:30:03.710 回答