HLSL - 全局变量在几何着色器(DirectX11)中保持不变

时间:2013-01-07 13:22:01

标签: geometry directx shader global hlsl

我的程序接收输入由线段组成,并将线条扩展为类似圆柱体的对象(如DX SDK示例浏览器中的 PipeGS 项目)。

我为管道添加了一个半径缩放参数数组,并按程序修改它们,但是管道半径没有改变。

我很确定缩放参数每帧都会更新,因为我将它们设置为像素值。当我修改它们时,管道会改变颜色,而它们的半径保持不变。

所以我想知道在GS中使用全局变量是否有任何限制,我没有在互联网上找到它。 (或者我使用过错误的关键词)

着色器代码就像

cbuffer {
   .....
   float scaleParam[10];
   .....
}

// Pass 1
VS_1 { // pass through }

// Tessellation stages
// Hull shader, domain shader and patch constant function

GS_1 {
   pipeRadius = MaxRadius * scaleParam[PipeID];
   ....
   // calculate pipe positions base on line-segments and pipeRadius
   ....
   OutputStream.Append ( ... );
}

// Pixel shader is disabled in the first pass

// Pass 2 
VS_2 { // pass through }

// Tessellation stages
// Hull shader, domain shader and patch constant function
// Transform the vertices and normals to world coordinate in DS

// No geometry shader in the second pass

PS_2 
{ 
   return float4( scaleParam[0], scaleParam[1], scaleParam[2], 0.0f );
}

编辑: 我缩小了这个问题。 在我的程序中有2个传递,在第一个传递中,我计算了几何着色器中的线段扩展和流出。

在第二遍中,程序从第一遍开始接收管道位置,对管道进行细分并对它们应用置换贴图,以便它们更加详细。

我可以更改第二遍中的曲面细分因子和像素颜色,并立即在屏幕上查看结果。

当我修改scaleParam时,管道会改变颜色,而它们的半径保持不变。这意味着我确实更改了scaleParam并将它们正确地传递给着色器,但是在第一遍中出现了错误。

第二次编辑:

我修改了上面的着色器代码并在此处发布了一些cpp文件的代码。 在cpp文件中:

void DrawScene() 
{
    // Update view matrix, TessFactor, scaleParam etc.
    ....
    ....

    // Bind stream-output buffer
    ID3D11Buffer* bufferArray[1] = {mStreamOutBuffer};
    md3dImmediateContext->SOSetTargets(1, bufferArray, 0);

    // Two pass rendering
    D3DX11_TECHNIQUE_DESC techDesc;
    mTech->GetDesc( &techDesc );
    for(UINT p = 0; p < techDesc.Passes; ++p)
    {
        mTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);

        // First pass
        if (p==0) 
        {
            md3dImmediateContext->IASetVertexBuffers(0, 1, 
                                   &mVertexBuffer, &stride, &offset);

            md3dImmediateContext->Draw(mVertexCount,0);

            // unbind stream-output buffer
            bufferArray[0] = NULL;
            md3dImmediateContext->SOSetTargets( 1, bufferArray, 0 );
        }
        // Second pass
        else 
        {                
            md3dImmediateContext->IASetVertexBuffers(0, 1, 
                                   &mStreamOutBuffer, &stride, &offset);

            md3dImmediateContext->DrawAuto();
        }
    }
    HR(mSwapChain->Present(0, 0));
}

2 个答案:

答案 0 :(得分:1)

检查您是否使用float4位置,向量的w值是场景中最终位置的比例,例如:

float4 pos0 = float4(5, 5, 5, 1);
// is equals that:
float4 pos1 = float4(10, 10, 10, 2);

要纠正一个位置,你必须只改变矢量位置的.xyz值。

答案 1 :(得分:0)

我通过在修改参数后每次重建顶点缓冲区和流输出缓冲区来解决这个问题,但我仍然不知道究竟是什么导致了这个问题。