【问题标题】:Render a shader without having to add a Geometry to the scene in ThreeJS渲染着色器而无需在 ThreeJS 中将几何图形添加到场景中
【发布时间】:2021-08-11 20:40:50
【问题描述】:

我目前正在尝试仅使用着色器绘制形状或至少相当于ThreeJS r128 中的geometry

使用此库在屏幕上绘制内容的常用方法包括创建一个 mesh 和一个与之关联的 geometry(这里是用于项目创建的 boilerplate code)。创建该对象后,我们可以通过ShaderMaterial 类将着色器应用到这个新组件。

但是,我找不到如何在场景上而不是在对象上渲染着色器。使用 OpenGL 着色语言 (GLSL),我们实际上可以在没有顶点的情况下在屏幕上绘制形状。这就是我的目标,但我似乎纠结于这个渲染系统。

是否可以仅使用 ThreeJS 中的着色器进行渲染?


为了测试,这里有一个用着色器创建实心圆的函数:

片段着色器:

uniform vec2 u_resolution;

float circleShape(vec2 position, float radius){
    return step(radius, length(position));
}

void main(){
    vec2 position = gl_FragCoord.xy / u_resolution;
    float circle = circleShape(position, 0.3);
    vec3 color = vec3(circle);
    gl_FragColor = vec4(color, 1.0);
} 

这是我的顶点着色器,以防万一:

void main(){
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

【问题讨论】:

    标签: javascript three.js glsl shader webgl


    【解决方案1】:

    只需在整个画布上绘制THREE.PlaneGeometry

    var container, camera, scene, renderer, uniforms;
    
    init();
    animate();
    
    function init() {
        container = document.getElementById( 'container' );
        camera = new THREE.Camera();
        camera.position.z = 1;
        scene = new THREE.Scene();
        var geometry = new THREE.PlaneGeometry( 2, 2 );
    
        uniforms = {
            //u_time: { type: "f", value: 1.0 },
            u_resolution: { type: "v2", value: new THREE.Vector2() },
            //u_mouse: { type: "v2", value: new THREE.Vector2() }
        };
    
        var material = new THREE.ShaderMaterial( {
            uniforms: uniforms,
            vertexShader: document.getElementById( 'vertexShader' ).textContent,
            fragmentShader: document.getElementById( 'fragmentShader' ).textContent
        } );
    
        var mesh = new THREE.Mesh( geometry, material );
        scene.add( mesh );
    
        renderer = new THREE.WebGLRenderer();
        renderer.setPixelRatio( window.devicePixelRatio );
        container.appendChild( renderer.domElement );
        onWindowResize();
        window.addEventListener( 'resize', onWindowResize, false );
        document.onmousemove = function(e){
            //uniforms.u_mouse.value.x = e.pageX
            //uniforms.u_mouse.value.y = e.pageY
        }
    }
    
    function onWindowResize( event ) {
        renderer.setSize( window.innerWidth, window.innerHeight );
        uniforms.u_resolution.value.x = renderer.domElement.width;
        uniforms.u_resolution.value.y = renderer.domElement.height;
    }
    
    function animate(delta_ms) {
        requestAnimationFrame(animate);
        render(delta_ms);
    }
    
    function render(delta_ms) {
        //uniforms.u_time.value = delta_ms;
        renderer.render( scene, camera );
    }
    <script src="https://cdn.jsdelivr.net/npm/three@0.128/build/three.js"></script>
    <div id="container"></div>
    
    <script id="vertexShader" type="x-shader/x-vertex">
    void main() {
        gl_Position = vec4( position, 1.0 );
    }
    </script>
    
    <script id="fragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    
    uniform vec2 u_resolution;
    
    float circleShape(vec2 position, float radius){
        return step(radius, length(position));
    }
    
    void main(){
        vec2 position = gl_FragCoord.xy / u_resolution;
        float circle = circleShape(position, 0.3);
        vec3 color = vec3(circle);
        gl_FragColor = vec4(color, 1.0);
    } 
    </script>

    【讨论】:

      猜你喜欢
      • 2020-08-20
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多