Permintaan maaf untuk pertanyaan yang tidak jelas tetapi saya tidak yakin bagaimana cara mengungkapkannya. Saya mencoba menulis beberapa kode THREE.js/GLSL yang menghasilkan gradien melingkar (untuk beberapa hal SDF). Dengan kode di bawah ini, saya berharap untuk melihat gradien pada bidang, tetapi bidang tetap putih dan tidak ada yang ditampilkan di atasnya. Adakah yang bisa memberi tahu saya di mana saya salah?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>My first three.js app</title>
        <style>
            body { margin: 0; }
            canvas { width: 100%; height: 100% }
        </style>
    </head>
    <body>
        <script type="x-shader/x-vertex" id="sdfVS">
            varying vec2 vUv; // pass the uv coordinates of each pixel to the frag shader

            void main() {
              vUv = uv;
              gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
            }
        </script>
        <script type="x-shader/x-fragment" id="sdfFS">
            precision mediump float;
            uniform vec2 u_resolution;
            varying vec2 vUv;

            float circle(vec2 pos, float radius)
            {
                return distance(pos, vec2(radius));
            }

            void main()
            {
                vec2 pos = (gl_FragCoord.xy / vUv) * 2.0 - 1.0;
                float circle1 = circle(pos, 0.5);
                vec3 color = vec3(circle1);
                gl_FragColor = vec4(color, 1.0);
            }
        </script>
        <script src="../../js/three.min.js"></script>
        <script>
            var scene, camera, renderer, aspect, geometry, material, plane;
            var container;
            var frustumSize = 2;

            init();
            animate();

            function init() {
                container = document.createElement( 'div' );
                document.body.appendChild( container );

                scene = new THREE.Scene();
                scene.background = new THREE.Color(0x0000ff);

                aspect = window.innerWidth / window.innerHeight;
                camera = new THREE.OrthographicCamera( 0.5 * frustumSize * aspect / - 2, 0.5 * frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, 0.1, 1 );
                cameraOrthoHelper = new THREE.CameraHelper( camera );
                scene.add( cameraOrthoHelper );

                var width = 1;
                var height = 1;
                geometry = new THREE.PlaneGeometry(width, height);

                material = new THREE.ShaderMaterial( {
                    vertexShader: document.getElementById('sdfVS').textContent,
                    fragmentShader: document.getElementById('sdfFS').textContent,
                    side: THREE.DoubleSide
                } );

                plane = new THREE.Mesh( geometry, material );
                plane.rotation.x = 0;
                plane.rotation.y = THREE.Math.degToRad( -90 );
                plane.rotation.z = 0;
                scene.add( plane )

                renderer = new THREE.WebGLRenderer();
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                container.appendChild( renderer.domElement );

                window.addEventListener( 'resize', onWindowResize, false );
            }

            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize( window.innerWidth, window.innerHeight );
            }

            function animate() {
                requestAnimationFrame( animate );
                render();
            }

            function render() {
                camera.position.x = -1;
                camera.position.y = 0;
                camera.position.z = 0;
                camera.lookAt( scene.position );
                camera.updateMatrixWorld();
                renderer.render( scene, camera );
            }
        </script>
    </body>
</html>
1
benjia 26 Oktober 2019, 20:37

1 menjawab

Jawaban Terbaik

Tidak bisa mendapatkan baris ini:

vec2 pos = (gl_FragCoord.xy / vUv) * 2.0 - 1.0;

Sepertinya Anda ingin menghitung koordinat uv, tetapi jika demikian, maka Anda sudah memiliki uvs (diteruskan vUv).

Anda dapat melakukan hal ini dengan cara ini, sebagai opsi:

var scene, camera, renderer, aspect, geometry, material, plane;
var container;
var clock = new THREE.Clock();
var frustumSize = 2;

init();
animate();

function init() {
  container = document.createElement('div');
  document.body.appendChild(container);

  scene = new THREE.Scene();
  scene.background = new THREE.Color(0x0000ff);

  aspect = window.innerWidth / window.innerHeight;
  camera = new THREE.OrthographicCamera(0.5 * frustumSize * aspect / -2, 0.5 * frustumSize * aspect / 2, frustumSize / 2, frustumSize / -2, 0.1, 1);
  cameraOrthoHelper = new THREE.CameraHelper(camera);
  scene.add(cameraOrthoHelper);

  var width = 1;
  var height = 1;
  geometry = new THREE.PlaneGeometry(width, height);

  material = new THREE.ShaderMaterial({
  	uniforms: {time: {value: 0}},
    vertexShader: document.getElementById('sdfVS').textContent,
    fragmentShader: document.getElementById('sdfFS').textContent,
    side: THREE.DoubleSide
  });

  plane = new THREE.Mesh(geometry, material);
  plane.rotation.x = 0;
  plane.rotation.y = THREE.Math.degToRad(-90);
  plane.rotation.z = 0;
  scene.add(plane)

  renderer = new THREE.WebGLRenderer();
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  window.addEventListener('resize', onWindowResize, false);
}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  camera.position.x = -1;
  camera.position.y = 0;
  camera.position.z = 0;
  camera.lookAt(scene.position);
  camera.updateMatrixWorld();
  var t = clock.getElapsedTime();
  material.uniforms.time.value = t;
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script type="x-shader/x-vertex" id="sdfVS">
  varying vec2 vUv; // pass the uv coordinates of each pixel to the frag shader

  void main() {
    vUv = uv;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
  }
</script>
<script type="x-shader/x-fragment" id="sdfFS">
  precision mediump float;

  uniform float time;
  uniform vec2 u_resolution;
  varying vec2 vUv;

  float circle(vec2 uv, vec2 pos, float radius) {
    return smoothstep(radius, 0., length(uv - pos));
  }

  void main()
  {
    vec2 uv = vUv * 2. - 1.;
    vec2 pos = vec2(cos(time), sin(time));
    float circle1 = circle(uv, pos, 1.0);
    vec3 color = vec3(circle1);
    gl_FragColor = vec4(color, 1.0);
  }
</script>
1
prisoner849 26 Oktober 2019, 18:19