Three.js ShaderMaterial освещение не работает
Я экспериментирую с Three.js ShaderMaterial и пытаюсь реализовать освещение. У меня есть рабочий код для r70, но тот же код (с небольшими изменениями - константа MAX_POINT_LIGHTS была переименована в NUM_POINT_LIGHTS) не работает для r76.
Глядя на трассировку в WebGL Inspector, становится ясно, что в шейдер не отправляются легкие данные. Итак, освещение сломалось или мне нужно настроить что-то еще, чтобы оно заработало?
Использование r70 (работает)
http://codepen.io/anon/pen/KzjXNr?editors=1010
Фрагмент шейдера
uniform vec3 diffuse;
varying vec3 vPos;
varying vec3 vNormal;
uniform vec3 pointLightColor[MAX_POINT_LIGHTS];
uniform vec3 pointLightPosition[MAX_POINT_LIGHTS];
uniform float pointLightDistance[MAX_POINT_LIGHTS];
void main() {
vec4 addedLights = vec4(0.1, 0.1, 0.1, 1.0);
for(int l = 0; l < MAX_POINT_LIGHTS; l++) {
vec3 lightDirection = normalize(vPos - pointLightPosition[l]);
addedLights.rgb += clamp(dot(-lightDirection, vNormal), 0.0, 1.0) * pointLightColor[l];
}
gl_FragColor = addedLights;
}
JavaScript - настройка Shadermaterial с помощью UniformsUtils и UniformsLib
var uniforms = THREE.UniformsUtils.merge([
THREE.UniformsLib['lights'],
{ diffuse: { type: 'c', value: new THREE.Color(0xff00ff) } }
]);
var vertexShader = document.getElementById('vertexShader').text;
var fragmentShader = document.getElementById('fragmentShader').text;
material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
lights: true
});
var geometry = new THREE.BoxGeometry(200, 200, 200);
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
Использование r76 (futzed)
http://codepen.io/anon/pen/ZWdXLZ?editors=1010
Фрагмент шейдера
uniform vec3 diffuse;
varying vec3 vPos;
varying vec3 vNormal;
uniform vec3 pointLightColor[NUM_POINT_LIGHTS];
uniform vec3 pointLightPosition[NUM_POINT_LIGHTS];
uniform float pointLightDistance[NUM_POINT_LIGHTS];
void main() {
vec4 addedLights = vec4(0.1, 0.1, 0.1, 1.0);
for(int l = 0; l < NUM_POINT_LIGHTS; l++) {
vec3 lightDirection = normalize(vPos - pointLightPosition[l]);
addedLights.rgb += clamp(dot(-lightDirection, vNormal), 0.0, 1.0) * pointLightColor[l];
}
gl_FragColor = addedLights;
}
JavaScript
без изменений
1 ответ
Легкая форма была изменена на struct
s в r74 (в частности, в # 7324). Обратите внимание, что хотя изменение struct
s произошло в r74, следующие работы r75 и позже.
Единый массив struct
s дается для каждого типа освещения. каждый struct
имеет position
а также color
свойства, которые вам нужны.
Фрагмент шейдера
uniform vec3 diffuse;
varying vec3 vPos;
varying vec3 vNormal;
struct PointLight {
vec3 position;
vec3 color;
};
uniform PointLight pointLights[ NUM_POINT_LIGHTS ];
void main() {
vec4 addedLights = vec4(0.1, 0.1, 0.1, 1.0);
for(int l = 0; l < NUM_POINT_LIGHTS; l++) {
vec3 adjustedLight = pointLights[l].position + cameraPosition;
vec3 lightDirection = normalize(vPos - adjustedLight);
addedLights.rgb += clamp(dot(-lightDirection, vNormal), 0.0, 1.0) * pointLights[l].color;
}
gl_FragColor = addedLights;//mix(vec4(diffuse.x, diffuse.y, diffuse.z, 1.0), addedLights, addedLights);
}
Обратите внимание, что положение освещения теперь относительно камеры, поэтому вы смещаете положение освещения относительно положения камеры.