【问题标题】:THREE.js/GLSL: WebGL shader to color fragments based on world space positionTHREE.js/GLSL:WebGL 着色器根据世界空间位置为片段着色
【发布时间】:2018-02-04 23:24:36
【问题描述】:

我已经看到了根据片段在屏幕空间或本地对象空间中的位置(如Three.js/GLSL - Convert Pixel Coordinate to World Coordinate)来为片段着色的解决方案。

那些正在使用屏幕坐标并在相机移动或旋转时发生变化;或仅适用于本地对象空间。

我喜欢完成的是基于它们在世界空间中的position 为片段着色(如在three.js 场景图的世界空间中)。

即使相机移动,颜色也应该保持不变。

期望行为示例:位于世界空间 (x:0,y:0,z:2) 的 1x1x1 立方体的第三个分量 (blue == z) 始终介于 1.5 - 2.5 之间。即使相机移动也是如此。

到目前为止我得到了什么:

顶点着色器

varying vec4 worldPosition;

void main() {


  // The following changes on camera movement:
  worldPosition = projectionMatrix * modelViewMatrix * vec4(position, 1.0);

  // This is closer to what I want (colors dont change when camera moves)
  // but it is in local not world space:
  worldPosition = vec4(position, 1.0);

  // This works fine as long as the camera doesnt move:
  worldPosition = modelViewMatrix * vec4(position, 1.0);
  // Instead I'd like the above behaviour but without color changes on camera movement


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

}

片段着色器

uniform vec2 u_resolution;
varying vec4 worldPosition;

void main(void)
{
    // I'd like to use worldPosition something like this:
    gl_FragColor = vec4(worldPosition.xyz * someScaling, 1.0);
    // Here this would mean that fragments xyz > 1.0 in world position would be white and black for <= 0.0; that would be fine because I can still divide it to compensate

}

这是我得到的: https://glitch.com/edit/#!/worldpositiontest?path=index.html:163:15

如果您使用 wasd 移动,您会看到颜色不会保持原位。不过,我希望他们这样做。

【问题讨论】:

  • 您需要介于 0 和 1 之间的颜色值,因此您需要一些方法来转换您的世界坐标。你以fract(worldCoord.xyz * scale)为例
  • @gman 我知道,我编辑了代码部分以指示缩放。但这并不能回答问题,我担心,因为我首先需要得到正确的worldPosition(基于世界空间中对象位置的位置,不会随着相机移动而改变)。跨度>
  • 你试过modelMatrixworldPosition = modelMatrix * vec4(position, 1);一样吗?如果three.js 还没有为您制作,您可以制作自己的制服并传入
  • @gman 我已经尝试过了(我想是三个.js 的modelViewMatrix == modelMatrix),只要相机保持固定,这就是我想要的行为。但是一旦相机移动,颜色就会相应改变,这不是我想要的效果。即使相机移动,位于固定位置的立方体也应保持其颜色。
  • @gman 我已经纠正了,你是对的,@neeh 在下面的答案中也是如此。我混淆了modelMatrixmodelViewMatrix,当然使用你的建议。仍在努力理解不同矩阵之间的关系。

标签: three.js glsl webgl glsles


【解决方案1】:

您的worldPosition 错误。您不应该将相机牵涉到计算中。这意味着,没有projectionMatrix 也没有viewMatrix

// The world poisition of your vertex: NO CAMERA
vec4 worldPosition = modelMatrix * vec4(position, 1.0);

// Position in normalized screen coords: ADD CAMERA
gl_Position = projectionMatrix * viewMatrix * worldPosition;

// Here you can compute the color based on worldPosition, for example:
vColor = normalize(abs(worldPosition.xyz));

检查this fiddle


注意

请注意,此处用于颜色的abs() 可能会为不同的位置提供相同的颜色,这可能不是您想要的。

【讨论】:

  • 谢谢!显然,有点尴尬的是,我混淆了modelMatrixmodelViewMatrix。我还在学习 OpenGL 的概念,但我还是错过了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-16
相关资源
最近更新 更多