【问题标题】:Three.js outlinesThree.js 大纲
【发布时间】:2021-01-05 11:33:10
【问题描述】:

是否可以在我的 3d 模型上使用 three.js 制作黑色轮廓?

我会有看起来像无主之地 2 的图形。(卡通阴影 + 黑色轮廓)

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    我确定我来晚了。希望以后能解决别人的问题。

    这就是交易,你不需要渲染 一切 两次,开销实际上并不大,你需要做的就是复制网格并将复制网格的材质面设置为“背面” ”。 没有双重通行证。相反,您将渲染两个网格,其中大部分轮廓的几何形状由 WebGL 的“背面剔除”剔除。

    这是一个例子:

    var scene = new THREE.Scene();
    
    //Create main object
    var mesh_geo = new THREE.BoxGeometry(1, 1, 1);
    var mesh_mat = new THREE.MeshBasicMaterial({color : 0xff0000});
    var mesh = new THREE.Mesh(mesh_geo, mesh_mat);
    scene.add(mesh);
    
    //Create outline object
    var outline_geo = new THREE.BoxGeometry(1, 1, 1);
    //Notice the second parameter of the material
    var outline_mat = new THREE.MeshBasicMaterial({color : 0x00ff00, side: THREE.BackSide});
    var outline = new THREE.Mesh(outline_geo, outline_mat);
    //Scale the object up to have an outline (as discussed in previous answer)
    outline.scale.multiplyScalar(1.5);
    scene.add(outline);
    

    有关背面剔除的更多详细信息,请查看:http://en.wikipedia.org/wiki/Back-face_culling

    如果您想在不添加卡通着色器的情况下为对象添加轮廓,则上述方法效果很好,因此会失去“真实感”。

    卡通着色本身支持边缘检测。他们在无主之地开发了“cel”着色器来实现这种效果。

    在 cel 着色开发者可以使用对象复制方法(在 [低] 管道级别完成),或者可以使用图像处理过滤器进行边缘检测。这是比较两种技术之间性能权衡的点。

    关于 cel 的更多信息:http://en.wikipedia.org/wiki/Cel_shading

    干杯!

    【讨论】:

    • 我用复杂的形状尝试过这个,第二个轮廓网格与主要的网格冲突,有时会显示在原始的整个面上。
    • @Blubberguy22 - 是的,它只适用于简单的凸形。你需要后期处理才能更准确。由于缩放,它还会为更大的对象绘制更大的轮廓,所以请记住这一点。
    【解决方案2】:

    是的,这是可能的,但不是以简单的开箱即用方式。对于卡通着色,/examples/js/ShaderToon.js 中甚至包含着色器

    对于轮廓,我认为最常用的方法是分两次渲染。第一次通过将模型渲染为黑色,并且比例略大。第二遍是正常比例和卡通着色器。这样,您将看到较大的黑色模型作为轮廓。这并不完美,但我认为没有简单的出路。搜索“three.js 隐藏线渲染”可能会更成功,因为虽然外观不同,但使用了一些相似的方法来实现。

    【讨论】:

    • 谢谢,但每帧两次渲染会将 fps 除以 2 吗?如果第一次渲染(对于黑色模型)只渲染黑色字符,可能会更少。第二次渲染的风景对象会隐藏黑色模型,不是吗?
    • 是的,我认为所有这些都是合理的担忧。你不需要任何阴影、灯光、阴影或第一次渲染的东西,所以它肯定更便宜但不是免费的。风景需要以某种方式处理,也许在第一遍就渲染它们或其他什么。我没做过,所以我的经验有限。
    • 请。是否可以对涉及以下内容的部分进行任何解释:link?谢谢
    【解决方案3】:

    这是一个老问题,但这是我所做的。

    我为我的 CG 课程创建了 Outlined Cel 着色器。不幸的是,它需要 3 次渲染通道。我目前正试图弄清楚如何删除一张通行证。

    这是一个想法: 1) 将 NormalDepth 图像渲染到纹理。

    在顶点着色器中你做你通常做的事情,定位到屏幕空间和垂直到屏幕空间。

    在片段着色器中计算像素的深度,然后以深度作为 alpha 值创建正常颜色

    float ndcDepth = (2.0 * gl_FragCoord.z - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near);
    float clipDepth = ndcDepth / gl_FragCoord.w;
    

    2) 使用 cel-shading 将场景渲染到纹理上。我更改了场景覆盖材质。

    3) 制作四边形并在四边形上渲染两个纹理,然后用 orto 相机观察它。 Cel-shaded 纹理只是在 quad 上渲染,但是 normaldepth 上的阴影是你使用一些边缘检测,然后你知道什么时候像素需要是黑色的(边缘)。

    【讨论】:

      猜你喜欢
      • 2016-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多