Угловое затухание прожектора вызывает острые края при угле › 90

Если угол конуса превышает 90 градусов, угловое затухание моего прожектора работает неправильно. От 0,1 до 90 затухание плавное от центра конуса к краям, но от 90 до 179,9 края становятся все резче и резче.

Вот мой код затухания:

uniform vec3 lightPosition; // Light's position
uniform vec3 lightDirection; // Light's direction
uniform float lightAngleCos: // Cosine of the half of the cone angle
uniform float lightRange: // Light's range

// Get the light vector
vec3 pixelToLight = lightPosition - position.xyz;
vec3 normPTL = normalize(pixelToLight);    

// Get the dot product between the light direction and the light vector
float rho = dot(normPTL, -lightDirection);

if(rho > lightAngleCos)
{
    float dif = 1.0 - lightAngleCos;
    float angularAttenuation = clamp((rho - lightAngleCos) / dif, 0.0, 1.0);
    float radialAttenuation = 1.0 - clamp(length(pixelToLight) / (lightRange), 0.0, 1.0);
    float attenuation = angularAttenuation * radialAttenuation;

    // Apply attenuation
    out_color = color * attenuation;
}

person manabreak    schedule 05.07.2013    source источник
comment
В каком направлении указывает ваш lightDirection, от света или к свету (по вашим расчетам кажется, что к свету, но это было бы странно, так что просто для уверенности)?   -  person Christian Rau    schedule 05.07.2013
comment
Это фактическое направление света, но я, кажется, неправильно написал pixelToLight. Собираюсь это исправить.   -  person manabreak    schedule 05.07.2013
comment
но, кажется, я неправильно написал pixelToLight - неправильно в вашем вопросе или неправильно в вашем фактическом коде. В последнем случае это вполне может быть ответом на ваш вопрос.   -  person Christian Rau    schedule 05.07.2013
comment
В вопросе было неправильно, я не копировал и не вставлял исходный код, а вместо этого написал его, поэтому я включил туда ошибку. :)   -  person manabreak    schedule 05.07.2013


Ответы (2)


Рассчитайте его в фактических углах, а не в cos, поскольку cos не является линейным, поэтому у вас был очень плавный градиент затухания около 0 и очень резкий около 180, вы можете увидеть это, просто взглянув на график cos около 0 и около Pi/2.

В коде вы должны вычислить:

rhoAngle = acos(rho);
lightAngleCos = acos(lightAngleCos);

а затем используйте его для расчета затухания:

float dif = Pi/2.0 - lightAngle;
float angularAttenuation = clamp((lightAngle - rhoAngle) / dif, 0.0, 1.0);
person Vasaka    schedule 05.07.2013
comment
Не могли бы вы уточнить, привести пример? - person manabreak; 05.07.2013
comment
ваш пример не работает, он вообще не дает освещения. AngularAttenuation равен нулю во всех случаях. - person manabreak; 06.07.2013
comment
@manabreak как ты это проверил? Я написал arccos вместо acos, поэтому он даже не должен компилироваться, исправлен ответ на правильное наименование arccosinus, также должно быть определено значение Pi const. - person Vasaka; 06.07.2013
comment
Я сделал все необходимые изменения, но это не сработало. Я предполагаю, что это потому, что вы вычитаете lightAngle из rhoAngle, а должно быть наоборот. В любом случае, мое первоначальное решение было правильным, во-первых, острый край был фактически вызван моей конусной сеткой. - person manabreak; 07.07.2013
comment
@manabreak Я просто переписал то, что было написано в вашем коде. В любом случае утверждение остается верным с грехом угла, вы получаете более острые края, чем с углом, фиксированный ответ, чтобы сделать его правильным. - person Vasaka; 07.07.2013

Мое первоначальное решение было правильным в целом. Это была моя конусная сетка, которая вызвала ограничения.

person manabreak    schedule 06.07.2013