为什么我的衰减不适用于这个基于点产品的聚光灯?

Why won't my falloff work for this dot product based spotlight?

本文关键字:于点产 聚光灯 衰减 我的 不适用 适用于 为什么      更新时间:2023-10-16

我做了一个聚光灯

  1. 将 3D 模型从每个灯光 POV 投影到渲染目标上以模拟阴影

  2. 从由于光照视锥
  3. 而投射到呈现目标上的正方形光中切出一个圆,然后只照亮该圆圈内的像素(当然,阴影部分除外),因此您看不到投影视锥体的方形边缘。

在执行 if 检查以查看光方向和光到顶点矢量的点积是否大于 .95 以获得我的初始截止值后,我将结果圆内的光强度值乘以相同的点积值,范围应介于 .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.95 - 1.0 的范围太小,无法产生影响!所以我不得不通过做

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

现在它有一个柔和的边缘。老实说,对我来说有点太软了。现在我只是通过平方扩展范围来做二次衰减,如您所见。有什么技巧可以让它看起来更好吗?让我知道,谢谢。