direct3d alphablend и пиксельные шейдеры - PullRequest
1 голос
/ 23 января 2012

У меня есть 2D-сцена, 2 текстуры, установленные в качестве целей рендеринга, и буфер вершин.

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

Все работает нормально, пока я не приду к экстремальным значениям яркости / контраста, которые выглядят как эффект затухания при изменении второго и перестают перерисовываться на очень экстремальных, хотя данные всегдакормили до первого.

Отключение AlphaBlendnable исправляет его, но я теряю альфа-смешивание ... Есть ли способ очистить буферы перед применением пиксельных шейдеров?Любая помощь приветствуется.

код пиксельного шейдера:

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__ );    

1 Ответ

0 голосов
/ 23 января 2012

Это сработало для меня, кажется, альфа-канал должен учитываться в этом случае

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;\
}\
...