如何在Autodesk Viewer中使用单张PNG图标作为纹理(基于指定示例项目修改)
如何在Autodesk Viewer中使用单张PNG图标作为纹理(基于指定示例项目修改)
嘿,我来帮你搞定这个问题!原来的示例用了一张包含4个标记图标的雪碧图,通过着色器把它分成4份来切换不同图标。现在你想只用单个图标的话,只需要调整着色器里的纹理采样逻辑,再对应修改相关代码就行,具体步骤如下:
1. 修改片段着色器(Fragment Shader)
原来的片段着色器里,这行代码是用来从4图标的雪碧图中选取对应部分的:
gl_FragColor = gl_FragColor * texture2D(tex, vec2((gl_PointCoord.x+vColor.y*1.0)/4.0, 1.0-gl_PointCoord.y));
这里的vColor.y是用来传递图标索引(0-3),/4.0是把X轴纹理坐标分成4份。现在我们只用单个图标,直接去掉偏移和分份逻辑,改成这样:
gl_FragColor = gl_FragColor * texture2D(tex, vec2(gl_PointCoord.x, 1.0-gl_PointCoord.y));
如果你的单图标PNG尺寸和原来雪碧图里单个图标一致,这样就能直接完整采样整张图了。
2. (可选)简化顶点着色器(Vertex Shader)
原来的顶点着色器传递了vColor的y分量用来选择图标,现在不需要这个功能了,可以把顶点着色器里的vColor = color;保留,但后续使用时不需要再给顶点颜色的y分量赋值;或者如果你想彻底简化,也可以把varying vec3 vColor;改成varying float vColor;,只传递灰度值,不过其实保留原来的写法也不会有问题,只是不用用到y分量而已。
修改后的简化版顶点着色器:
uniform float size; varying float vColor; void main() { vColor = color.x; vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); gl_PointSize = size * ( size / (length(mvPosition.xyz) + 1.0) ); gl_Position = projectionMatrix * mvPosition; }
对应的片段着色器也要同步调整:
uniform sampler2D tex; varying float vColor; void main() { gl_FragColor = vec4( vColor, vColor, vColor, 1.0 ); gl_FragColor = gl_FragColor * texture2D(tex, vec2(gl_PointCoord.x, 1.0-gl_PointCoord.y)); if (gl_FragColor.w < 0.5) discard; }
这个简化步骤不是必须的,但能让代码更干净。
3. 确保纹理加载正确
把纹理加载的路径改成你单个图标的PNG路径,比如:
var texture = THREE.ImageUtils.loadTexture("img/single-icon.png");
注意要确保这个路径在你的项目中能正确访问到。
修改后的完整代码示例
这里给你整合好的完整代码,你可以直接替换原来的部分:
// 修改后的顶点着色器(简化版) this.vertexShader = ` uniform float size; varying float vColor; void main() { vColor = color.x; vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); gl_PointSize = size * ( size / (length(mvPosition.xyz) + 1.0) ); gl_Position = projectionMatrix * mvPosition; } ` // 修改后的片段着色器 this.fragmentShader = ` uniform sampler2D tex; varying float vColor; void main() { gl_FragColor = vec4( vColor, vColor, vColor, 1.0 ); gl_FragColor = gl_FragColor * texture2D(tex, vec2(gl_PointCoord.x, 1.0-gl_PointCoord.y)); if (gl_FragColor.w < 0.5) discard; } ` // 创建点云材质 var texture = THREE.ImageUtils.loadTexture("img/single-icon.png"); // 替换成你的单图标路径 var material = new THREE.ShaderMaterial({ vertexColors: THREE.VertexColors, fragmentShader: this.fragmentShader, vertexShader: this.vertexShader, depthWrite: true, depthTest: true, uniforms: { size: { type: "f", value: this.size }, tex: { type: "t", value: texture } } });
这样修改后,你的点云就会使用单张PNG图标作为纹理了!
备注:内容来源于stack exchange,提问作者Yusuke
相关产品推荐
相关产品推荐

