【问题标题】:Why won't my falloff work for this dot product based spotlight?为什么我的衰减不适用于这种基于点积的聚光灯?
【发布时间】:2018-06-20 15:10:29
【问题描述】:

我做了一个聚光灯

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

  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;
}

【问题讨论】:

    标签: c++ graphics directx-11 hlsl spotlight


    【解决方案1】:

    哎呀!这是因为 0.95 - 1.0 的范围太小而无法产生影响!所以我不得不通过做

    将范围扩大到 0~1
    float expandedRange = (dotProduct - .95)/.05f;
    return saturate(dot(SurfaceNormal_WS, normalize(LightPos_VertexSpace))*expandedRange*expandedRange);
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多