opengl – 为什么GL将“gl_Position”由W分配给你,而不是让你自己做?

前端之家收集整理的这篇文章主要介绍了opengl – 为什么GL将“gl_Position”由W分配给你,而不是让你自己做?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
注意:我了解基础数学.我明白,各种数学库中的典型透视函数产生一个矩阵,将z值从-zNear转换为-zFar,返回到-1到1,但只有结果除以w

具体问题是GPU为您做了什么,而不是自己做这个?

换句话说,让我们说GPU并没有通过gl_Position.w神奇地划分gl_Position,而是你手动地像

attribute vec4 position;
uniform mat4 worldViewProjection;

void main() {
  gl_Position = worldViewProjection * position;

  // imaginary version of GL where we must divide by W ourselves
  gl_Position /= gl_Position.w;
}

由于这个原因,这个想象的GL有什么突破?它会工作还是有一些关于传递价值的东西,然后再分配给w,为GPU提供额外的需求信息?

请注意,如果我真的做到了纹理映射透视中断.

"use strict";
var m4 = twgl.m4;
var gl = twgl.getWebGLContext(document.getElementById("c"));
var programInfo = twgl.createProgramInfo(gl,["vs","fs"]);

var bufferInfo = twgl.primitives.createCubeBufferInfo(gl,2);

var tex = twgl.createTexture(gl,{
  min: gl.NEAREST,mag: gl.NEAREST,src: [
    255,255,192,],});

var uniforms = {
  u_diffuse: tex,};

function render(time) {
  time *= 0.001;
  twgl.resizeCanvasToDisplaySize(gl.canvas);
  gl.viewport(0,gl.canvas.width,gl.canvas.height);

  gl.enable(gl.DEPTH_TEST);
  gl.enable(gl.CULL_FACE);
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  var projection = m4.perspective(
      30 * Math.PI / 180,gl.canvas.clientWidth / gl.canvas.clientHeight,0.5,10);
  var eye = [1,4,-6];
  var target = [0,0];
  var up = [0,1,0];

  var camera = m4.lookAt(eye,target,up);
  var view = m4.inverse(camera);
  var viewProjection = m4.multiply(projection,view);
  var world = m4.rotationY(time);

  uniforms.u_worldInverseTranspose = m4.transpose(m4.inverse(world));
  uniforms.u_worldViewProjection = m4.multiply(viewProjection,world);

  gl.useProgram(programInfo.program);
  twgl.setBuffersAndAttributes(gl,programInfo,bufferInfo);
  twgl.setUniforms(programInfo,uniforms);
  gl.drawElements(gl.TRIANGLES,bufferInfo.numElements,gl.UNSIGNED_SHORT,0);

  requestAnimationFrame(render);
}
requestAnimationFrame(render);
body {  margin: 0; }
canvas { display: block; width: 100vw; height: 100vh; }
<script id="vs" type="notjs">
uniform mat4 u_worldViewProjection;
uniform mat4 u_worldInverseTranspose;

attribute vec4 position;
attribute vec3 normal;
attribute vec2 texcoord;

varying vec2 v_texcoord;
varying vec3 v_normal;

void main() {
  v_texcoord = texcoord;
  v_normal = (u_worldInverseTranspose * vec4(normal,0)).xyz;
  gl_Position = u_worldViewProjection * position;
  gl_Position /= gl_Position.w;
}
  </script>
  <script id="fs" type="notjs">
precision mediump float;

varying vec2 v_texcoord;
varying vec3 v_normal;

uniform sampler2D u_diffuse;

void main() {
  vec4 diffuseColor = texture2D(u_diffuse,v_texcoord);
  vec3 a_normal = normalize(v_normal);
  float l = dot(a_normal,vec3(1,0));
  gl_FragColor.rgb = diffuseColor.rgb * (l * 0.5 + 0.5);
  gl_FragColor.a = diffuseColor.a;
}
  </script>
  <script src="https://twgljs.org/dist/2.x/twgl-full.min.js"></script>
  <canvas id="c"></canvas>

但是,是因为GPU实际上需要z和w是不同的,还是只是GPU设计,而不同的设计可以得到所需的信息,如果我们自己划分w?

解决方法

原因在于,不仅将gl_Position除以均匀坐标,还可以将所有其他内插变化除以.这被称为透视正确插值,其需要在插值之后(并且因此在光栅化之后)进行除法.因此,在顶点着色器中进行划分将无法正常工作.参见 this post.

猜你在找的CSS相关文章