在 threejs 中使用顶点着色器旋转几何体
Rotating a geometry using vertex shader in threejs
我正在尝试使用顶点着色器旋转一个盒子,但由于我无法弄清楚的原因它被剪切了,下面是代码,请帮助我。这是 fiddle 和我的顶点着色器代码
uniform float delta;
void main()
{
vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = (projectionMatrix * modelViewPosition);
float new_x = gl_Position.x*cos(delta) - gl_Position.y*sin(delta);
float new_y = gl_Position.y*cos(delta) + gl_Position.x*sin(delta);
gl_Position.x = new_x;
gl_Position.y = new_y;
}
如果视口是矩形的,则由投影矩阵补偿。
这意味着必须应用于顶点坐标的最后一个变换是投影矩阵:
clip_position = projection * view * model * position
您必须将旋转应用于顶点坐标 position
。然后通过视图矩阵和投影矩阵转换结果:
uniform float delta;
void main()
{
vec3 p = position.xyz;
float new_x = p.x*cos(delta) - p.y*sin(delta);
float new_y = p.y*cos(delta) + p.x*sin(delta);
gl_Position = projectionMatrix * modelViewMatrix * vec4(new_x, new_y, p.z, 1.0);
}
此外,设置为投影矩阵 (PerspectiveCamera
) 的纵横比必须与视口 (canvas
) 的纵横比相匹配:
任一
//RENDERER
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
//CAMERA
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10000);
或
//RENDERER
renderer = new THREE.WebGLRenderer();
renderer.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
//CAMERA
camera = new THREE.PerspectiveCamera(75, CANVAS_WIDTH / CANVAS_HEIGHT, 0.01, 10000);
看例子:
var renderer,
scene,
camera,
container = document.getElementById('Canvas_3');
//RENDERER
renderer = new THREE.WebGLRenderer();
//renderer.setClearColor(0xffffff);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
//CAMERA
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10000);
//SCENE
scene = new THREE.Scene();
var customUniforms = {
delta: {
value: 0
}
};
var material = new THREE.ShaderMaterial({
uniforms: customUniforms,
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent
});
var geometry = new THREE.BoxBufferGeometry(1, 1, 1, 0, 0, 0);
var mesh = new THREE.Mesh(geometry, material);
mesh.position.z = -5;
mesh.position.x = 0;
scene.add(mesh);
window.onresize = function() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
//RENDER LOOP
render();
var delta = 0;
function render() {
delta += 0.006;
if (delta > 1.57) delta = 0;
mesh.material.uniforms.delta.value = delta;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>
<div id="Canvas_3"></div>
<script type="x-shader/x-vertex" id="vertexShader">
uniform float delta;
void main()
{
vec3 p = position.xyz;
float new_x = p.x*cos(delta) - p.y*sin(delta);
float new_y = p.y*cos(delta) + p.x*sin(delta);
gl_Position = projectionMatrix * modelViewMatrix * vec4(new_x, new_y, p.z, 1.0);
}
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
uniform float delta;
void main() {
gl_FragColor = vec4(delta, 0.0, 1.0-delta, 1.0);
}
</script>
我正在尝试使用顶点着色器旋转一个盒子,但由于我无法弄清楚的原因它被剪切了,下面是代码,请帮助我。这是 fiddle 和我的顶点着色器代码
uniform float delta;
void main()
{
vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
gl_Position = (projectionMatrix * modelViewPosition);
float new_x = gl_Position.x*cos(delta) - gl_Position.y*sin(delta);
float new_y = gl_Position.y*cos(delta) + gl_Position.x*sin(delta);
gl_Position.x = new_x;
gl_Position.y = new_y;
}
如果视口是矩形的,则由投影矩阵补偿。 这意味着必须应用于顶点坐标的最后一个变换是投影矩阵:
clip_position = projection * view * model * position
您必须将旋转应用于顶点坐标 position
。然后通过视图矩阵和投影矩阵转换结果:
uniform float delta;
void main()
{
vec3 p = position.xyz;
float new_x = p.x*cos(delta) - p.y*sin(delta);
float new_y = p.y*cos(delta) + p.x*sin(delta);
gl_Position = projectionMatrix * modelViewMatrix * vec4(new_x, new_y, p.z, 1.0);
}
此外,设置为投影矩阵 (PerspectiveCamera
) 的纵横比必须与视口 (canvas
) 的纵横比相匹配:
任一
//RENDERER
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
//CAMERA
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10000);
或
//RENDERER
renderer = new THREE.WebGLRenderer();
renderer.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
//CAMERA
camera = new THREE.PerspectiveCamera(75, CANVAS_WIDTH / CANVAS_HEIGHT, 0.01, 10000);
看例子:
var renderer,
scene,
camera,
container = document.getElementById('Canvas_3');
//RENDERER
renderer = new THREE.WebGLRenderer();
//renderer.setClearColor(0xffffff);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
//CAMERA
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10000);
//SCENE
scene = new THREE.Scene();
var customUniforms = {
delta: {
value: 0
}
};
var material = new THREE.ShaderMaterial({
uniforms: customUniforms,
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent
});
var geometry = new THREE.BoxBufferGeometry(1, 1, 1, 0, 0, 0);
var mesh = new THREE.Mesh(geometry, material);
mesh.position.z = -5;
mesh.position.x = 0;
scene.add(mesh);
window.onresize = function() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
//RENDER LOOP
render();
var delta = 0;
function render() {
delta += 0.006;
if (delta > 1.57) delta = 0;
mesh.material.uniforms.delta.value = delta;
renderer.render(scene, camera);
requestAnimationFrame(render);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>
<div id="Canvas_3"></div>
<script type="x-shader/x-vertex" id="vertexShader">
uniform float delta;
void main()
{
vec3 p = position.xyz;
float new_x = p.x*cos(delta) - p.y*sin(delta);
float new_y = p.y*cos(delta) + p.x*sin(delta);
gl_Position = projectionMatrix * modelViewMatrix * vec4(new_x, new_y, p.z, 1.0);
}
</script>
<script type="x-shader/x-fragment" id="fragmentShader">
uniform float delta;
void main() {
gl_FragColor = vec4(delta, 0.0, 1.0-delta, 1.0);
}
</script>