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

时间:2018-01-11 10:13:01

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

我成了一个聚光灯

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

1 个答案:

答案 0 :(得分:0)

糟糕!这是因为0.95 - 1.0的范围太小而无法发挥作用!所以我不得不通过

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

现在它有一个柔软的优势。老实说,对我来说有点太软了。现在,我只是通过平方扩大的范围进行二次衰减,如你所见。有关让它看起来更好的任何提示吗?让我知道,谢谢。