【问题标题】:direct3d alphablend and pixel shadersdirect3d alphablend 和像素着色器
【发布时间】:2012-02-16 20:04:39
【问题描述】:

我有一个 2D 场景、2 个设置为渲染目标的纹理和一个顶点缓冲区。

第一个纹理被对比度/亮度像素着色器过滤掉,第二个作为一个菜单,我不想被同一个着色器处理,但希望它与第一个着色器混合。

一切都运行良好,直到我达到亮度/对比度的极端值,这看起来像是更改第二个时的淡出效果,并且在非常极端的情况下它完全停止重绘,尽管数据总是被馈送到第一个。

禁用 AlphaBlendnable 可以纠正它,但我会松动 alpha 混合...在应用像素着色器之前有什么方法可以清理缓冲区吗?任何帮助表示赞赏。

像素着色器代码:

float offsetBrightness = 0.0f; \
float offsetContrast   = 0.0f; \
float4 PSBrightnessContrast(float2 inCoord : TEXCOORD0) : COLOR0\
{\
    float4 color = tex2D( screen, inCoord.xy); \
    color = color + offsetBrightness; \
    color = color * (1.0 + offsetContrast); \
    return saturate( color ); \
}\

渲染代码

// Begin the scene
    hr = IDirect3DDevice9_BeginScene(d3ddev);
  if (FAILED(hr)) 
    throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );

// Render the vertex buffer contents
hr = IDirect3DDevice9_SetStreamSource(d3ddev, 0, d3dvtc, 0, sizeof(CUSTOMVERTEX));
if (FAILED(hr)) {
    IDirect3DDevice9_EndScene(d3ddev);
    throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
}

// we use FVF instead of vertex shader
hr = IDirect3DDevice9_SetFVF(d3ddev, D3DFVF_CUSTOMVERTEX);
if (FAILED(hr)) {
    IDirect3DDevice9_EndScene(d3ddev);
    throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
}

//apply shaders

UINT shaderPasses;
if(d3dxShader)
{
    hr = d3dxShader->Begin( &shaderPasses, 0 );
    if (FAILED(hr))
        throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
}
else
    shaderPasses = 1;

for( UINT uPass = 0; uPass < shaderPasses; ++uPass )
{
    if(d3dxShader)
    {
        hr = d3dxShader->BeginPass(uPass);
        if (FAILED(hr))
            throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
    }

    hr = IDirect3DDevice9_SetTexture(d3ddev, 0, (LPDIRECT3DBASETEXTURE9)d3dtex);
    if (FAILED(hr)) {
        IDirect3DDevice9_EndScene(d3ddev);
        throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
    }

    // draw rectangle
    hr = IDirect3DDevice9_DrawPrimitive(d3ddev, D3DPT_TRIANGLEFAN, 0, 2);
    if (FAILED(hr)) {
        IDirect3DDevice9_EndScene(d3ddev);
        throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
    }

    if(d3dxShader)
    {
        hr = d3dxShader->EndPass();
        if (FAILED(hr))
            throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
    }
}

if(d3dxShader)
{
    hr = d3dxShader->End();
    if (FAILED(hr))
        throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
}

// Render the vertex buffer contents
hr = IDirect3DDevice9_SetStreamSource(d3ddev, 0, d3dvtc, 0, sizeof(CUSTOMVERTEX));
if (FAILED(hr)) {
    IDirect3DDevice9_EndScene(d3ddev);
    throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
}

// we use FVF instead of vertex shader
hr = IDirect3DDevice9_SetFVF(d3ddev, D3DFVF_CUSTOMVERTEX);
if (FAILED(hr)) {
    IDirect3DDevice9_EndScene(d3ddev);
    throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
}

// Setup our texture. Using textures introduces the texture stage states,
// which govern how textures get blended together (in the case of multiple
// textures) and lighting information. In this case, we are modulating
// (blending) our texture with the diffuse color of the vertices.
hr = IDirect3DDevice9_SetTexture(d3ddev, 0, (LPDIRECT3DBASETEXTURE9)d3dtex2);
if (FAILED(hr)) {
    IDirect3DDevice9_EndScene(d3ddev);
    throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
}

// draw rectangle
hr = IDirect3DDevice9_DrawPrimitive(d3ddev, D3DPT_TRIANGLEFAN, 0, 2);
if (FAILED(hr)) {
    IDirect3DDevice9_EndScene(d3ddev);
    throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );
}

// End the scene
hr = IDirect3DDevice9_EndScene(d3ddev);
if (FAILED(hr)) 
    throw FatalException( DXGetErrorDescription(hr), _T(__FILE__), __LINE__ );    

【问题讨论】:

    标签: direct3d alphablending pixel-shader


    【解决方案1】:

    这对我有用,似乎在这种情况下必须考虑 alpha 通道

    float offsetBrightness = 0.0f; \
    float offsetContrast   = 0.0f; \
    float4 PSBrightnessContrast(float2 inCoord : TEXCOORD0) : COLOR0\
    {\
       float4 pixelColor = tex2D( screen, inCoord.xy); \
       pixelColor.rgb /= pixelColor.a; \
       \
      pixelColor.rgb = ((pixelColor.rgb + 1.0f) * max(offsetContrast, 0)) - 1.0f; \
      pixelColor.rgb += offsetBrightness; \
      pixelColor.rgb *= pixelColor.a; \
    \
     return pixelColor;\
    }\
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多