Вершинный шейдер для поворота объекта Three JS - PullRequest
1 голос
/ 06 марта 2020

Я хотел бы повернуть меня sh вокруг оси Y, и я использую этот код для генерации меня sh:

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;
}

Объект, однако, не вращается . Он отображается в правильном положении и имеет желтый цвет, поэтому фрагментный шейдер работает. Я неправильно строю матрицу или неправильно использую ее в вершинном шейдере?

1 Ответ

3 голосов
/ 06 марта 2020

Кажется, вы не правильно настроили rotationMatrix. Помните, что параметр Matrix4.makeRotationY() определяется в радианах (не в градусах). Попробуйте это с помощью следующего кода в качестве основы. Плоскость поворачивается на 45 градусов вокруг оси Y.

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...