1

我想围绕 y 轴旋转一个网格,我使用这个代码来生成网格:

const coinMaterial = new THREE.ShaderMaterial({
    uniforms: { 
        rotationMatrix: { type: 'mat4', value: SHADERS.COIN_ROTATION_MATRIX }
    },
    wireframe: false,
    side: THREE.DoubleSide,
    vertexShader: SHADERS.coinRotationShader(), 
    fragmentShader: SHADERS.coinFragmentShader()
});
const coinGeometry = new THREE.TorusGeometry(5, 2, 8, 30);
const coinMesh = new THREE.Mesh(coinGeometry, coinMaterial);

在这里您可以看到生成旋转矩阵的 SHADERS 模块和着色器:

export function coinRotationShader() { //vertex shader 
    return "                                \
    uniform mat4 rotationMatrix;            \
    void main() {                           \
        vec4 rotatedPosition = rotationMatrix * vec4(position, 1.0); \
        gl_Position = projectionMatrix * modelViewMatrix * rotatedPosition; \
    } \
    ";
}

export function coinFragmentShader() { //just applies yellow color
    return "                        \
    void main() {                   \
        gl_FragColor = vec4(0.8, 0.8, 0, 1.0);   \
    }                               \
    ";
}

const ROTATION_ANGLE = (2*Math.PI) / 60.0; //angle of rotation

export const COIN_ROTATION_MATRIX = createCoinRotationMatrix();

function createCoinRotationMatrix() { //rotates around Y axis
    const rotationMatrix = new THREE.Matrix4();
    rotationMatrix.makeRotationY(ROTATION_ANGLE);
    return rotationMatrix;
}

然而,该对象没有旋转。它出现在正确的位置,并且是黄色的,因此片段着色器正在工作。我是在构造错误的矩阵,还是在顶点着色器中滥用它?

4

1 回答 1

3

看来您设置不rotationMatrix正确。请记住,参数 ofMatrix4.makeRotationY()以弧度(而不是度数)定义。以下面的代码为基础试一试。平面绕 y 轴旋转 45 度。

function coinRotationShader() { //vertex shader 
    return `                                
    uniform mat4 rotationMatrix;            
    void main() {                           
        vec4 rotatedPosition = rotationMatrix * vec4(position, 1.0);
        gl_Position = projectionMatrix * modelViewMatrix * rotatedPosition;
    }
    `;
}

function coinFragmentShader() { //just applies yellow color
    return `
    void main() {
        gl_FragColor = vec4(0.8, 0.8, 0, 1.0);
    }
    `;
}

function createCoinRotationMatrix() { //rotates around Y axis
    const rotationMatrix = new THREE.Matrix4();
    rotationMatrix.makeRotationY( Math.PI * 0.25 );
    return rotationMatrix;
}

//

let camera, scene, renderer;

init();
animate();

function init() {

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
    camera.position.z = 5;

    scene = new THREE.Scene();

    const coinMaterial = new THREE.ShaderMaterial({
        uniforms: { 
            rotationMatrix: { value: createCoinRotationMatrix() }
        },
        vertexShader: coinRotationShader(), 
        fragmentShader: coinFragmentShader()
    });
    const coinGeometry = new THREE.PlaneBufferGeometry();
    const coinMesh = new THREE.Mesh(coinGeometry, coinMaterial);
    
    scene.add( coinMesh );

    renderer = new THREE.WebGLRenderer( { antialias: true } );
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );

}

function animate() {

    requestAnimationFrame( animate );
    renderer.render( scene, camera );

}
body {
	margin: 0;
}
canvas {
	display: block;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.114/build/three.js"></script>

请注意,您可以通过调制 来获得相同的结果Object3D.rotation

于 2020-03-06T17:54:29.030 回答