#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 .