三维模型上的webGL等高线颜色图

三维模型上的webGL等高线颜色图,webgl,Webgl,我正在开发一个软件,该软件将三维模型表面上的工程数据可视化为彩色地图。为此,我使用WebGL。当时我能够在3D模型的表面上显示颜色。 但现在我需要改进可视化,以便在颜色之间进行锐利的转换(在三角形表面上没有颜色插值)。 我不知道如何有效地做这件事 平滑等高线图 尖锐等高线图 一种方法是将平面添加到颜色属性中,如本教程所述。这将防止对颜色值进行插值,因此每个三角形将只使用一种颜色(在三个顶点中的第一个顶点中指定的颜色)。 遗憾的是,我找不到任何关于其webgl支持的信息,但您不妨尝试一下,看看它

我正在开发一个软件,该软件将三维模型表面上的工程数据可视化为彩色地图。为此,我使用WebGL。当时我能够在3D模型的表面上显示颜色。 但现在我需要改进可视化,以便在颜色之间进行锐利的转换(在三角形表面上没有颜色插值)。 我不知道如何有效地做这件事

平滑等高线图

尖锐等高线图


一种方法是将
平面添加到颜色属性中,如本教程所述。这将防止对颜色值进行插值,因此每个三角形将只使用一种颜色(在三个顶点中的第一个顶点中指定的颜色)。
遗憾的是,我找不到任何关于其webgl支持的信息,但您不妨尝试一下,看看它是否有效


如果它不起作用,或者您不希望单个三角形可见,您还可以在片段着色器中检索每个像素的颜色。根据纹理大小,仍然会有一些插值(类似于图像在放大时变得模糊)。

不清楚您要做什么。您没有提供足够的信息来了解您的颜色是如何选择/计算的

我只能猜测几个可能符合您描述的解决方案

  • 采用后处理技术的后处理

    你可以做一个简单的

    gl_FragColor.rgb = floor(gl_FragColor.rgb * numLevels) / numLevels;
    
    或者你可以在一些颜色空间里做,比如

    // convert to HSV
    vec3 hsv = rgb2hsv(gl_FragColor.rgb);
    
    // quantize hue only
    hsv.x = floor(hsv.x * numLevels) / numLevels;
    
    // concert back to RGB
    gl_FragColor.rgb = hsv2rgb(hsv);
    
    也可以在3D着色器中执行此操作,而不必进行后期处理

    您可以找到rgb2hsv和hsv2rgb,但当然可以使用其他颜色空间

  • 例如:

    const gl=document.querySelector('canvas').getContext('webgl');
    常数m4=twgl.m4;
    常数v3=twgl.v3;
    //用于生成颜色
    const ctx=document.createElement('canvas').getContext('2d');
    ctx.canvas.width=1;
    ctx.canvas.height=1;
    常数vs=`
    属性向量4位置;
    属性向量3正常;
    //注意:没有理由必须来自属性(每个顶点)
    //它可以很容易地来自片段着色器中使用的纹理
    //以获得更高的分辨率
    属性向量4颜色;
    均匀mat4投影;
    统一mat4模型视图;
    可变vec3 v_正常;
    可变的vec4 v_颜色;
    空干管(){
    gl_位置=投影*模型视图*位置;
    v_法线=mat3(模型视图)*法线;
    v_color=颜色;
    }
    `;
    常数fs=`
    精密中泵浮子;
    可变vec3 v_正常;
    可变的vec4 v_颜色;
    均匀浮点数;
    方向一致;
    vec3 rgb2hsv(vec3 c){
    vec4k=vec4(0.0,-1.0/3.0,2.0/3.0,-1.0);
    vec4p=mix(vec4(c.bg,K.wz),vec4(c.gb,K.xy),步骤(c.b,c.g));
    vec4 q=混合(vec4(p.xyw,c.r),vec4(c.r,p.yzx),步骤(p.x,c.r));
    浮动d=q.x-最小值(q.w,q.y);
    浮子e=1.0e-10;
    返回向量3(abs(q.z+(q.w-q.y)/(6.0*d+e)),d/(q.x+e),q.x);
    }
    vec3 hsv2rgb(vec3 c){
    c=vec3(c.x,夹具(c.yz,0.0,1.0));
    vec4k=vec4(1.0,2.0/3.0,1.0/3.0,3.0);
    vec3 p=abs(分形(c.xxx+K.xyz)*6.0-K.www);
    返回c.z*mix(K.xxx,夹具(p-K.xxx,0.0,1.0),c.y);
    }
    void main(){
    vec3 hsv=rgb2hsv(v_color.rgb);
    hsv.x=楼层(hsv.x*numLevels)/numLevels;
    vec3 rgb=hsv2rgb(hsv);
    //假光
    浮动灯光=点(标准化(v_法线),灯光方向)*.5+.5;
    gl_FragColor=vec4(rgb*光,v_颜色.a);
    //取消注释下一行以查看而不使用色调量化
    //gl_FragColor=v_颜色;
    }
    `;
    const programInfo=twgl.createProgramInfo(gl[vs,fs]);
    常数半径=5;
    常数厚度=2;
    常数半径=32;
    const bodyDivisions=12;
    //创建位置、法线等。。。
    常量数组=twgl.primitives.createTorusVertices(
    半径、厚度、半径分割、车身分割);
    //为每个顶点添加颜色
    const numVerts=arrays.position.length/3;
    常量颜色=新的Uint8Array(numVerts*4);
    for(设i=0;i
    body{margin:0;}
    画布{宽度:100vw;高度:100vh;显示:块;}
    
    
    现在您正在将颜色设置为顶点数据的一部分?是的,确切地说,颜色是根据三角形的每个顶点定义的。您最终找到了解决方案吗?我发现这个项目已经实现了类似的功能,但我发现很难破译它