三.js/GLSL:WebGL 着色器根据世界 space 位置为片段着色
THREE.js/GLSL: WebGL shader to color fragments based on world space position
我已经看到根据片段在屏幕中的位置 space 或它们在本地对象 space 中的位置对颜色片段进行着色的解决方案,例如 Three.js/GLSL - Convert Pixel Coordinate to World Coordinate。
那些使用屏幕坐标工作,并且在相机移动或旋转时会发生变化;或仅适用于本地对象 space.
我想完成的是根据 space 世界中的 position
片段着色(如 three.js 场景图的 space 世界)。
即使相机移动,颜色也应保持不变。
希望的行为示例:位于世界 space 处 (x:0,y:0,z:2) 的 1x1x1 立方体的第三个分量(蓝色 == 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 移动,您会发现颜色不会留在原地。不过,我希望他们这样做。
你的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()
可能会为不同的位置提供相同的颜色,这可能不是您要查找的颜色。
我已经看到根据片段在屏幕中的位置 space 或它们在本地对象 space 中的位置对颜色片段进行着色的解决方案,例如 Three.js/GLSL - Convert Pixel Coordinate to World Coordinate。
那些使用屏幕坐标工作,并且在相机移动或旋转时会发生变化;或仅适用于本地对象 space.
我想完成的是根据 space 世界中的 position
片段着色(如 three.js 场景图的 space 世界)。
即使相机移动,颜色也应保持不变。
希望的行为示例:位于世界 space 处 (x:0,y:0,z:2) 的 1x1x1 立方体的第三个分量(蓝色 == 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 移动,您会发现颜色不会留在原地。不过,我希望他们这样做。
你的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()
可能会为不同的位置提供相同的颜色,这可能不是您要查找的颜色。