如何让3D空间中的图层连接两点同时最大程度朝向相机?
Let’s tackle this problem step by step—you want a 3D layer to have its X-axis point directly from one 3D point to another, while also rotating to face the camera as much as possible without breaking that X-axis constraint. Your existing After Effects expression gets close, but it has edge cases where the layer disappears (usually when the camera angle triggers gimbal lock or incorrect axis calculations).
What Was Wrong With the Original Expression?
Your code calculates Y and Z rotation based on a partial vector, but it doesn’t factor in the camera’s position relative to the layer. This is why you see the layer vanish at extreme angles—it’s hitting a gimbal lock scenario where the rotation math breaks down. Additionally, hardcoding the X orientation to 0 ignores how the camera’s perspective should influence the layer’s overall orientation to stay visible.
Robust Solution: Axis-Based Orientation
Instead of calculating rotations directly, we’ll build a full rotation matrix using three orthogonal axes: one locked to your two points, one aligned to the camera as much as possible, and a third derived to maintain 3D space consistency. Here’s the improved expression:
// Get start and end points in world space startLayer = thisComp.layer("A"); start = startLayer.toWorld(startLayer.anchorPoint); endLayer = thisComp.layer("B"); end = endLayer.toWorld(endLayer.anchorPoint); // Calculate normalized X-axis (points directly from start to end) xAxis = normalize(end - start); // Get active camera's world position cam = thisComp.activeCamera; camPos = cam.toWorld(cam.anchorPoint); // Vector from layer's anchor point to camera (normalized) toCam = normalize(camPos - thisLayer.toWorld(thisLayer.anchorPoint)); // Calculate Y-axis: perpendicular to X-axis, aligned to camera direction as much as possible yAxis = normalize(toCam - dot(toCam, xAxis) * xAxis); // Z-axis is cross product of X and Y (maintains right-hand coordinate system) zAxis = cross(xAxis, yAxis); // Convert axis matrix to orientation values lookAtMat = [xAxis[0], yAxis[0], zAxis[0], 0, xAxis[1], yAxis[1], zAxis[1], 0, xAxis[2], yAxis[2], zAxis[2], 0, 0, 0, 0, 1]; fromCompMatrix(lookAtMat)[0];
Key Breakdown of the Solution
- X-axis Lock: The
xAxisvector is strictly normalized to point from your start layer to end layer—this ensures the layer’s X-axis never deviates from that line, which is your core requirement. - Camera-Facing Y-axis: We calculate
yAxisby projecting the camera direction onto the plane perpendicular to the X-axis. This keeps the layer facing the camera without breaking the X-axis constraint. - Gimbal Lock Prevention: By constructing a full rotation matrix from the three orthogonal axes and converting it to orientation with
fromCompMatrix, we avoid the rotation math errors that made your layer disappear.
Fixed Results
- Properly aligned layer (X-axis between points, facing camera):

- Edge case fixed (layer remains visible even at extreme camera angles):

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

