मैं सीख रहा हूं कि जीएलएसएल कोड में आकृतियाँ कैसे बनाई जाती हैं और मैंने हाल ही में निम्नलिखित कोड का उपयोग करके एक वर्ग के केंद्र में एक तारे जैसा आकार बनाया है:

#idef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution;
uniform vec2 u_time;


void main(){
  vec2 st = gl_FragCoord.xy/u_resolution.xy;
  st.x *= u_resolution.x/u_resolution.y;
  vec3 color = vec3(0.0);
  float d = 0.0;

  // Remap space to -1 to 1.
  st = st *2.-1.;

  // Make Distance Field
  d = length(abs(st)-.3);
  d = length(min(abs(st)-.3, 0.));

  // Visualize the Distance Field
  gl_FragColor = vec4(vec3(fract(d*10.0)), 1.0);

  // Draw with the distance field
  gl_FragColor = vec4(vec3(step(.3, d)), 1.0);

}

अब मैं इस वर्गाकार डिजाइन को एक बॉर्डर वाले टाइल जैसे पैटर्न में दोहराने की कोशिश करना चाहता हूं, लेकिन मुझे नहीं पता कि कॉलम में इसे डुप्लिकेट करने के लिए अपने कोड को कैसे संशोधित किया जाए। क्या कोई मदद कर सकता है?

2
Garrus 27 सितंबर 2020, 10:46

1 उत्तर

सबसे बढ़िया उत्तर

बस st को टाइलों की संख्या से मापें और परिणाम का भिन्नात्मक भाग fract(). उदाहरण के लिए:

void main()
{
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    st.x *= u_resolution.x/u_resolution.y;
    
    float tiles = 5.0;
    st = fract(st * tiles);

    // [...]
}

आपके उदाहरण में आपको दायर की गई दूरी की गणना को थोड़ा अनुकूलित करना होगा (0.3 -> 0.32):

// Make Distance Field
d = length(abs(st)-.32);
d = length(min(abs(st)-.32, 0.));

अपने प्रश्न से खंड शेडर का उपयोग करके वेबजीएल उदाहरण देखें:

(function loadscene() {    

var canvas, gl, vp_size, prog, bufObj = {};

function initScene() {

    canvas = document.getElementById( "ogl-canvas");
    gl = canvas.getContext( "experimental-webgl" );
    if ( !gl )
      return;

    progDraw = gl.createProgram();
    for (let i = 0; i < 2; ++i) {
        let source = document.getElementById(i==0 ? "draw-shader-vs" : "draw-shader-fs").text;
        let shaderObj = gl.createShader(i==0 ? gl.VERTEX_SHADER : gl.FRAGMENT_SHADER);
        gl.shaderSource(shaderObj, source);
        gl.compileShader(shaderObj);
        let status = gl.getShaderParameter(shaderObj, gl.COMPILE_STATUS);
        if (!status) alert(gl.getShaderInfoLog(shaderObj));
        gl.attachShader(progDraw, shaderObj);
        gl.linkProgram(progDraw);
    }
    status = gl.getProgramParameter(progDraw, gl.LINK_STATUS);
    if ( !status ) alert(gl.getProgramInfoLog(progDraw));
    progDraw.inPos = gl.getAttribLocation(progDraw, "inPos");
    progDraw.u_time = gl.getUniformLocation(progDraw, "u_time");
    progDraw.u_resolution = gl.getUniformLocation(progDraw, "u_resolution");
    gl.useProgram(progDraw);

    var pos = [ -1, -1, 1, -1, 1, 1, -1, 1 ];
    var inx = [ 0, 1, 2, 0, 2, 3 ];
    bufObj.pos = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, bufObj.pos );
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( pos ), gl.STATIC_DRAW );
    bufObj.inx = gl.createBuffer();
    bufObj.inx.len = inx.length;
    gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufObj.inx );
    gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( inx ), gl.STATIC_DRAW );
    gl.enableVertexAttribArray( progDraw.inPos );
    gl.vertexAttribPointer( progDraw.inPos, 2, gl.FLOAT, false, 0, 0 ); 
    
    gl.enable( gl.DEPTH_TEST );
    gl.clearColor( 0.0, 0.0, 0.0, 1.0 );

    window.onresize = resize;
    resize();
    requestAnimationFrame(render);
}

function resize() {
    //vp_size = [gl.drawingBufferWidth, gl.drawingBufferHeight];
    vp_size = [window.innerWidth, window.innerHeight];
    //vp_size = [256, 256]
    canvas.width = vp_size[0];
    canvas.height = vp_size[1];
}

function render(deltaMS) {

    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
   
    gl.uniform1f(progDraw.u_time, deltaMS/1000.0);
    gl.uniform2f(progDraw.u_resolution, canvas.width, canvas.height);
    gl.drawElements( gl.TRIANGLES, bufObj.inx.len, gl.UNSIGNED_SHORT, 0 );
    
    requestAnimationFrame(render);
}  

initScene();

})();
<script id="draw-shader-vs" type="x-shader/x-vertex">
#version 100
//precision mediump float;

attribute vec2 inPos;

//varying vec2 ndcPos;

void main()
{
    //ndcPos = inPos;
    gl_Position = vec4( inPos.xy, 0.0, 1.0 );
}
</script>

<script id="draw-shader-fs" type="x-shader/x-fragment">
precision mediump float;

//varying vec2 ndcPos;  // normaliced device coordinates in range [-1.0, 1.0]
uniform float u_time;
uniform vec2 u_resolution;

void main()
{
    vec2 st = gl_FragCoord.xy/u_resolution.xy;
    st.x *= u_resolution.x/u_resolution.y;
    
    float tiles = 5.0;
    st = fract(st * tiles);
    
    vec3 color = vec3(0.0);
    float d = 0.0;

    // Remap space to -1 to 1.
    st = st *2.-1.;

    // Make Distance Field
    d = length(abs(st)-.32);
    d = length(min(abs(st)-.32, 0.));

    // Visualize the Distance Field
    gl_FragColor = vec4(vec3(fract(d*10.0)), 1.0);

    // Draw with the distance field
    gl_FragColor = vec4(vec3(step(.3, d)), 1.0);
}
</script>

<canvas id="ogl-canvas" style="border: none"></canvas>
1
Rabbid76 27 सितंबर 2020, 08:08