OpenGL шейдер направленного света зеркальное отражение увеличивается с расстоянием

название говорит само за себя … используя встроенную систему освещения opengls, specularlight не увеличивается и не уменьшается с расстоянием от объекта, а благодаря реализации шейдера.

Вершинный шейдер:

#version 330

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in vec3 normal;

out vec2 texCoord0;
out vec3 normal0;
out vec3 worldPos0;

uniform mat4 transform;
uniform mat4 normalRotation;
uniform mat4 transformProjected;

void main()
{
gl_Position = transformProjected * vec4(position, 1.0);
texCoord0 = texCoord;

normal0 = normalize((normalRotation * vec4(normal, 0.0))).xyz;
worldPos0 = (transform * vec4(position, 1.0)).xyz;
}

Фрагмент шейдера:

#version 330

in vec2 texCoord0;
in vec3 normal0;
in vec3 worldPos0;

out vec4 fragColor;

struct BaseLight
{
vec3 colorDiffuse;
vec3 colorSpecular;
float intensityDiffuse;
};
struct DirectionalLight
{
BaseLight base;
vec3 direction;
};

uniform vec3 tint;
uniform sampler2D sampler;

uniform vec3 eyePos; // camera pos

uniform vec3 ambientLight;
uniform vec3 emissiveLight;

//material
uniform float specularIntensity;
uniform float specularPower;

uniform DirectionalLight directionalLight;

vec4 calcLight(BaseLight base,vec3 direction, vec3 normal)
{
float diffuseFactor = dot(normal, -direction);

vec4 diffuseColorFinal = vec4(0,0,0,0);
vec4 specularColorFinal = vec4(0,0,0,0);

if(diffuseFactor > 0)
{
diffuseColorFinal =  vec4(base.colorDiffuse,1) * diffuseFactor * base.intensityDiffuse;

vec3 directionToEye = normalize(eyePos - worldPos0);
vec3 reflectDirection = normalize(reflect(direction, normal));

float specularFactor = dot(directionToEye, reflectDirection);
specularFactor = pow(specularFactor, specularPower);

if(specularFactor > 0)
specularColorFinal = vec4(base.colorSpecular,1) * specularFactor   * specularIntensity;
}
//
return diffuseColorFinal + specularColorFinal;
}void main()
{
vec4 colorD = texture(sampler, texCoord0.xy) * vec4(tint,1);
vec3 normal = normal0;
vec4 totalLight = vec4(ambientLight,1) + vec4(emissiveLight,1);

totalLight += calcLight(directionalLight.base,-directionalLight.direction,normal);fragColor = colorD * totalLight;
}

введите описание изображения здесь
введите описание изображения здесь

Как вы можете видеть из двух изображений, зеркальный свет занимает большую площадь поверхности, чем дальше камера от плоскости. В моем тесте с opengls, встроенным в освещение, этого не происходит. Есть ли способ исправить это? Я новичок в освещении, может быть, это нормально для направленных источников света? Спасибо за помощь!

Я также устанавливаю форму eyePos на свои камеры. я не знаю, поможет ли это.

0

Решение

В основном вам нужно иметь расстояние между фрагментом и светом dist , Это может быть проблемой для направленного света, потому что у вас есть только направление, а расстояние считается бесконечным. Может быть, переключиться на точечный свет?

когда у вас есть ‘dist’, вы используете формулу

att = 1.0 / (Kc + Kl*dist + Kq*dist^2)
Kc - constant attenuation
Kl - linear attenuation
Kq - quadratic attenuation

более простая версия (используется только Kq, остальные установлены на 1,0):

float attenuation = 1.0 / (1.0 + light.attenuation * pow(distanceToLight, 2));

тогда в уравнении освещения вы в основном умножаете рассчитанный цвет на это att фактор:

vec4 finalColor = ambient + (diffuseColorFinal + specularColorFinal)*att

http://www.ozone3d.net/tutorials/glsl_lighting_phong_p4.php#part_4

http://tomdalling.com/blog/modern-opengl/07-more-lighting-ambient-specular-attenuation-gamma/

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]