Карта глубины для системы частиц с использованием карты текстуры

Я пытаюсь создать карту глубины для системы частиц, но если я визуализирую систему частиц с помощью MeshDepthMaterial, то каждая частица визуализируется только как одна точка для каждой вершины, не покрывая всю область, на которой отображается частица с текстурой. .

Нужно ли использовать MeshDepthMaterial для создания карты глубины или есть другие варианты?


person Someone    schedule 05.12.2012    source источник


Ответы (1)


Сейчас нет способа заставить MeshDepthMaterial учитывать размер или текстуру ParticleSystem. Однако не так уж сложно реализовать собственный ShaderMaterial, который делает это. Во-первых, вам нужен вершинный шейдер и фрагментный шейдер.

<script type="x-shader/x-vertex" id="vertexShader">
  uniform float size;
  void main() {
    gl_PointSize = size;
    gl_Position = projectionMatrix * modelViewMatrix * vec4( position , 1.0 ); 
  }
</script>

<script type = "x-shader/x-fragment" id="fragmentShader">
  uniform sampler2D map;
  uniform float near;
  uniform float far;

  void main() {
    float depth = gl_FragCoord.z / gl_FragCoord.w;
    float depthColor = 1.0 - smoothstep( near, far, depth );

    vec4 texColor = texture2D( map, vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y ) );
    gl_FragColor = vec4( vec3(depthColor), texColor.a);
  }
</script>

Вершинный шейдер полностью стандартный, фрагментный шейдер берет текстуру (sampler2D map), но вместо того, чтобы использовать ее для значений цвета, он просто использует альфа-уровень texColor.a. Для rgb используется значение оттенков серого на основе глубины, как и MeshDepthMaterial. Теперь, чтобы использовать этот шейдер, вам просто нужно взять html и создать THREE.ShaderMaterial следующим образом:

var material = new THREE.ShaderMaterial({
    uniforms : {
      size : { type: 'f', value : 20.0 },
      near : { type: 'f', value : camera.near },
      far  : { type: 'f', value : camera.far },
      map  : { type: "t", value : THREE.ImageUtils.loadTexture( url ) }
    },
    attributes : {},
    vertexShader: vertShader,
    fragmentShader: fragShader,
    transparent: true
  });

Здесь вы предоставили шейдеру всю необходимую информацию: ближний/дальний диапазон камеры, размер частицы и текстуру, которую необходимо отобразить.

Вы можете увидеть демонстрацию jsFiddle здесь.

person Paul Kaplan    schedule 05.12.2012
comment
Спасибо, Пол. Отличный ответ. На самом деле мне даже не нужно было генерировать карту глубины, как только я понял, что информация о глубине, используемая в шейдере, доступна во фрагментном шейдере (gl_FragCoord.z ​​/ gl_FragCoord.w), я мог сделать весь эффект за один проход. - person Someone; 27.12.2012