У меня есть проблема, которую я не могу понять. Я просто добавил точечный свет в свой проект, и он делает текстуры полностью черными. Понятия не имею почему.
Я думаю, что это может быть либо нормаль, которая не обновляется правильно, либо это может быть вычисление s.x, s.y и s.z.
Я был бы очень рад, если бы у кого-то было время взглянуть на это и помочь мне. Благодарю.
Так. Вот мой пиксельный шейдер:
Texture2D txDiffuse : register(t0);
SamplerState sampState;
cbuffer PointLight : register(b0)
{
float3 Pos;
float diff;
float amb;
float spec;
float range;
float intensity;
};
struct VS_IN
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
float4 Norm : NORMAL;
float4 Pos2 : POSITION;
};
float4 PS_main(VS_IN input) : SV_Target
{
float3 s = txDiffuse.Sample(sampState, input.Tex).xyz;
float3 lightPos = Pos;
float3 lightVector = lightPos - input.Pos2;
lightVector = normalize(lightVector);
float nDotL = dot(lightVector, input.Norm);
float diff1 = 0.8;
float amb1 = 0.1;
s.x = (s.x * diff * nDotL + s.x * amb);
s.y = (s.y * diff * nDotL + s.y * amb);
s.z = (s.z * diff * nDotL + s.z * amb);return float4(s, 0.0);
};
Геометрия шейдера:
cbuffer worldMatrix : register(b0)
{
matrix world;
}
cbuffer viewMatrix : register(b1)
{
matrix view;
}
cbuffer projectionMatrix : register(b2)
{
matrix projection;
}
struct VS_IN
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
};
struct VS_OUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
float4 Norm : NORMAL;
float4 Pos2 : POSITION;
};
[maxvertexcount(6)]
void main(triangle VS_IN input[3] : SV_POSITION, inout TriangleStream< VS_OUT > output2)
{
matrix wvp = mul(projection, mul(world, view));
matrix worldView = mul(world, view);float4 normal = float4(cross(input[1].Pos - input[0].Pos, input[2].Pos - input[0].Pos), 0.0f);
normal = normalize(normal);
float4 rotNorm = mul(worldView, normal);
rotNorm = normalize(rotNorm);
VS_OUT output[3];
for (uint i = 0; i < 3; i++)
{
output[i].Pos = input[i].Pos;
output[i].Pos = mul(wvp, input[i].Pos);
output[i].Tex = input[i].Tex;
output[i].Norm = rotNorm;
output[i].Pos2 = mul(worldView, output[i].Pos);
output2.Append(output[i]);
}
output2.RestartStrip();
VS_OUT outputcopy[3];
for (uint i = 0; i < 3; i++)
{
outputcopy[i].Pos = input[i].Pos + (normal);
outputcopy[i].Pos = mul(wvp, outputcopy[i].Pos);
outputcopy[i].Tex = input[i].Tex;
outputcopy[i].Norm = rotNorm;
outputcopy[i].Pos2 = mul(worldView, outputcopy[i].Pos);
output2.Append(outputcopy[i]);
}
output2.RestartStrip();
}
Код для инициализации точечного источника света:
struct PointLight
{
Vector3 Pos;
float diff;
float amb;
float spec;
float range;
float intensity;
};
PointLight* pointLight = nullptr;
PointLight PL =
{
Vector3(0.0f, 0.0f, -3.0f),
0.8f,
0.2f,
0.0f,
100.0f,
1.0f
};
pointLight = &PL;
D3D11_BUFFER_DESC lightBufferDesc;
memset(&lightBufferDesc, 0, sizeof(lightBufferDesc));
lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightBufferDesc.Usage = D3D11_USAGE_DEFAULT;
lightBufferDesc.StructureByteStride = 0;
lightBufferDesc.MiscFlags = 0;
lightBufferDesc.ByteWidth = sizeof(PointLight);
D3D11_SUBRESOURCE_DATA pointLightData;
memset(&pointLightData, 0, sizeof(pointLightData));
pointLightData.pSysMem = &PL;
gDevice->CreateBuffer(&lightBufferDesc, &pointLightData, &lightBuffer);
и в render () я бегу
gDeviceContext->PSSetConstantBuffers(0, 1, &lightBuffer);
Текстура будет черной, если s.x
, s.y
, s.z
равно нулю.
s.x = (s.x * diff * nDotL + s.x * amb);
s.y = (s.y * diff * nDotL + s.y * amb);
s.z = (s.z * diff * nDotL + s.z * amb);
Попробуй поменять diff
а также amb
с ненулевой константой, так что вы можете быть уверены, что вы установили постоянный буфер правильно или нет. Если после того, как вы измените их, он все еще черный, то это должно быть nDotL
и / или выборочная текстура, которая равна нулю. Затем попробуйте с ненулевой константой для образца текстуры. Если они все еще заставляют текстуру выглядеть черной, виноват ваш расчет вектора света.
Других решений пока нет …