【问题标题】:Three.js vertices position not updating with custom shaderThree.js 顶点位置未使用自定义着色器更新
【发布时间】:2015-09-15 22:43:28
【问题描述】:

我在 three.js 中创建了一个自定义着色器,允许我设置单个顶点的颜色、大小和位置。

颜色和大小可以正常工作,但是当我更新顶点 x、y 或 z 时,它不会在屏幕上更新。

JSFiddle

我错过了什么?

顶点着色器:

<script type="x-shader/x-vertex" id="vertexshader">

  attribute float size;
  attribute vec3 color;

  varying vec3 vColor;
  varying vec2 vUv;

  void main() 
  {
    vColor = color;
    gl_PointSize = size;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }

</script>

片段着色器

<script type="x-shader/x-fragment" id="fragmentshader">

  uniform sampler2D texture;

  varying vec2 vUv;
  varying vec3 vColor;

  void main() 
  {
    vec4 color = vec4(vColor, 1);
    gl_FragColor = color;
  }

</script>

JS:

var container = document.getElementById('container');
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 100;

var scene = new THREE.Scene();

var vShader = document.getElementById('vertexshader').textContent;
var fShader = document.getElementById('fragmentshader').textContent;

var uniforms = {};

var attributes = {
  color: { type: 'c', value: [] },
  size:  { type: 'f', value: [] }
};

var geometry = new THREE.Geometry();

for ( var i = 0; i < 100; i ++ ) 
{
  var angle = Math.random() * Math.PI * 2;
  var radius = 40 + (Math.random() * 5);

  var vertex = new THREE.Vector3();
  vertex.x = Math.cos(angle) * radius;
  vertex.y = Math.sin(angle) * radius;
  vertex.z = 0; 

  attributes.size.value[i] = Math.random() * 10;
  attributes.color.value[i] = new THREE.Color( 0xff0000 );

  geometry.vertices.push( vertex );
}

var material = new THREE.ShaderMaterial(
{ 
  uniforms: uniforms,
  attributes: attributes,
  vertexShader: vShader,
  fragmentShader: fShader,
  transparent: true
});

var particleSystem = new THREE.PointCloud(geometry, material);
scene.add( particleSystem );

renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x292B30, 1 );
container.appendChild( renderer.domElement );

animate();

function animate() 
{
  requestAnimationFrame( animate );
  render();
}

function render() 
{
  for (var i = geometry.vertices.length - 1; i >= 0; i--) 
  {
    geometry.vertices[i].z = geometry.vertices[i].z - 0.5 ;
  }

  camera.lookAt( scene.position );
  //particleSystem.geometry.__dirtyVertices = true;
  renderer.render( scene, camera );
}

【问题讨论】:

    标签: javascript three.js


    【解决方案1】:

    修改顶点位置时,设置verticesNeedUpdate标志:

    geometry.verticesNeedUpdate = true;

    更新小提琴:https://jsfiddle.net/1cmg0z2f/2/

    Three.js r71,由于ShaderMaterial 的更改,小提琴不适用于新版本。

    【讨论】:

    • 太棒了,我有particleSystem.geometry.__dirtyVertices = true;但这似乎什么也没做,也许那是旧代码?但不管怎样,现在请你吃饭,谢谢!
    • 是的,在 r49 之前。请参阅github.com/mrdoob/three.js/wiki/Updates 了解如何更新其他属性。
    • 我怀疑该属性已从 verticesNeedUpdate 更改为 needsUpdate
    【解决方案2】:

    我在之前接受的答案中添加了评论,但以防万一这里有更新的答案

    geometry.attributes[attributeName].needsUpdate = true

    例如

    geometry.attributes.position.needsUpdate = true


    请记住,这适用于您使用 setAttribute 添加的自定义/着色器属性,这是我在找到此 QA 之前一直在搜索的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2012-10-12
      • 1970-01-01
      • 2014-02-03
      相关资源
      最近更新 更多