用于旋转 ThreeJS 对象的顶点着色器
Vertex shader to rotate a ThreeJS object
我想围绕 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;
}
然而,该物体不旋转。它出现在正确的位置,并且是黄色的,所以片段着色器正在工作。是我构建的矩阵有误,还是在顶点着色器中误用了它?
您似乎没有正确设置 rotationMatrix
。请记住,Matrix4.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
.
即可获得相同的结果
我想围绕 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;
}
然而,该物体不旋转。它出现在正确的位置,并且是黄色的,所以片段着色器正在工作。是我构建的矩阵有误,还是在顶点着色器中误用了它?
您似乎没有正确设置 rotationMatrix
。请记住,Matrix4.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
.