Revision control
Copy as Markdown
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
/* Simplified lighting for particles
*
* Treat particles as points -> do not take normal into account
* -> directional lights become ambient
* -> point lights only account for attenuation
* -> spotlights only account for attenuation and spot angles
*/
vec4 qt_attenuate4(in vec4 dist, in vec4 catt, in vec4 latt, in vec4 qatt)
{
vec4 factors = catt + dist * latt + dist * dist * qatt;
return vec4(1.0) / factors;
}
vec3 qt_calcPointLights(in vec3 position)
{
vec4 lengths = vec4(length(position - lightData.qt_pointLightPosition[0].xyz),
length(position - lightData.qt_pointLightPosition[1].xyz),
length(position - lightData.qt_pointLightPosition[2].xyz),
length(position - lightData.qt_pointLightPosition[3].xyz));
vec4 attenuations = qt_attenuate4(lengths, lightData.qt_pointLightConstantAtt, lightData.qt_pointLightLinearAtt, lightData.qt_pointLightQuadAtt);
return lightData.qt_pointLightColor[0].rgb * attenuations.x + lightData.qt_pointLightColor[1].rgb * attenuations.y + lightData.qt_pointLightColor[2].rgb * attenuations.z + lightData.qt_pointLightColor[3].rgb * attenuations.w;
}
vec3 qt_calcSpotLights(in vec3 position)
{
vec3 lightVector0 = position - lightData.qt_spotLightPosition[0].xyz;
vec3 lightVector1 = position - lightData.qt_spotLightPosition[1].xyz;
vec3 lightVector2 = position - lightData.qt_spotLightPosition[2].xyz;
vec3 lightVector3 = position - lightData.qt_spotLightPosition[3].xyz;
vec4 lengths = vec4(length(lightVector0), length(lightVector1), length(lightVector2), length(lightVector3));
vec4 attenuations = qt_attenuate4(lengths, lightData.qt_spotLightConstantAtt, lightData.qt_spotLightLinearAtt, lightData.qt_spotLightQuadAtt);
vec4 spots = vec4(acos(dot(normalize(lightVector0), normalize(lightData.qt_spotLightDirection[0].xyz))),
acos(dot(normalize(lightVector1), normalize(lightData.qt_spotLightDirection[1].xyz))),
acos(dot(normalize(lightVector2), normalize(lightData.qt_spotLightDirection[2].xyz))),
acos(dot(normalize(lightVector3), normalize(lightData.qt_spotLightDirection[3].xyz))));
vec4 cones = vec4(1.0 - smoothstep(lightData.qt_spotLightInnerConeAngle, lightData.qt_spotLightConeAngle, spots));
attenuations *= cones;
return lightData.qt_spotLightColor[0].rgb * attenuations.x + lightData.qt_spotLightColor[1].rgb * attenuations.y + lightData.qt_spotLightColor[2].rgb * attenuations.z + lightData.qt_spotLightColor[3].rgb * attenuations.w;
}
vec3 qt_calcLightColor(in vec3 position)
{
vec3 color = vec3(0.0);
if (qt_pointLights)
color += qt_calcPointLights(position);
if (qt_spotLights)
color += qt_calcSpotLights(position);
return color + qt_light_ambient_total;
}