Пиксельный шейдер странная ошибка компиляции - PullRequest
0 голосов
/ 22 марта 2010

Я немного сталкиваюсь с шейдерами и получаю эту странную ошибку компиляции, которая сводит меня с ума!

следующий фрагмент кода пиксельного шейдера:

            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 является float LightVal & f4Light [i] являются float4. Все остальные являются float3.

Мой вопрос, кроме того, почему он не компилируется, почему DX-компилятор заботится о значении float?даже если мои значения неверны, разве это не должно быть во время выполнения?код компиляции шейдера такой:

/* 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;

любая помощь приветствуется, спасибо !!!:]

Ответы [ 3 ]

0 голосов
/ 22 марта 2010

Пиксельные шейдеры не поддерживают приведение в стиле C ++ - пример float( ... ) в вашем примере.Поскольку он полностью избыточен, вы можете просто избавиться от него, но если вы хотите использовать приведение, используйте (float) как в C

0 голосов
/ 25 марта 2010

Из вашего фрагмента шейдера похоже, что вы перебираете множество источников света, накапливая их вклад.

Я полагаю, что когда компилятор развернет цикл с вашими фактическими вычислениями легкого затенения, скомпилированный шейдер использует больше слотов арифметических команд, чем поддерживает профиль ps_2_0 (максимум 64 инструкции).

Когда вы заменяете вычисления на LightStrFactor = 1, компилятор полностью оптимизирует три предшествующие ему строки кода, в результате чего ваш тестовый шейдер становится значительно короче и, следовательно, помещается в выделенные 64 инструкции.

Если это возможно для аппаратной цели вашего приложения, простое изменение версии профиля шейдера позволит вашему шейдеру использовать больше слотов с инструкциями и компилировать без ошибок. Любой из ps_3_0 / ps_2_a / ps_2_b должен иметь возможность скомпилировать ваш шейдер. (Профили 2_a / b являются ублюдком, но официально поддерживаются, расширения NV / ATI для базового профиля 2_0)

(Как уже упоминалось в другом ответе, потратить время на то, чтобы зафиксировать и распечатать ошибки компиляции, стоит вашего времени.)

0 голосов
/ 22 марта 2010

Не забывайте, что шейдеры много оптимизируются во время компиляции. Это может быть причиной того, что он не завершится ошибкой, когда вы жестко закодируете значение.

Когда вы жестко кодируете значение сразу после присвоения ему уравнения, все уравнение оптимизируется, и вы остаетесь только с окончательным назначением.

...