首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多点灯加减光

多点灯加减光
EN

Stack Overflow用户
提问于 2022-05-19 17:23:21
回答 1查看 53关注 0票数 1

我目前正在尝试添加多点灯光到我的游戏。我所做的似乎主要是在工作,除了一个小的问题,混合轻下降。这里有两张图片向你展示正在发生的事情。在第一个,光衰减被评论掉。两个点灯都显示正确。

这是第二张图片,在这里,我启用了光下坠。你会看到只有光#2是“大部分”可见。有轻#1的痕迹,但在大多数情况下,光#1似乎被轻#2的衰败所覆盖。换句话说,每一个连续的光的衰减超过了以前的光。

有谁知道如何增加多点灯光的衰减吗?我肯定我做了一些轻微的错误,这就是为什么灯没有适当地积累起来。

这是我的着色器

代码语言:javascript
复制
struct Vertex
{
    float4 pos : POSITION;
    float2 tex : TEXTURE;
    float3 norm : NORMAL;
};

struct PixelShaderArgs
{
    float4 pos : SV_POSITION;
    float2 col : TEXTURE;
    float3 norm : NORMAL;
    float3 worldPos : POSITION;
};

struct PointLightShaderArgs
{
    float3 pos;
    float radius;
    float intensity;
    float3 padding;
    float4 ambient;
    float4 diffuse;
};

Texture2D ShaderTexture : register(t0);
SamplerState Sampler : register(s0);

float4x4 localMatrix : register(b0);
cbuffer ShaderDataBuffer : register(b1)
{
    float2 TextureResolution;
};
cbuffer cbPerFrame : register(b3)
{
    PointLightShaderArgs light[8];
};

cbuffer WorldPositionBuffer : register(b4)
{
    float4x4 World;
};

PixelShaderArgs VertexShaderMain(Vertex vertex)
{
    PixelShaderArgs output;
    output.pos = mul(vertex.pos, localMatrix);
    output.col = vertex.tex;
    output.norm = mul(vertex.norm, World);
    output.worldPos = mul(vertex.pos, World);
    return output;
}

int2 convertUVToPixel(float u, float v)
{
    int width = TextureResolution.x;
    int height = TextureResolution.y;
    int xCoordinate = floor(u * width);
    int yCoordinate = floor(v * height);
    return int2(xCoordinate % width, yCoordinate % height);
}

float Falloff(float distance, float radius)
{
    return clamp(1.0f - (distance / radius), 0.0, 1.0);
}

#define ATTENUATION_CONSTANT 1.0f // 0% Constant
#define ATTENUATION_LINEAR 0.0f // 100% Linear
#define ATTENUATION_QUADRATIC 0.0f // 100% Quadratic


float4 PixelShaderMain(PixelShaderArgs pixelShaderArgs) : SV_Target
{
    float u = pixelShaderArgs.col.x;
    float v = pixelShaderArgs.col.y;
    // Lighting
    float3 fragColor = float3(0.0f, 0.0f, 0.0f);
    float4 diffuse = ShaderTexture.Load(int3(convertUVToPixel(u, v), 0));
    for (int i = 0; i < 2; i++)
    {
        
        
        float3 ambient = diffuse * light[i].ambient;
        pixelShaderArgs.norm = normalize(pixelShaderArgs.norm);
        float3 lightToPixelVec = light[i].pos - pixelShaderArgs.worldPos;
        float distance = length(lightToPixelVec);
        float luminosity = dot(lightToPixelVec / distance, pixelShaderArgs.norm);
        float intensity = 1.00f;
        if (luminosity > 0.0f)
        {
        
            // Do lighting attenuation
            fragColor += luminosity * diffuse * light[i].diffuse;
            fragColor /= ATTENUATION_CONSTANT + (ATTENUATION_LINEAR * distance) + (ATTENUATION_QUADRATIC * (distance * distance));
            fragColor *= light[i].intensity; // multiply the final result by the intensity.
            fragColor *= Falloff(distance, light[i].radius); // This is what's causing the problem!!
            //fragColor = saturate(fragColor + ambient);
        }
        
    }
    return float4(fragColor, diffuse.a);
        
}
EN

回答 1

Stack Overflow用户

发布于 2022-05-19 22:08:27

我想出来了。解决方案是将下降计算向上移动,并使用以下行内联:fragColor += luminosity * diffuse * light[i].diffuse * Falloff(distance,light[i].radius);

这将导致校正的跌落混合,如图所示:

另一张照片显示三个重叠点灯:

这是更新后的着色器(第一个版本中做了很多修改,因为我实际上是很晚才发布这个答案)

代码语言:javascript
复制
struct Vertex
{
    float4 pos : POSITION;
    float2 tex : TEXTURE;
    float3 norm : NORMAL;
};

struct PixelShaderArgs
{
    float4 pos : SV_POSITION;
    float2 col : TEXTURE;
    float3 norm : NORMAL;
    float3 worldPos : POSITION;
};

struct PointLightShaderArgs
{
    float3 pos;
    float radius;
    float intensity;
    float3 padding;
    float4 ambient;
    float4 diffuse;
};

Texture2D ShaderTexture : register(t0);
SamplerState Sampler : register(s0);

float4x4 localMatrix : register(b0);
cbuffer ShaderDataBuffer : register(b1)
{
    float2 TextureResolution;
};
cbuffer cbPerFrame : register(b3)
{
    PointLightShaderArgs light[32];
};

cbuffer WorldPositionBuffer : register(b4)
{
    float4x4 World;
};

PixelShaderArgs VertexShaderMain(Vertex vertex)
{
    PixelShaderArgs output;
    output.pos = mul(vertex.pos, localMatrix);
    output.col = vertex.tex;
    output.norm = mul(vertex.norm, World);
    output.worldPos = mul(vertex.pos, World);
    return output;
}

int2 convertUVToPixel(float u, float v)
{
    int width = TextureResolution.x;
    int height = TextureResolution.y;
    int xCoordinate = floor(u * width);
    int yCoordinate = floor(v * height);
    return int2(xCoordinate % width, yCoordinate % height);
}

float Falloff(float distance, float radius)
{
    return clamp(1.0f - (distance / radius), 0.0, 1.0);
}

#define ATTENUATION_CONSTANT 1.0f // 0% Constant
#define ATTENUATION_LINEAR 0.0f // 100% Linear
#define ATTENUATION_QUADRATIC 0.0f // 100% Quadratic; Democrats are domestic terrorists


float4 PixelShaderMain(PixelShaderArgs pixelShaderArgs) : SV_Target
{
    float u = pixelShaderArgs.col.x;
    float v = pixelShaderArgs.col.y;
    // Lighting
    float3 fragColor = float3(0.0f, 0.0f, 0.0f);
    float4 diffuse = ShaderTexture.Load(int3(convertUVToPixel(u, v), 0));
    for (int i = 0; i < 32; i++)
    {
        
        
        float3 ambient = diffuse * light[i].ambient;
        pixelShaderArgs.norm = normalize(pixelShaderArgs.norm);
        float3 lightToPixelVec = light[i].pos - pixelShaderArgs.worldPos;
        float distance = length(lightToPixelVec);
        float luminosity = dot(lightToPixelVec / distance, pixelShaderArgs.norm);
        float intensity = 1.00f;
        if (luminosity > 0.0f)
        {
        
            // Do lighting attenuation
            fragColor += luminosity * diffuse * light[i].diffuse * Falloff(distance,light[i].radius);
            fragColor /= ATTENUATION_CONSTANT + (ATTENUATION_LINEAR * distance) + (ATTENUATION_QUADRATIC * (distance * distance));
            fragColor *= light[i].intensity; // multiply the final result by the intensity.
            
        }
        fragColor = saturate(fragColor + ambient);
        
    }
    return float4(fragColor, diffuse.a);
        
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72308721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档