[英]Forge viewer: 3D markups with text
我们正在尝试在3D模型中每个对象顶部的特定位置(右上方)显示标记。 我们还希望在3D标记上渲染文本。 这可能吗? 如果是这样,我们将在其之上放置一个后处理着色器,以便在浏览时不会隐藏在模型中的其他对象之下。
选项2:在2D中,无论是在Forge中还是在HTML中,这都是在顶部带有文本的图像,在每一帧期间,这些图像+文本的位置必须进行更新以匹配3D对象的2D位置,这可能有效但这可能会滞后,这就是为什么我们更愿意使用3D选项的原因-如果可能的话。
看看我最新的PointCloud Markup演示 ,以了解使用动态纹理的自定义着色器的示例: Forge Viewer中使用PointCloud的高性能3D标记 。
您可以使用类似的方法来生成包含标签的纹理。
createShader (options) {
// Vertex Shader code
const vertexShader = options.vertexShader || `
attribute float pointSize;
attribute vec4 color;
varying vec4 vColor;
void main() {
vec4 vPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = projectionMatrix * vPosition;
gl_PointSize = pointSize;
vColor = color;
}
`
// Fragment Shader code
const fragmentShader = options.fragmentShader || `
uniform sampler2D texture;
varying vec4 vColor;
void main() {
vec4 tex = texture2D(texture, gl_PointCoord);
if (tex.a < 0.2) discard;
if (vColor.a == 0.0) {
gl_FragColor = vec4(tex.r, tex.g, tex.b, tex.a);
} else {
gl_FragColor = vColor;
}
}
`
const tex = options.texture || defaultTex
// Shader material parameters
const shaderParams = options.shaderParams || {
side: THREE.DoubleSide,
depthWrite: false,
depthTest: false,
fragmentShader,
vertexShader,
opacity: 0.5,
attributes: {
pointSize: {
type: 'f',
value: []
},
color: {
type: 'v4',
value: []
}
},
uniforms: {
texture: {
value: THREE.ImageUtils.loadTexture(tex),
type: 't'
}
}
}
// creates shader material
const material =
new THREE.ShaderMaterial(
shaderParams)
const generateTexture = (size, radius) => {
const pixels = []
for (let u = 0; u < size; ++u) {
for (let v = 0; v < size ; ++v) {
const dist = Math.sqrt(
(u/size - 0.5) * (u/size - 0.5) +
(v/size - 0.5) * (v/size - 0.5))
if (dist < 0.1) {
pixels.push(0xff, 0x00, 0x00, 0xff)
} else if (dist < (radius - 0.05)) {
pixels.push(0xff, 0x00, 0x00, 0x00)
} else if (dist < radius) {
pixels.push(0xff, 0x00, 0x00, 0xff)
} else {
pixels.push(0x00, 0x00, 0x00, 0x00)
}
}
}
const dataTexture = new THREE.DataTexture (
Uint8Array.from (pixels),
size, size,
THREE.RGBAFormat,
THREE.UnsignedByteType,
THREE.UVMapping
)
dataTexture.minFilter = THREE.LinearMipMapLinearFilter
dataTexture.magFilter = THREE.LinearFilter // THREE.NearestFilter
dataTexture.needsUpdate = true
return dataTexture
}
const stopwatch = new Stopwatch()
let radius = 0.0
return {
setTexture: (tex) => {
const {texture} = shaderParams.uniforms
texture.value = THREE.ImageUtils.loadTexture(tex)
texture.needsUpdate = true
},
update: () => {
const dt = stopwatch.getElapsedMs() * 0.001
radius += dt * 0.25
radius = radius > 0.5 ? 0.0 : radius
const {texture} = shaderParams.uniforms
texture.value = generateTexture(96, radius)
texture.needsUpdate = true
},
material
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.