Как избежать артефактов рендеринга из-за неточных мировых координат в WebGL? - PullRequest
2 голосов
/ 05 апреля 2019

Проблема:

Я испытываю артефакты рендеринга при использовании координат мира внутри шейдера фрагмента для рендеринга сетки.При перемещении плоскости, на которую отображается, сетка не перемещается равномерно (одна «половина» движется, а другая - нет).

См. Рисунок: Rendering artifacts

Я предполагаю, что "значение перемещения" 0.05 слишком мало, что вызывает неточности и, следовательно, артефакты рендеринга.Однако я не уверен, как ограничить значение таким образом, чтобы оно не вызывало артефактов, поскольку значения перемещения зависят от ряда других факторов (увеличение камеры до сцены, заданная пользователем скорость перемещения и т. Д.).

Было бы прекрасно, если бы сетка двигалась только на каждом втором такте движения, пока она движется равномерно .

Есть ли лучший способ избежать такого рендеринга?надежные артефакты?

Контекст:

Я разрабатываю приложение, которое отображает данные изображения на плоскость.Для каждого текселя визуализированной плоскости ищется соответствующая мировая координата для визуализации данных.Камера является орфографической и смотрит прямо на указанную плоскость.Когда я заметил "колеблющиеся" артефакты рендеринга, я проследил, что источник обратно (что я предполагаю) является неточным в мировых координатах (?).

Минимальный код для воспроизведения

const scene = new THREE.Scene();
const camera = new THREE.OrthographicCamera(window.innerWidth / -50, window.innerWidth / 20, window.innerHeight / 50, window.innerHeight / -20, 1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const geometry = new THREE.PlaneGeometry(100, 100, 1, 1);
const material = new THREE.ShaderMaterial({
  vertexShader: `
precision highp float;

varying vec4 worldCoord;

void main() {
  worldCoord = modelMatrix * vec4(position, 1.0);
  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
  fragmentShader: `
varying vec4 worldCoord;
void main() {
  gl_FragColor = mod(floor(worldCoord), 2.0) / 2.0; 
}
`
});

const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;

let i = 0;
let moveValue = 0.05;
let render = function() {
  i++;
  if (i % 5 === 0) {
    moveValue *= -1.0;
  }

  cube.position.x += moveValue;
  camera.position.x += moveValue;
  
  renderer.render(scene, camera);
};

setInterval(render, 400);
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>

1 Ответ

1 голос
/ 05 апреля 2019

Я думаю, что вы, возможно, испытываете форму "псевдонимов".

Эта статья может оказаться полезной:

http://madebyevan.com/shaders/grid/

и это:

https://fgiesen.wordpress.com/2011/07/10/a-trip-through-the-graphics-pipeline-2011-part-8/

...