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

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

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

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

  1. attribute vec4 position;
  2. uniform mat4 worldViewProjection;
  3.  
  4. void main() {
  5. gl_Position = worldViewProjection * position;
  6.  
  7. // imaginary version of GL where we must divide by W ourselves
  8. gl_Position /= gl_Position.w;
  9. }

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

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

  1. "use strict";
  2. var m4 = twgl.m4;
  3. var gl = twgl.getWebGLContext(document.getElementById("c"));
  4. var programInfo = twgl.createProgramInfo(gl,["vs","fs"]);
  5.  
  6. var bufferInfo = twgl.primitives.createCubeBufferInfo(gl,2);
  7.  
  8. var tex = twgl.createTexture(gl,{
  9. min: gl.NEAREST,mag: gl.NEAREST,src: [
  10. 255,255,192,],});
  11.  
  12. var uniforms = {
  13. u_diffuse: tex,};
  14.  
  15. function render(time) {
  16. time *= 0.001;
  17. twgl.resizeCanvasToDisplaySize(gl.canvas);
  18. gl.viewport(0,gl.canvas.width,gl.canvas.height);
  19.  
  20. gl.enable(gl.DEPTH_TEST);
  21. gl.enable(gl.CULL_FACE);
  22. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  23.  
  24. var projection = m4.perspective(
  25. 30 * Math.PI / 180,gl.canvas.clientWidth / gl.canvas.clientHeight,0.5,10);
  26. var eye = [1,4,-6];
  27. var target = [0,0];
  28. var up = [0,1,0];
  29.  
  30. var camera = m4.lookAt(eye,target,up);
  31. var view = m4.inverse(camera);
  32. var viewProjection = m4.multiply(projection,view);
  33. var world = m4.rotationY(time);
  34.  
  35. uniforms.u_worldInverseTranspose = m4.transpose(m4.inverse(world));
  36. uniforms.u_worldViewProjection = m4.multiply(viewProjection,world);
  37.  
  38. gl.useProgram(programInfo.program);
  39. twgl.setBuffersAndAttributes(gl,programInfo,bufferInfo);
  40. twgl.setUniforms(programInfo,uniforms);
  41. gl.drawElements(gl.TRIANGLES,bufferInfo.numElements,gl.UNSIGNED_SHORT,0);
  42.  
  43. requestAnimationFrame(render);
  44. }
  45. requestAnimationFrame(render);
  1. body { margin: 0; }
  2. canvas { display: block; width: 100vw; height: 100vh; }
  1. <script id="vs" type="notjs">
  2. uniform mat4 u_worldViewProjection;
  3. uniform mat4 u_worldInverseTranspose;
  4.  
  5. attribute vec4 position;
  6. attribute vec3 normal;
  7. attribute vec2 texcoord;
  8.  
  9. varying vec2 v_texcoord;
  10. varying vec3 v_normal;
  11.  
  12. void main() {
  13. v_texcoord = texcoord;
  14. v_normal = (u_worldInverseTranspose * vec4(normal,0)).xyz;
  15. gl_Position = u_worldViewProjection * position;
  16. gl_Position /= gl_Position.w;
  17. }
  18. </script>
  19. <script id="fs" type="notjs">
  20. precision mediump float;
  21.  
  22. varying vec2 v_texcoord;
  23. varying vec3 v_normal;
  24.  
  25. uniform sampler2D u_diffuse;
  26.  
  27. void main() {
  28. vec4 diffuseColor = texture2D(u_diffuse,v_texcoord);
  29. vec3 a_normal = normalize(v_normal);
  30. float l = dot(a_normal,vec3(1,0));
  31. gl_FragColor.rgb = diffuseColor.rgb * (l * 0.5 + 0.5);
  32. gl_FragColor.a = diffuseColor.a;
  33. }
  34. </script>
  35. <script src="https://twgljs.org/dist/2.x/twgl-full.min.js"></script>
  36. <canvas id="c"></canvas>

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

解决方法

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

猜你在找的CSS相关文章