2

我是 WebGL 初学者并尝试绘制多个对象,我已经渲染了一个,现在要绘制多个。多对象渲染的教程非常少,我可以在这个链接上找到一个http://webglfundamentals.org/webgl/lessons/webgl-drawing-multiple-things.html

我尝试根据它更改代码但它不起作用,有人可以纠正问题并给出解决方案并解释我的尝试有什么问题吗?

我的完整代码是:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script class="WebGL">
        var gl;
        function createProgram(gl, vertexShader, fragmentShader)
        {
            var vs = gl.createShader(gl.VERTEX_SHADER);
            gl.shaderSource(vs, vertexShader);
            gl.compileShader(vs);

            if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS))
                alert(gl.getShaderInfoLog(vs));
            //////
            var fs = gl.createShader(gl.FRAGMENT_SHADER);
            gl.shaderSource(fs, fragmentShader);
            gl.compileShader(fs);

            if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS))
                alert(gl.getShaderInfoLog(fs));
            program = gl.createProgram();
            gl.attachShader(program, vs);
            gl.attachShader(program, fs);
            gl.linkProgram(program);
            if (!gl.getProgramParameter(program, gl.LINK_STATUS))
                alert(gl.getProgramInfoLog(program));
            return program;
        }
        function createShaderFromScriptElement(gl , shaderName)
        {
            var Shader = document.getElementById(shaderName).firstChild.nodeValue;
            return Shader;
        }
        function start()
        {
            var canvas = document.getElementById("canvas");
            gl = canvas.getContext("experimental-webgl");
            if (!gl) { alert("error while GL load"); }

              var vertexShader = createShaderFromScriptElement(gl, "2d-vertex-shader");
              var fragmentShader = createShaderFromScriptElement(gl, "2d-fragment-shader");

              var program = createProgram(gl, vertexShader, fragmentShader);

            gl.useProgram(program);
            var colorMult = gl.getAttribLocation(program, "u_colorMult");
            var colorLocation = gl.getUniformLocation(program, "u_color");


            // Our uniforms for each thing we want to draw
            var sphereUniforms = {
                u_colorMult: [0.5, 1, 0.5, 1],
                u_matrix: makeIdentity(),
            };
            var cubeUniforms = {
                u_colorMult: [1, 0.5, 0.5, 1],
                u_matrix: makeIdentity(),
            };
            var coneUniforms = {
                u_colorMult: [0.5, 0.5, 1, 1],
                u_matrix: makeIdentity(),
            };

            // The translation for each object.
            var sphereTranslation = [0, 0, 0];
            var cubeTranslation = [-40, 0, 0];
            var coneTranslation = [40, 0, 0];


            var sphereXRotation = time;
            var sphereYRotation = time;
            var cubeXRotation = -time;
            var cubeYRotation = time;
            var coneXRotation = time;
            var coneYRotation = -time;

            // ------ Draw the sphere --------

            gl.useProgram(programInfo.program);

            // Setup all the needed attributes.
            setBuffersAndAttributes(gl, programInfo.attribSetters, sphereBufferInfo);

            sphereUniforms.u_matrix = computeMatrix(
                viewMatrix,
                projectionMatrix,
                sphereTranslation,
                sphereXRotation,
                sphereYRotation);

            // Set the uniforms we just computed
            setUniforms(programInfo.uniformSetters, sphereUniforms);

            gl.drawArrays(gl.TRIANGLES, 0, sphereBufferInfo.numElements);

            // ------ Draw the cube --------

            // Setup all the needed attributes.
            setBuffersAndAttributes(gl, programInfo.attribSetters, cubeBufferInfo);

            cubeUniforms.u_matrix = computeMatrix(
                viewMatrix,
                projectionMatrix,
                cubeTranslation,
                cubeXRotation,
                cubeYRotation);

            // Set the uniforms we just computed
            setUniforms(programInfo.uniformSetters, cubeUniforms);

            gl.drawArrays(gl.TRIANGLES, 0, cubeBufferInfo.numElements);

            // ------ Draw the cone --------

            // Setup all the needed attributes.
            setBuffersAndAttributes(gl, programInfo.attribSetters, coneBufferInfo);

            coneUniforms.u_matrix = computeMatrix(
                viewMatrix,
                projectionMatrix,
                coneTranslation,
                coneXRotation,
                coneYRotation);

            // Set the uniforms we just computed
            setUniforms(programInfo.uniformSetters, coneUniforms);

            gl.drawArrays(gl.TRIANGLES, 0, coneBufferInfo.numElements);
        }
    </script>
    <script id="2d-vertex-shader" type="x-shader/x-vertex">
        // Passed in from the vertex shader.
        varying vec4 v_color;
        uniform vec4 u_colorMult;

        void main() 
        {
            gl_FragColor = v_color * u_colorMult;
        }
    </script>

    <script id="2d-fragment-shader" type="x-shader/x-fragment">
        precision mediump float;
        uniform vec4 u_color;

        void main()
        {
        gl_FragColor = u_color;  // green
        }
    </script>
</head>
<body onload="start()">
    <div style="text-align: center">

    </div>
    <table style="width:100%; height: 10%;">       
        <tr>
            <td style="width:200px; max-width:200px; ">
                <canvas id="canvas" width="300" height="300"></canvas>
            </td>
            <td style="width:200px; max-width:200px; background-color:gray; ">
                <canvas id="canvas2" width="300" height="300"></canvas>
            </td>
        </tr>
    </table>
</body>
</html> 

请向我解释解决方案,以便我理解并在未来保留它。谢谢

4

1 回答 1

1

GLSL 着色器有 3 种类型的变量:

  • Uniforms由主机应用程序设置,并在单个绘图调用中在所有顶点/片段中保持不变。
  • 属性由主机应用程序按顶点设置,并且在顶点着色器中只读。
  • Varyings仅由顶点着色器写入,并在光栅化器中插值后由片段着色器读取。

因此,我可以在您的代码中发现一些问题:

  • 您正在尝试在顶点着色器中读取“变化”,请改用顶点属性。
  • 您正在调用类似makeIdentity但我没有看到它们声明的函数,编辑您的页面以拉入适当的矩阵库以提供这些函数。
  • 我在这里没有看到任何实际的顶点数据被传递到 WebGL。没有顶点数据,什么都不会被渲染。

您在问题中链接到的文章有一个独立的演示,您可以View source查看完整的工作示例。请注意,它在顶部引入了一些矩阵数学帮助程序库,并调用诸如createCubeVertices创建顶点数据之类的函数。

另请查看Learning WebGL 的第 2 课,他们将顶点颜色应用于某些多边形。您可能想按照自己的方式完成那里的所有课程

此外,大多数开发人员发现他们不需要从头开始构建自己的 3D 引擎。考虑学习一种可以隐藏 WebGL 低级细节的现有 WebGL 框架。其中,Three.js是一个受欢迎的起点。如果您不需要深入了解所有底层细节,这将为您节省大量时间和精力。

于 2015-10-20T14:40:13.913 回答