You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

THREE.js OcclusionComposer报错:Cannot read properties of undefined (reading 'x')

体积光照复现中的OcclusionComposer问题与GLSL着色器调试
  • 尝试复现体积光照示例时,遇到OcclusionComposer相关问题,作为GLSL新手调试难度大
  • 代码仓库主逻辑位于components/HomeCanvas/Scene.ts
  • 推测问题出在VolumetricLightCylinder.js的着色器代码中,将worldPosition.xyz修改为worldPosition后错误消失

相关着色器代码如下:

import * as THREE from 'three'

export default () => ({
  lights: true,
  transparent: true,
  depthWrite: false,
  uniforms: THREE.UniformsUtils.merge([
    THREE.UniformsLib['lights'],
    {
      attenuation: { value: 25.0 },
      anglePower: { value: 10.0 },
      spotPosition: { value: new THREE.Vector3(0, 0, 0) },
    },
  ]),
  vertexShader: /* glsl */ `
    #include <common>

    struct PointLight {
      vec3 position;
      vec3 color;
      float distance;
      float decay;
      int shadow;
      float shadowBias;
      float shadowRadius;
      vec2 shadowMapSize;
      float shadowCameraNear;
      float shadowCameraFar;
    };

    uniform PointLight pointLights[NUM_POINT_LIGHTS];
    uniform float viewMix;

    varying vec4 vColor;
    varying vec3 vNormal;
    varying vec3 vWorldPosition;

    float _punctualLightIntensityToIrradianceFactor( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {
        if( decayExponent > 0.0 ) {
            return pow( saturate( -lightDistance / cutoffDistance + 1.0 ), decayExponent );
        }
        return 1.0;
    }

    void main() {
      vNormal = normalize(normalMatrix * normal);

      vec4 worldPosition = modelMatrix * vec4(position, 1.0);
      vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
      gl_Position = projectionMatrix * modelViewPosition;

      vec4 addedLights = vec4(0.1, 0.1, 0.1, 1.0);
      for(int l = 0; l < NUM_POINT_LIGHTS; l++) {
        float dist = distance(pointLights[l].position, worldPosition.xyz);
        addedLights.rgb += pointLights[l].color *
          _punctualLightIntensityToIrradianceFactor(
            dist,
            pointLights[l].distance,
            pointLights[l].decay
          );
      }

      vWorldPosition = worldPosition.xyz;
      vColor = addedLights;
    }
  `,
  fragmentShader: /* glsl */`
    varying vec3 vNormal;
    varying vec3 vWorldPosition;
    uniform vec3 spotPosition;
    uniform float attenuation;
    uniform float anglePower;
    varying vec4 vColor;

    void main() {
      float intensity;
      intensity = distance(vWorldPosition, spotPosition)/attenuation;
      intensity = 1.0 - clamp(intensity, 0.0, 1.0);
      vec3 normal   = vec3(vNormal.x, vNormal.y, abs(vNormal.z));
      float angleIntensity  = pow(dot(normal, vec3(0.0, 0.0, 1.0)), anglePower);
      intensity = intensity * angleIntensity;
      gl_FragColor = vec4(vColor.rgb, intensity);
    }
  `,
})

内容的提问来源于stack exchange,提问作者Roland Teslaru

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 23:20:39