THREE.JS: Как вращать объект вокруг его центра в вершинном шейдере? - PullRequest
1 голос
/ 03 июня 2019

У меня есть простой объект THREE.Points. Необходимо повернуть его вокруг центральной оси Y с помощью шейдера (зеленая линия), а также общего положения объекта. Я уже прокомментировал это, так что это не влияет на проблему вращения.

enter image description here

Теперь он имеет неправильное «орбитальное» вращение. Уверен, что мне нужно играть с tPos. Пытались без успеха.

       

		var stats, scene, renderer;
		var camera, cameraControl, mesh;

		if( !init() )	animate();

		function init(){

            renderer = new THREE.WebGLRenderer({
					antialias		: true,
					preserveDrawingBuffer	: true
				});
            renderer.setClearColor( 0xBBBBBB, 1 );
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.getElementById('container').appendChild(renderer.domElement);

			scene = new THREE.Scene();

			camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 1, 10000 );
			camera.position.set(0, 0, 5);
			scene.add(camera);

            var geometry = new THREE.BufferGeometry();

            var vertices = new Float32Array( [
                
                -1.0, -1.0,  1.0,
                1.0, -1.0,  1.0,
                1.0,  1.0,  1.0,

                1.0,  1.0,  1.0,
                -1.0,  1.0,  1.0,
                -1.0, -1.0,  1.0
                
            ] );

            geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
            
            var material = new THREE.ShaderMaterial( {

            side : THREE.DoubleSide,
                
            uniforms: {

            parentPosition: { value: new THREE.Vector3(0.0, 0.0, 0.0) },
            rotation: { type: "f", value: 0.0 },
            texture: { value: new THREE.TextureLoader().load( "assets/blob.png" ) }

            },

             vertexShader: document.getElementById( "vertexshader" ).textContent,
             fragmentShader: document.getElementById( "fragmentshader" ).textContent,
             alphaTest: 0.9

            } );
            
            mesh = new THREE.Mesh( geometry, material );
            scene.add(mesh);

		}

		function animate() {
            
                     //mesh.material.uniforms.parentPosition.value.x += 0.01;
      mesh.material.uniforms.rotation.value += 0.01;
            
			requestAnimationFrame( animate );
            
			render();

		}


		function render() {
            
			renderer.render( scene, camera );
            
		}
body{ margin: 0px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/105/three.js"></script>

<!doctype html>
<html>
	<head>
		<title>three.js template</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

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

    uniform vec3 parentPosition;
    uniform float rotation;
    varying vec4 vColor;
    varying mat4 vPosition;
    
    void main() {
    
        mat4 tPos = mat4(vec4(1.0,0.0,0.0,0.0),
                       vec4(0.0,1.0,0.0,0.0),
                       vec4(0.0,0.0,1.0,0.0),
                       vec4(0,0,0,1.0));
                        
        mat4 rYPos = mat4(vec4(cos(rotation),0.0,sin(rotation),0.0),
                        vec4(0.0,1.0,0.0,0.0),
                        vec4(-sin(rotation),0.0,cos(rotation),0.0),
                        vec4(0.0,0.0,0.0,1.0));

        vPosition = tPos * rYPos;
        
        vColor = vec4(1.0, 0.0, 1.0, 1.0);
        vec3 newPosition = position + parentPosition;
        vec4 mvPosition = modelViewMatrix * vPosition * vec4( newPosition, 1.0 );
        gl_PointSize = 32.0 * ( 300.0 / -mvPosition.z );
        gl_Position = projectionMatrix * mvPosition;
        
    }
    
</script>

<script type="x-shader/x-fragment" id="fragmentshader">

    uniform sampler2D texture;
    varying vec4 vColor;
    varying mat4 vPosition;
    
    void main() {

        gl_FragColor = vColor;
        gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
    
    }
    
</script>
        
        
	</head>
<body>

    <div id="container"></div>

</body>
</html>
mat4 tPos = mat4(vec4(1.0,0.0,0.0,0.0),
                       vec4(0.0,1.0,0.0,0.0),
                       vec4(0.0,0.0,1.0,0.0),
                       vec4(0,0,0,1.0));

mat4 rYPos = mat4(vec4(cos(rotation),0.0,sin(rotation),0.0),
                        vec4(0.0,1.0,0.0,0.0),
                        vec4(-sin(rotation),0.0,cos(rotation),0.0),
                        vec4(0.0,0.0,0.0,1.0));

vPosition = tPos * rYPos;

vColor = vec4(1.0, 0.0, 1.0, 1.0);
vec3 newPosition = position + parentPosition;
vec4 mvPosition = modelViewMatrix * vPosition * vec4( newPosition, 1.0 );

Может кто-нибудь мне помочь?

1 Ответ

0 голосов
/ 03 июня 2019

Это моя вина. Код работает отлично. Необходимо установить все значения Z на 0.0.

var vertices = new Float32Array( [

-1.0, -1.0,  0.0,
1.0, -1.0,  0.0,
1.0,  1.0,  0.0,

1.0,  1.0,  0.0,
-1.0,  1.0,  0.0,
-1.0, -1.0,  0.0

] );
...