Возникли проблемы с преобразованием пиксельной шейдера d3d9 в d3d11

#shader #hlsl #direct3d #direct3d11 #pixel-shader

#шейдер #hlsl #direct3d #direct3d11 #пиксельный шейдер

Вопрос:

У меня есть этот пиксельный шейдер, который я пытаюсь преобразовать. Я исправил весь синтаксис для d3d11, но когда я запускаю файл HLSL через компилятор, который выдает файл .fxc, он выдает эту ошибку:

 warning X3206: 'dot': implicit truncation of vector type
 

Обратите внимание, что я вообще плохо разбираюсь в этом.

Вот код.

 // Global variables
Texture2D<float4> img;
sampler imgSampler;

Texture2D<float4> bkd : register(t1);
sampler bkdSampler : register(s1);

cbuffer PS_VARIABLES : register(b0)
{
int lightAenabled, lightBenabled, lightCenabled;
float4 lightAColor, lightBColor, lightCColor, ambientLight;
float lightAX, lightBX, lightCX;
float lightAY, lightBY, lightCY;
float lightAZ, lightBZ, lightCZ;
float lightABrightness, lightBBrightness, lightCBrightness;
float objX, objY;

};

cbuffer PS_PIXELSIZE : register(b1)
{
float fPixelWidth;
float fPixelHeight;
};


float4 ps_main(in float2 texCoord : TEXCOORD ) : SV_TARGET
{
    float4 normal = img.Sample(imgSampler, texCoord);
    normal = float4(normal.x - 0.5, normal.y - 0.5, normal.z - 0.5, normal.w);
    float4 background = bkd.Sample(bkdSampler, texCoord);
    float4 color = float4(0,0,0,normal.a);
    float3 pixelPos = float3(texCoord.xy,0);
    float3 objPos = float3(objX,objY,0);
    float3 lightPos;
    float3 dir;
    float dist, amount;
    
    

    if(lightAenabled)
    {
        
        lightPos = float3((lightAX-objX)*fPixelWidth 0.5,(lightAY-objY)*fPixelHeight 0.5,lightAZ);
        dir = normalize(lightPos - pixelPos);
        dist = 1/length(lightPos - pixelPos);
        float3 amount = (normal, dir);
        color.rgb  = amount * lightABrightness * dist * lightAColor.rgb;
    }
    
    if(lightBenabled)
    {
        lightPos = float3((lightBX-objX)*fPixelWidth 0.5,(lightBY-objY)*fPixelHeight 0.5,lightBZ);
        dir = normalize(lightPos - pixelPos);
        dist = 1/length(lightPos - pixelPos);
         amount = saturate(dot(normal,dir));
        color.rgb  = amount * lightBBrightness * dist * lightBColor.rgb;
    }
    
    if(lightCenabled)
    {
        lightPos = float3((lightCX-objX)*fPixelWidth 0.5,(lightCY-objY)*fPixelHeight 0.5,lightCZ);
        dir = normalize(lightPos - pixelPos);
        dist = 1/length(lightPos - pixelPos);
        amount = saturate(dot(normal,dir));
        color.rgb  = amount * lightCBrightness * dist * lightCColor.rgb;
    }

    return float4(ambientLight.rgb,0)   color * background;
};



float4 Demultiply(float4 _color)
{
float4 color = _color;
    if ( color.a != 0 )
        color.rgb /= color.a;
    return color;
}



float4 ps_main_pm(in float2 texCoord : TEXCOORD ) : SV_TARGET
{
    float4 normal = Demultiply(img.Sample(imgSampler, texCoord));
    normal = float4(normal.x-0.5, normal.y-0.5, normal.z-0.5, normal.w);
    float4 background = Demultiply(bkd.Sample(bkdSampler, texCoord));
    float4 color = float4(0,0,0,normal.a);
    float4 O = float4(ambientLight.rgb, 0)   color * background;
    float3 pixelPos = float3(texCoord.xy,0);
    float3 objPos = float3(objX,objY,0);
    float3 lightPos, dir;
    float dist, amount; 
    


    if(lightAenabled)
    {
        lightPos = float3((lightAX-objX)*fPixelWidth 0.5,(lightAY-objY)*fPixelHeight 0.5,lightAZ);
        dir = normalize(lightPos - pixelPos);
        dist = 1/length(lightPos - pixelPos);
        amount = saturate(dot(normal,dir));
        color.rgb  = amount * lightABrightness * dist * lightAColor.rgb;
    }
    
    if(lightBenabled)
    {
        lightPos = float3((lightBX-objX)*fPixelWidth 0.5,(lightBY-objY)*fPixelHeight 0.5,lightBZ);
        dir = normalize(lightPos - pixelPos);
        dist = 1/length(lightPos - pixelPos);
        amount = saturate(dot(normal,dir));
        color.rgb  = amount * lightBBrightness * dist * lightBColor.rgb;
    }
    
    if(lightCenabled)
    {
        lightPos = float3((lightCX-objX)*fPixelWidth 0.5,(lightCY-objY)*fPixelHeight 0.5,lightCZ);
        dir = normalize(lightPos - pixelPos);
        dist = 1/length(lightPos - pixelPos);
        amount = saturate(dot(normal,dir));
        color.rgb  = amount * lightCBrightness * dist * lightCColor.rgb;
    }

    O.rgb *= O;
    return O;
    
}; 

Ответ №1:

Это normal 4-вектор. Это dir 3-вектор. Скалярное произведение допустимо только для векторов одинаковой длины.

В этом случае normal.a в «обычной текстуре» есть какое-то другое значение, поэтому вы можете просто использовать маскирование / прокрутку исходного регистра, чтобы преобразовать его в 3-вектор, что и происходит неявно:

 amount = saturate(dot(normal.xyz,dir));
 

normal.rgb и normal.xyz сделал бы то же самое.

Комментарии:

1. Ах, хорошо, спасибо. Теперь компилятор выдает fxc без каких-либо ошибок, но шейдер теперь полностью черный. Вы случайно не знаете, почему это так? При необходимости я могу опубликовать исходный код d3d9.

2. Графическая отладка является сложной задачей. Любое количество ошибок может привести к появлению черного экрана. Лучший совет, который я могу вам дать, — это отталкиваться от рабочего примера и добавлять что-то одно за раз. Убедитесь, что у вас включено устройство отладки , и проверьте все HRESULT возвращаемые значения на предмет успеха / неудачи. Возможно, вы также захотите ознакомиться с DirectX Tool Kit для DX11 .