Почему мой спад не работает для этого точечного прожектора на основе точечного продукта?

Я сделал акцент на том, что

  1. Проецирует 3d модели на цель рендеринга от каждого источника света для имитации теней

  2. Вырезает круг из квадрата света, который был спроецирован на цель рендеринга в результате светового усеченного контура, затем подсвечивает только пиксели внутри этого круга (за исключением, конечно, затененных частей), поэтому вы не видите краев квадрата прогнозируемого усеченного конуса.

После проверки if, чтобы увидеть, является ли точечное произведение направления света и вектора света на вершину больше, чем 0,95, чтобы получить мое начальное отсечение, я затем умножаю значение интенсивности света внутри результирующего круга на то же значение точечного произведения, которое должно диапазон от 0,95 до 1,0.

Это должно дать свет внутри этого круга спад со 100% до 0% в направлении к краю круга. Однако спада нет. Просто все одинаково освещено внутри круга. С какой стати я понятия не имею. Если кто-то может взять гандера и сообщить мне, пожалуйста, помогите, большое спасибо.

float CalculateSpotLightIntensity(
float3 LightPos_VertexSpace,
float3 LightDirection_WS,
float3 SurfaceNormal_WS)
{
//float3 lightToVertex = normalize(SurfacePosition - LightPos_VertexSpace);
float3 lightToVertex_WS = -LightPos_VertexSpace;

float dotProduct = saturate(dot(normalize(lightToVertex_WS), normalize(LightDirection_WS)));

// METALLIC EFFECT (deactivate for now)
float metalEffect = saturate(dot(SurfaceNormal_WS, normalize(LightPos_VertexSpace)));
if(dotProduct > .95 /*&& metalEffect > .55*/)
{
return saturate(dot(SurfaceNormal_WS, normalize(LightPos_VertexSpace)));
//return saturate(dot(SurfaceNormal_WS, normalize(LightPos_VertexSpace))) * dotProduct;
//return dotProduct;
}
else
{
return 0;
}
}

float4 LightPixelShader(PixelInputType input) : SV_TARGET
{
float2 projectTexCoord;
float depthValue;
float lightDepthValue;
float4 textureColor;

// Set the bias value for fixing the floating point precision issues.
float bias = 0.001f;

// Set the default output color to the ambient light value for all pixels.
float4 lightColor = cb_ambientColor;

/////////////////// NORMAL MAPPING //////////////////
float4 bumpMap = shaderTextures[4].Sample(SampleType, input.tex);

// Expand the range of the normal value from (0, +1) to (-1, +1).
bumpMap = (bumpMap * 2.0f) - 1.0f;

// Change the COORDINATE BASIS of the normal into the space represented by basis vectors tangent, binormal, and normal!
float3 bumpNormal = normalize((bumpMap.x * input.tangent) + (bumpMap.y * input.binormal) + (bumpMap.z * input.normal));//////////////// LIGHT LOOP ////////////////
for(int i = 0; i < NUM_LIGHTS; ++i)
{
// Calculate the projected texture coordinates.
projectTexCoord.x =  input.vertex_ProjLightSpace[i].x / input.vertex_ProjLightSpace[i].w / 2.0f + 0.5f;
projectTexCoord.y = -input.vertex_ProjLightSpace[i].y / input.vertex_ProjLightSpace[i].w / 2.0f + 0.5f;

if((saturate(projectTexCoord.x) == projectTexCoord.x) && (saturate(projectTexCoord.y) == projectTexCoord.y))
{
// Sample the shadow map depth value from the depth texture using the sampler at the projected texture coordinate location.
depthValue = shaderTextures[6 + i].Sample(SampleTypeClamp, projectTexCoord).r;

// Calculate the depth of the light.
lightDepthValue = input.vertex_ProjLightSpace[i].z / input.vertex_ProjLightSpace[i].w;

// Subtract the bias from the lightDepthValue.
lightDepthValue = lightDepthValue - bias;

float lightVisibility = shaderTextures[6 + i].SampleCmp(SampleTypeComp, projectTexCoord, lightDepthValue );

// Compare the depth of the shadow map value and the depth of the light to determine whether to shadow or to light this pixel.
// If the light is in front of the object then light the pixel, if not then shadow this pixel since an object (occluder) is casting a shadow on it.
if(lightDepthValue < depthValue)
{
// Calculate the amount of light on this pixel.
float lightIntensity = saturate(dot(bumpNormal, normalize(input.lightPos_LS[i])));

if(lightIntensity > 0.0f)
{
// Determine the final diffuse color based on the diffuse color and the amount of light intensity.
float spotLightIntensity = CalculateSpotLightIntensity(
input.lightPos_LS[i], // NOTE - this is NOT NORMALIZED!!!
cb_lights[i].lightDirection,
bumpNormal/*input.normal*/);

lightColor += cb_lights[i].diffuseColor*spotLightIntensity* .18f; // spotlight
//lightColor += cb_lights[i].diffuseColor*lightIntensity* .2f; // square light
}
}
}
}

// Saturate the final light color.
lightColor = saturate(lightColor);
// lightColor = saturate( CalculateNormalMapIntensity(input, lightColor, cb_lights[0].lightDirection));

// TEXTURE ANIMATION -  Sample pixel color from texture at this texture coordinate location.
input.tex.x += textureTranslation;

// BLENDING
float4 color1 = shaderTextures[0].Sample(SampleTypeWrap, input.tex);
float4 color2 = shaderTextures[1].Sample(SampleTypeWrap, input.tex);
float4 alphaValue = shaderTextures[3].Sample(SampleTypeWrap, input.tex);
textureColor = saturate((alphaValue * color1) + ((1.0f - alphaValue) * color2));

// Combine the light and texture color.
float4 finalColor = lightColor * textureColor;

/////// TRANSPARENCY /////////
//finalColor.a = 0.2f;

return finalColor;
}

0

Решение

К сожалению! Это потому, что диапазон 0,95 — 1,0 был слишком мал, чтобы иметь значение! Поэтому мне пришлось расширить диапазон до 0 ~ 1, выполнив

float expandedRange = (dotProduct - .95)/.05f;
return saturate(dot(SurfaceNormal_WS, normalize(LightPos_VertexSpace))*expandedRange*expandedRange);

Теперь у этого есть мягкий край. Честно говоря, слишком мягко для меня. Теперь я просто делаю квадратичный спад, возводя в квадрат расширенный диапазон, как вы можете видеть. Какие-нибудь советы, как сделать его лучше? Дайте мне знать, спасибо.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]