javascript - WebGl扫描仪效果

标签 javascript three.js webgl shader

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

一开始,需要 2 组:一组持有带有 Material 的立方体,另一组拥有相同的立方体但只是线框,因此可以获得这些图层。

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

最佳答案

复制自 original demo 的描述

This experiment was inspired by real-world projection mapping onto physical shapes. The field is created by random generation and merged into a single geometry. It is duplicated and the copy is rendered with a ShaderMaterial that looks at a uniform point and makes most pixels transparent other than those near the light point. Moving the point through the field creates the appearance of scanning.

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

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>

关于javascript - WebGl扫描仪效果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28717938/

相关文章:

基于 Canvas 的游戏的 JavaScript 缓冲 : mediocre performance

javascript - 如何让统计框显示在我的 Threejs Canvas 上?

javascript - Three.js纹理 Material 不带光照

javascript - 在 Javascript 中,如何在窗口位置重定向 Ajax 响应

javascript - 语义用户界面 : Collapsable sidebar with responsive content

javascript - 固定位置着色器背景在 Three.js 中?

webgl - 让 webgl 在 ionic 人行横道上工作

opengl - 我需要 openGl 2.0 但我的显卡支持 1.5

javascript - 如何在动态链接函数jquery函数C#上传递多个参数?

javascript - 无法读取未定义的属性 'controller'