【问题标题】:WebGl scanner effectWebGl 扫描仪效果
【发布时间】:2015-02-26 15:35:09
【问题描述】:

嘿,我刚刚看到这个短视频:https://vine.co/v/hxHz5H2Q07q,我想知道如何实现这种扫描效果。

首先需要 2 组:一组持有带有材料的立方体,另一组对应的持有相同的立方体但只是线框,因此可以获得这些层。

但是如何让有线的人以这种“扫描仪”的方式出现呢?是通过着色器还是threejs中有一些遮罩方法用于在渲染中移动遮罩并显示与遮罩链接的给定对象?

【问题讨论】:

标签: javascript three.js webgl shader


【解决方案1】:

复制自original demo的描述

这个实验的灵感来自于现实世界的投影映射到物理形状。该字段由随机生成创建并合并为单个几何图形。它被复制,并使用 ShaderMaterial 渲染副本,该材质查看一个统一的点并使大多数像素透明,而不是靠近光点的像素。在字段中移动点会创建扫描的外观。

所以,制作一些几何图形,绘制两次,一次是平面阴影,一次是线框。对于线框版本,制作一个采用单点统一的自定义着色器。如果顶点(或像素)靠近该点绘制颜色,如果不绘制透明(或丢弃)。

var camera = new THREE.PerspectiveCamera( 20, 1, 1, 10000 );
camera.position.z = 1800;

var scene = new THREE.Scene();

var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 1, 1, 1 );
scene.add( light );

var flatMaterial = new THREE.MeshLambertMaterial( { color: 0x606060, shading: THREE.FlatShading } );
var geometry = new THREE.IcosahedronGeometry( 200, 1 );

//var wireMaterial = new THREE.MeshBasicMaterial( { color: 0x00FF00, wireframe:true  } );

var uniforms = {
    color:           { type: "c",  value: new THREE.Color(0x00FF00) },
    lightPos:        { type: "v3", value: new THREE.Vector3(0, 0, 0) },
    range:           { type: "f",  value: 150, },
};


var wireMaterial = new THREE.ShaderMaterial({
    wireframe:      true,
    uniforms:       uniforms,
    attributes:     {
    },
    vertexShader:   document.getElementById('vertexshader').text,
    fragmentShader: document.getElementById('fragmentshader').text,
    depthTest:      true,
    transparent:    true,
  });


var	mesh = new THREE.Mesh( geometry, flatMaterial );
scene.add( mesh );

var mesh = new THREE.Mesh( geometry, wireMaterial );
scene.add( mesh );

renderer = new THREE.WebGLRenderer( { antialias: true } );
document.body.appendChild( renderer.domElement );

function resize() {
    var canvas = renderer.context.canvas
    var width = canvas.clientWidth;
    var height = canvas.clientHeight;
    if (width != canvas.width || height != canvas.height) {
      renderer.setSize( width, height, false );
      camera.aspect = width / height;
      camera.updateProjectionMatrix();
    }
}

function render() {
  
    resize();
  
    var time = Date.now() * 0.001;
    uniforms.lightPos.value.x = Math.sin(time) * 200;
    uniforms.lightPos.value.y = Math.cos(time) * 200;
  
    camera.lookAt( scene.position );

    renderer.render( scene, camera );

    requestAnimationFrame( render );
}
render();
html, body {
  margin: 0px;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
canvas {
  width: 100%;
  height: 100%;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.min.js"></script>
<body>
</body>

    <script type="not-js" id="vertexshader">
      varying vec4 v_position;

      void main() {

        vec4 pos = vec4(position, 1.0);

        gl_Position = projectionMatrix * modelViewMatrix * pos;
        v_position = modelMatrix * pos;
      }

    </script>

    <script type="not-js" id="fragmentshader">

      uniform vec3 color;
      uniform vec3 lightPos;
      uniform float range;

      varying vec4 v_position;

      void main() {
        float distanceToLight = distance(lightPos, v_position.xyz);
        gl_FragColor = mix(vec4(color, 1), vec4(0,0,0,0), step(range, distanceToLight));

      }

    </script>

【讨论】:

    【解决方案2】:

    你有一堆平行光线,可能有 100 条,或者你想要多少条,它们射向你的场景并与它相交,同时向上移动 y 方向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 2013-03-04
      • 1970-01-01
      相关资源
      最近更新 更多