Home Forums Games202-高质量实时渲染 [作业1]关于CPU和GPU同步问题

Viewing 2 reply threads
  • Author
    Posts
    • #8027 Score: 0
      Frank
      Participant

      可能不在大家关心的话题之内,这个问题不涉及到具体的硬/软阴影实现。

      我比较好奇的是phongMaterial的渲染需要shadowMap这个unifor matrix input。那么在2 pass rendering里面,就必须保证两个渲染顺序,更严格地讲,除非shadow map渲染结束,否则phoneMaterial GPU渲染不得开始。这个在代码里是如何体现的呢?

      两个可能性: 第一个在 threeJS里;
      第二个是在loadOBJ这个promises:

      
      material.then((data) => {
      let meshRender = new MeshRender(renderer.gl, mesh, data)						renderer.addMeshRender(meshRender);
      });
      shadowMaterial.then((data) => {
      let shadowMeshRender = new MeshRender(renderer.gl, mesh, data);				renderer.addShadowMeshRender(shadowMeshRender);
      });
      

      但是这是在load obj时的,假如这是正确的那就是每一帧都重新load mesh这件事显得太过蹊跷了…….

      总之希望有解答

    • #8029 Score: 0
      JH
      Participant
      3 pts

      我觉得渲染顺序就是在WebGLRenderer.js的render()函数里确定的,先渲染shadow pass然后渲染camera pass。GPU上commands的执行顺序是由submit的顺序决定的,所以如果CPU先submit shadow pass的draw call再submit camera pass的draw call,那么GPU也会先shadow再camera,而不是同时进行。OpenGL也有一些强制同步的命令比如glFinish()和glFlush(),不过在这种情况下并不需要。不知道我有没有理解对你的问题…
      stackoverflow上类似问题的解答:https://stackoverflow.com/questions/20696150/execution-sequence-for-opengl-commands
      还有一些opengl wiki上关于synchronization的参考资料:https://www.khronos.org/opengl/wiki/Synchronization

      • #8037 Score: 0
        zyk
        Participant
        5 pts

        我也认为是在render函数中确定的,渲染的目标framebuffer是在material中确定的。shadow pass用的材质是渲染到light.fbo,camera pass则是直接渲染到屏幕

    • #8092 Score: 0
      DCXC
      Participant

      框架封装的WebGLRenderer里面写得很清楚,是先draw light, 再Shadow pass,最后Camera pass。

      render() {
              const gl = this.gl;
      
              gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black, fully opaque
              gl.clearDepth(1.0); // Clear everything
              gl.enable(gl.DEPTH_TEST); // Enable depth testing
              gl.depthFunc(gl.LEQUAL); // Near things obscure far things
      
              console.assert(this.lights.length != 0, "No light");
              console.assert(this.lights.length == 1, "Multiple lights");
      
              for (let l = 0; l < this.lights.length; l++) {
                  // Draw light
                  // TODO: Support all kinds of transform
                  this.lights[l].meshRender.mesh.transform.translate = this.lights[l].entity.lightPos;
                  this.lights[l].meshRender.draw(this.camera);
      
                  // Shadow pass
                  if (this.lights[l].entity.hasShadowMap == true) {
                      for (let i = 0; i < this.shadowMeshes.length; i++) {
                          this.shadowMeshes[i].draw(this.camera);
                      }
                  }
      
                  // Camera pass
                  for (let i = 0; i < this.meshes.length; i++) {
                      this.gl.useProgram(this.meshes[i].shader.program.glShaderProgram);
                      this.gl.uniform3fv(this.meshes[i].shader.program.uniforms.uLightPos, this.lights[l].entity.lightPos);
                      this.meshes[i].draw(this.camera);
                  }
              }
          }
      
Viewing 2 reply threads
  • You must be logged in to reply to this topic.