【问题标题】:ThreeJS - Material which shows surface structure in a scene without lightThreeJS - 在没有光线的场景中显示表面结构的材料
【发布时间】:2018-02-09 14:37:38
【问题描述】:

在我的场景中,我渲染了复杂的对象,它们具有复杂的表面结构。此外,我不在我的场景中使用光,并且我正在努力避免它。

目前我正在使用MeshNormalMaterial,它完美地显示了我的对象的表面结构。

MeshNormalMaterial 的对象:

但我想用独特的颜色渲染某些对象(例如,根据表面结构从深红色到浅红色/类似于MeshNormalMaterial)。


我为一个对象尝试了MeshDepthMaterial,但它以几乎颜色(无/稀疏颜色渐变)渲染整个对象,并且不像example 中那样预期。与相机位置无关。

与上面相同的对象:MeshDepthMaterial


我正在使用THREE.PerspectiveCameraTHREE.OrbitControls。相机属性:

//camera attributes
  public fieldOfView: number = 60;
  public nearClippingPane: number = 0.1;
  public farClippingPane: number = 50000;

MeshNormalMaterial 是否需要光或为什么会这样?我可以以某种方式放大MeshNormalMaterial 的深度效果吗?

是否可以限制 MeshNormalMaterial 的 RGB 颜色,还是我必须使用其他材质来达到我的目的?

【问题讨论】:

标签: three.js


【解决方案1】:

我只是从这个SO answer稍微修改了片段着色器的代码,所以所有功劳归功于Rabbid76:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);

var colors = {
  color1: "#ff0000",
  color2: "#ffaaaa"
}

var geometry = new THREE.TorusKnotBufferGeometry(2, 0.5, 100, 16);
var material = new THREE.ShaderMaterial({
  uniforms: {
    color1: {
      value: new THREE.Color(colors.color1)
    },
    color2: {
      value: new THREE.Color(colors.color2)
    }
  },
  vertexShader: vertShader,
  fragmentShader: fragShader
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

var gui = new dat.GUI();
gui.addColor(colors, "color1").onChange(function(value) {
  material.uniforms.color1.value.set(value);
});
gui.addColor(colors, "color2").onChange(function(value) {
  material.uniforms.color2.value.set(value);
});

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://threejs.org/examples/js/libs/dat.gui.min.js"></script>
<script>
  var vertShader = `
  varying vec3 vNormal;

  void main(void)
  {
      vNormal      = normalMatrix * normalize(normal); 
      gl_Position  = projectionMatrix * modelViewMatrix * vec4(position,1.0);
  }
  `;

  var fragShader = `
  uniform vec3 color1;
  uniform vec3 color2;
  
  varying vec3 vNormal;

  void main(void)
  {
      vec3 view_nv  = normalize(vNormal);
      vec3 nv_color = view_nv * 0.5 + 0.5;
      vec3 c = mix(color1, color2, nv_color.r);
      gl_FragColor  = vec4(c, 1.0);
  }
  `;
</script>

【讨论】:

  • 正是我想要的。但我没有在 html 部分得到 js 部分。 ` 有什么作用?这段代码在 html 部分中是否有特定原因?
  • @d4rty '`' 用于现代浏览器中的多行字符串,因此您不需要为着色器使用字符串数组。一种生活的简化:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2018-04-05
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 2012-12-13
  • 2015-07-07
相关资源
最近更新 更多