是否可以在webgl中翻转3d模型?

问题描述 投票:0回答:1

我使用webgl创建了5个3D模型,并将它们放在同一张画布上。这三个模型中有两个面对用户,但是其余的都背向我。我已经使用照明来照亮模型。

我希望没有面对我的三个模型面对我,但是我似乎无法使其正常工作。我尝试使用矩阵变换将它们旋转180度,但是当它们面对我时它们是黑色的(因为它们没有点亮)。有什么办法可以解决这个问题,或者有可以使用的翻转方法吗?

我的顶点着色器如下:

<script id="vertex-shader" type="x-shader/x-vertex">

attribute vec4 vPosition;
attribute vec3 vNormal;
attribute vec4 vColor;
varying vec4 fColor;
uniform vec4 ambientProduct, diffuseProduct, specularProduct;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec4 lightPosition;
uniform float shininess;

uniform vec3 theta;
uniform vec3 delta;
uniform vec3 omega;


void main()
{

    vec3 angles = radians( theta );
    vec3 c = cos( angles );
    vec3 s = sin( angles );


    mat4 tr = mat4( 1.0, 0.0, 0.0, delta[0],
            0.0,  1.0, 0.0, delta[1],
            0.0,  0.0, 1.0, delta[2],
            0.0,  0.0, 0.0, 1.0 );

    mat4 sc = mat4( omega[0], 0.0, 0.0, 0.0,
            0.0,  omega[1], 0.0, 0.0,
            0.0,  0.0, omega[2], 0.0,
            0.0,  0.0, 0.0, 1.0 );

    mat4 rx = mat4( 1.0,  0.0,  0.0, 0.0,
            0.0,  c.x,  s.x, 0.0,
            0.0, -s.x,  c.x, 0.0,
            0.0,  0.0,  0.0, 1.0 );

    mat4 ry = mat4( c.y, 0.0, -s.y, 0.0,
            0.0, 1.0,  0.0, 0.0,
            s.y, 0.0,  c.y, 0.0,
            0.0, 0.0,  0.0, 1.0 );

    mat4 rz = mat4( c.z, -s.z, 0.0, 0.0,
            s.z,  c.z, 0.0, 0.0,
            0.0,  0.0, 1.0, 0.0,
            0.0,  0.0, 0.0, 1.0 );

    vec3 pos = -(modelViewMatrix * vPosition).xyz;

    vec3 light = lightPosition.xyz;
    vec3 L = normalize( light - pos );
    vec3 E = normalize( -pos );
    vec3 H = normalize( L + E );
    vec4 NN = vec4(vNormal,0);

    vec3 N = normalize( (modelViewMatrix*NN).xyz);

    vec4 ambient = ambientProduct;

    float Kd = max( dot(L, N), 0.0 );
    vec4 diffuse = Kd*diffuseProduct*vColor;

    float Ks = pow( max(dot(N, H), 0.0), shininess );
    vec4 specular = Ks * specularProduct;

    if( dot(L, N) < 0.0 ) {
    specular = vec4(0.0, 0.0, 0.0, 1.0);
    }

    gl_Position = projectionMatrix * modelViewMatrix *  sc * rz * ry * rx *vPosition* tr ;
    fColor = ambient + diffuse+specular;

    fColor.a = 1.0;
}
</script>

我的主要js文件:

var canvas;
var gl;

var lightPosition = vec4(1.0, 3.0, 10.0, 1.0);
var lightAmbient = vec4(0.2, 0.2, 0.2, 1.0);
var lightDiffuse = vec4(1.0, 1.0, 1.0, 1.0);
var lightSpecular = vec4(1.0, 1.0, 1.0, 1.0);
var materialAmbient = vec4(0.0, 0.0, 0.0, 1);
var materialDiffuse = vec4(0.0, 0.0, 0.0, 1);
var materialSpecular = vec4(0.0, 0.0, 0.0, 1);
var materialShininess = 100.0;

var ctm;
var ambientColor, diffuseColor, specularColor;
var modelView, projection;
var viewerPos;
var program;


var theta = 1;
var thetaLoc;

var omega = [ 0, 0, 0 ];
var omegaLoc;


var modelX = 0.2;
var modelY = -0.856;
var modelZ = 0.0;    

var delta = [ 0, 0, 0 ];
var deltaLoc;


window.onload = function init()
{
  canvas = document.getElementById("gl-canvas");
  gl = WebGLUtils.setupWebGL(canvas);
  if (!gl) {
    alert("WebGL isn't available");
  }

  gl.viewport(0, 0, canvas.width, canvas.height);
  gl.clearColor(1.0, 1.0, 1.0, 1.0);
  gl.enable(gl.DEPTH_TEST);
  gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  program = initShaders(gl, "vertex-shader", "fragment-shader");
  gl.useProgram(program);

  scale(0.075,0.075,0.075); 
  translate(modelX, modelY, modelZ); 
  rotate(0,180,0);
  color();
  render(i,b,bc,n);

  requestAnimFrame(init);

};

function render(index,vertex,color,normal){

  var iBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, iBuffer);    
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(index), gl.STATIC_DRAW);

  var nBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, nBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, flatten(normal), gl.STATIC_DRAW);

  var vNormal = gl.getAttribLocation(program, "vNormal");
  gl.vertexAttribPointer(vNormal, 3, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(vNormal);

  var vBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, flatten(vertex), gl.STATIC_DRAW);

  var vPosition = gl.getAttribLocation(program, "vPosition");
  gl.vertexAttribPointer(vPosition, 4, gl.FLOAT, false, 0, 0);
  gl.enableVertexAttribArray(vPosition);

  var cBuffer = gl.createBuffer();
  gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
  gl.bufferData( gl.ARRAY_BUFFER, flatten(color), gl.STATIC_DRAW );

  var vColor = gl.getAttribLocation( program, "vColor" );
  gl.vertexAttribPointer( vColor, 4, gl.FLOAT, false, 0, 0 );
  gl.enableVertexAttribArray( vColor );

  var numVertices= index.length;

  viewerPos = vec3(0.0, 0.0, -20.0);
  projection = ortho(-1, 1, -1, 1, -100, 100);

  ambientProduct = vec4(0.0,0.0,0.0,0.0);
  diffuseProduct = vec4(1.0,1.0,1.0,1.0);
  specularProduct = vec4(1.0,1.0,1.0,1.0);

  gl.uniform4fv(gl.getUniformLocation(program, "ambientProduct"),
    flatten(ambientProduct));
  gl.uniform4fv(gl.getUniformLocation(program, "diffuseProduct"),
    flatten(diffuseProduct));
  gl.uniform4fv(gl.getUniformLocation(program, "specularProduct"),
    flatten(specularProduct));
  gl.uniform4fv(gl.getUniformLocation(program, "lightPosition"),
    flatten(lightPosition));
  gl.uniform1f(gl.getUniformLocation(program,
    "shininess"), materialShininess);

  gl.uniformMatrix4fv(gl.getUniformLocation(program, "projectionMatrix"),
    false, flatten(projection));


  modelView = mat4();
  gl.uniformMatrix4fv(gl.getUniformLocation(program,
    "modelViewMatrix"), false, flatten(modelView));

  gl.drawArrays(gl.TRIANGLES, 0, numVertices);

}

function scale(a,b,c){


    omega=vec3(a,b,c);
    omegaLoc = gl.getUniformLocation(program, "omega");
    gl.uniform3fv(omegaLoc, omega);

};


function translate(d,e,f){


    delta=vec3(d,e,f);
    deltaLoc = gl.getUniformLocation(program, "delta");
    gl.uniform3fv(deltaLoc, delta);
};

function rotate(g,h,i){


    theta=vec3(g,h,i);
    thetaLoc = gl.getUniformLocation(program, "theta");
    gl.uniform3fv(thetaLoc, theta);
};

我模型的js文件(其中一个不面向我)

    var b = [];
    var n = [];

    //VERTICES
  var v = [
    ...
    vec4(-1.75, 10.8, -1.2,1.0),    //0
    vec4(-1.75, 11.2, -1.2,1.0),    //1
    vec4(-1.25, 11.2, -1.2,1.0),    //2
    vec4(-1.25, 10.8, -1.2,1.0),    //3
    vec4(-1.75, 10.8, -1.4,1.0),    //4
    vec4(-1.75, 11.2, -1.4,1.0),    //5
    vec4(-1.25, 11.2, -1.4,1.0),    //6
    vec4(-1.25, 10.8, -1.4,1.0),    //7

  ];

  //VERTEX COLORS
  var c = [
    ...
    vec4( 0.73, 0.60, 0.50, 1.0 ), // black   0
    vec4( 0.73, 0.60, 0.50, 1.0 ), // red     1
    vec4( 0.73, 0.60, 0.50, 1.0 ), // yellow  2
    vec4( 0.73, 0.60, 0.50, 1.0 ), // green   3 
    vec4( 0.73, 0.60, 0.50, 1.0 ), // blue    4
    vec4( 0.73, 0.60, 0.50, 1.0 ), // magenta 5
    vec4( 0.73, 0.60, 0.50, 1.0 ), // white   6
    vec4( 0.73, 0.60, 0.50, 1.0 ), // cyan    7

  ];

  var bc=new Array();

    for(var j=0;j<c.length;j++)
    {
        for(var i=0;i<36;i++)
        {
            bc.push(c[j]);
        }
        j+=7;
    }

  //INDICES
  var i=[
    1,    0,    3,
    3,    2,    1,
    2,    3,    7,
    7,    6,    2,
    3,    0,    4,
    4,    7,    3,
    6,    5,    1,
    1,    2,    6,
    4,    5,    6,
    6,    7,    4,
    5,    4,    0,
    0,    1,    5,
    ...
    577,  576,  579,
    579,  578,  577,
    578,  579,  583,
    583,  582,  578,
    579,  576,  580,
    580,  583,  579,
    582,  581,  577,
    577,  578,  582,
    580,  581,  582,
    582,  583,  580,
    581,  580,  576,
    576,  577,  581,

  ];

  function quadrants(a, b, c, d) {

        var t1 = subtract(v[b], v[a]);
        var t2 = subtract(v[c], v[b]);
        var normal = cross(t1, t2);
        var normal = vec3(normal);

        b.push(v[a]);
        n.push(normal);
        b.push(v[b]);
        n.push(normal);
        b.push(v[c]);
        n.push(normal);
        b.push(v[a]);
        n.push(normal);
        b.push(v[c]);
        n.push(normal);
        b.push(v[d]);
        n.push(normal);

    }

    function color() {

        quadrants(1, 0, 3, 2);
        quadrants(2, 3, 7, 6);
        quadrants(3, 0, 4, 7);
        quadrants(6, 5, 1, 2);
        quadrants(4, 5, 6, 7);
        quadrants(5, 4, 0, 1);
    ...

    quadrants(577, 576, 579, 578);
    quadrants(578, 579, 583, 582);
    quadrants(579, 576, 580, 583);
    quadrants(582, 581, 577, 578);
    quadrants(580, 581, 582, 583);
    quadrants(581, 580, 576, 577);

    }
javascript webgl
1个回答
0
投票

问题是这些行和/或与其相关的JS代码

    vec3 pos = -(modelViewMatrix * vPosition).xyz;

    vec3 light = lightPosition.xyz;
    vec3 L = normalize( light - pos );

查看代码pos是相对于视图的,它在视图空间中,但是light在世界空间中。您可以通过使用“模型矩阵”而不是“模型视图矩阵”来计算pos来修复它,以便在世界空间中以pos的方式进行计算。或者,您可以通过设置lightPosition来修复它,使其位于JavaScript的视图空间中。

由于JavaScipt代码未执行任何矩阵数学运算,因此很难告诉您确切要更改的内容。在着色器中执行大量矩阵数学运算并不常见。我在您的着色器中看到有trscrxryrz。那行得通,但这并不常见。

更为常见的方法是进行矩阵数学运算,以至少使用场景图来计算JavaScript中的至少世界矩阵(模型矩阵)。这意味着您不必编写新的着色器即可更改矩阵的乘法方式。参见thisthis,也许还有this

© www.soinside.com 2019 - 2024. All rights reserved.