对象的明暗器线框 [英] Shader wireframe of an object

查看:84
本文介绍了对象的明暗器线框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想看到一个没有像对角线这样的物体的线框

I want to see a wireframe of an object without the diagonals like

当前,我根据顶点添加线,问题是在遇到其中几条之后,我的性能出现了严重的下降.

Currently, I add lines according to the vertices, the problem is after I have several of those I experience a major performance degradation.

示例此处对于我的《三人》版本来说太新了,或者不起作用(我对此发表了评论).

The examples here are either too new for my version of Three or don't work (I commented there about it).

所以我想尝试实现一个着色器.

So I want to try to implement a shader instead.

我尝试使用此着色器: https://stackoverflow.com/a/31610464/4279201 但它会中断零件的形状,并且出现WebGL错误.

I tried to use this shader: https://stackoverflow.com/a/31610464/4279201 but it breaks the shape to parts and I'm getting WebGL errors.

这就是我的用法:

const vertexShader = `
varying vec2 vUv;
void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
`

const fragmentShader = `
#version 150 compatibility                                         
flat in float diffuse;
flat in float specular;
flat in vec3  edge_mask;                                           
in vec2 bary;
uniform float mesh_width = 1.0;
uniform vec3 mesh_color = vec3(0.0, 0.0, 0.0);
uniform bool lighting = true;
out vec4 frag_color ;
float edge_factor(){                                               
  vec3 bary3 = vec3(bary.x, bary.y, 1.0 - bary.x - bary.y);
  vec3 d = fwidth(bary3);
  vec3 a3 = smoothstep(vec3(0.0, 0.0, 0.0), d * mesh_width, bary3);
  a3 = vec3(1.0, 1.0, 1.0) - edge_mask + edge_mask * a3;
  return min(min(a3.x, a3.y), a3.z);
}
void main() {                                                      
  float s = (lighting && gl_FrontFacing) ? 1.0 : -1.0;
  vec4  Kdiff = gl_FrontFacing ?
    gl_FrontMaterial.diffuse : gl_BackMaterial.diffuse;
  float sdiffuse = s * diffuse;
  vec4 result = vec4(0.1, 0.1, 0.1, 1.0);
  if (sdiffuse > 0.0) {
    result += sdiffuse * Kdiff +
      specular * gl_FrontMaterial.specular;
  }
  frag_color = (mesh_width != 0.0) ?
    mix(vec4(mesh_color, 1.0), result, edge_factor()) :
    result;
}`     

...

const uniforms = {
  color: {
    value: new THREE.Vector4(0, 0, 1, 1),
    type: 'v4'
  }
}

const material = new THREE.ShaderMaterial({
  fragmentShader: data.fragmentShader,
  vertexShader: data.vertexShader,
  uniforms
})

this._viewer.impl.matman().addMaterial(
  data.name, material, true)

    const fragList = this._viewer.model.getFragmentList()

this.toArray(fragIds).forEach((fragId) => {

  fragList.setMaterial(fragId, material)
})

因此,要实现此着色器,正确的方法是基本上检查每两个顶点之间的角度并在度数为90时画一条线吗?

So to implement this shader, is the right approach would be to basically check the angle between every two vertices, and draw a line if the degree is 90?

如何从顶点着色器访问形状的所有顶点?

How can I have access to all the vertices of the shape from the vertex shader?

又如何告诉片段着色器在与上述条件匹配的两个顶点之间绘制一条线? (也可以保留其他所有内容的默认阴影)

And how can I tell the fragment shader to draw a line between two vertices that match the above condition? (also to leave the default shading for everything else as is)

我正在使用使用Three.js修订版71的Autodesk Viewer.

I'm using Autodesk viewer that uses Three.js rev 71.

推荐答案

// -- Vertex Shader --
precision mediump float;

// Input from buffers
attribute vec3 aPosition;
attribute vec2 aBaryCoord;

// Value interpolated accross pixels and passed to the fragment shader
varying vec2 vBaryCoord;

// Uniforms
uniform mat4 uModelMatrix;
uniform mat4 uViewMatrix;
uniform mat4 uProjMatrix;

void main() {
    vBaryCoord = aBaryCoord;
    gl_Position = uProjMatrix * uViewMatrix * uModelMatrix * vec4(aPosition,1.0);
}
// ---------------------

// -- Fragment Shader --
// This shader doesn't perform any lighting
precision mediump float;

varying vec2 vBaryCoord;

uniform vec3 uMeshColour;

float edgeFactor() {
    vec3 d = fwidth(vBaryCoord);
    vec3 a3 = smoothstep(vec3(0.0,0.0,0.0),d * 1.5,vBaryCoord);
    return min(min(a3.x,a3.y),a3.z);
}

void main() {
    gl_FragColor = vec4(uMeshColour,(1.0 - edgeFactor()) * 0.95);
}
// ---------------------

/*
    This code isn't tested so take it with a grain of salt

    Idea taken from
    http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/
*/

这篇关于对象的明暗器线框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆