Webgl Текстурные Артефакты - PullRequest
       101

Webgl Текстурные Артефакты

0 голосов
/ 30 января 2020

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

float y_rot = mix(uAnimationStep, ease_out, aTextureCoord.x) * -PI;

All good

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

float curve = mix(0.0, 0.25, aTextureCoord.y);
float y_rot = mix(uAnimationStep, ease_out + curve, aTextureCoord.x) * -PI;

Я уверен, что мне чего-то не хватает, здесь c здесь ... любой идеи? Я пытался включить mipmapping, но это не помогло. Спасибо!

enter image description here

1 Ответ

1 голос
/ 08 февраля 2020

На самом деле не хватает кода, чтобы ответить на ваш вопрос, но, скопировав 2 строки в какой-то случайный образец, я не вижу проблем, поэтому кажется, что ваша проблема в другом месте.

'use strict';

/* global twgl, requestAnimationFrame, document */

const m4 = twgl.m4;
const gl = document.querySelector('canvas').getContext('webgl');

const vs = `
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texcoord;

uniform mat4 projection;
uniform mat4 modelView;
uniform float uAnimationStep;

const float ease_out = 0.0;

varying vec3 v_normal;
varying vec2 v_texcoord;

#define PI radians(180.0)

mat4 rotY(float angleInRadians) {
    float s = sin(angleInRadians);
    float c = cos(angleInRadians);
  	
    return mat4( 
      c, 0,-s, 0,
      0, 1, 0, 0,
      s, 0, c, 0,
      0, 0, 0, 1);  
}

void main() {
  vec2 aTextureCoord = texcoord;
  float curve = mix(0.0, 0.25, aTextureCoord.y);
  float y_rot = mix(uAnimationStep, ease_out + curve, aTextureCoord.x) * -PI;

  mat4 effectiveModelView = modelView * rotY(y_rot);
  gl_Position = projection * effectiveModelView * position;
  v_normal = mat3(effectiveModelView) * normal;
  v_texcoord = texcoord;
}
`;

const fs = `
precision highp float;

varying vec3 v_normal;
varying vec2 v_texcoord;
varying float v_modelId;

uniform sampler2D tex;

void main() {
  vec3 lightDirection = normalize(vec3(1, 2, 30));  // arbitrary light direction
  vec3 color = texture2D(tex, v_texcoord).rgb;

  float l = dot(lightDirection, normalize(v_normal)) * .5 + .5;
  gl_FragColor = vec4(color * l, 1);
}
`;

// compile shader, link, look up locations
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);

// make some vertex data
// calls gl.createBuffer, gl.bindBuffer, gl.bufferData
const bufferInfo = twgl.primitives.createPlaneBufferInfo(
    gl, 
    32,   // width
    32,   // depth
    32,   // width subdivisions
    32,   // height subdivisions
    m4.rotationX(Math.PI / 2),  // matrix to apply (plane is XZ, make it XY)
);

const tex = twgl.createTexture(gl, {src: 'https://i.imgur.com/ZKMnXce.png'});

function render(time) {
  time *= 0.001;  // seconds

  twgl.resizeCanvasToDisplaySize(gl.canvas);

  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  gl.enable(gl.DEPTH_TEST);

  const fov = Math.PI * 0.25;
  const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
  const near = 0.1;
  const far = 100;
  const projection = m4.perspective(fov, aspect, near, far);

  const eye = [0, 30, 35];
  const target = [0, 0, 0];
  const up = [0, 1, 0];
  const camera = m4.lookAt(eye, target, up);
  const view = m4.inverse(camera);
  let modelView = m4.rotateY(view, 0.2 * time);
  modelView = m4.translate(modelView, [0, 0, 0]);

  gl.useProgram(programInfo.program);

  // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
  twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);

  // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
  twgl.setUniforms(programInfo, {
    projection,
    modelView,
    tex,
    uAnimationStep: Math.sin(time),
  });  

  // calls gl.drawArrays or gl.drawElements
  twgl.drawBufferInfo(gl, bufferInfo);

  requestAnimationFrame(render);
}
requestAnimationFrame(render);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>
...