Three.js ShaderMaterial 照明不起作用

标签 three.js lighting 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 - 使用 UniformsUtils 和 UniformsLib 设置着色器 Material
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

不变

最佳答案

浅色制服已更改为 struct s 在 r74 (特别是在 #7324 中)。请注意,虽然更改为 struct s 发生在 r74 中,以下适用于 r75 及更高版本。
struct 的单个数组s 是针对每种灯光类型给出的。每个structpositioncolor你需要的属性。

片段着色器

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);
}

请注意,灯光位置现在是相对于相机的,因此您可以用相机位置偏移灯光位置。

Working Fiddle

关于Three.js ShaderMaterial 照明不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37342114/

相关文章:

c++ - 如何在现代 opengl 中处理正交投影中的照明?

c - 同时使用纹理和照明

three.js - Threejs DataTexture 不更新

javascript - 如何使用 iTowns2 在浏览器中渲染点云数据

three.js - 片段着色器三js中的抗锯齿

javascript - 如何使用 three.js 'wrap' 球体上的平面?

javascript - 三.JS Mesh位置平滑动画

opengl - Phong 着色/插值和 Phong 照明模型之间有什么区别?