gl-fragcoord-xy-values.html (5268B)
1 <!-- 2 Copyright (c) 2019 The Khronos Group Inc. 3 Use of this source code is governed by an MIT-style license that can be 4 found in the LICENSE.txt file. 5 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>gl-fragcoord Test</title> 12 <link rel="stylesheet" href="../../../resources/js-test-style.css"/> 13 <script src="../../../js/js-test-pre.js"></script> 14 <script src="../../../js/webgl-test-utils.js"> </script> 15 </head> 16 <body> 17 <canvas id="canvas" width="32" height="32"> 18 </canvas> 19 <div id="description"></div> 20 <div id="console"></div> 21 <script id="vshader" type="x-shader/x-vertex"> 22 // Inputs 23 attribute vec4 aPosInfo; 24 25 // Outputs 26 varying vec2 vTargetPixelCoord; 27 28 void main() 29 { 30 vTargetPixelCoord = aPosInfo.zw; 31 32 gl_PointSize = 1.0; 33 gl_Position = vec4(aPosInfo.xy, 0.0, 1.0); 34 } 35 </script> 36 37 <script id="fshader" type="x-shader/x-fragment"> 38 precision mediump float; 39 40 // Inputs 41 varying vec2 vTargetPixelCoord; 42 43 // Colors used to signal correctness 44 const vec4 red = vec4(1.0, 0.0, 0.0, 1.0); 45 const vec4 green = vec4(0.0, 1.0, 0.0, 1.0); 46 47 void main() 48 { 49 // Check pixel index 50 bool pixelIxValid = (floor(gl_FragCoord.xy) == vTargetPixelCoord); 51 52 // Check fractional part of coordinates 53 bool fracCoordValid = all(lessThan(abs(fract(gl_FragCoord.xy) - vec2(0.5)), vec2(0.0001))); 54 55 gl_FragColor = (pixelIxValid && fracCoordValid) ? green : red; 56 } 57 </script> 58 59 <script id="test_fshader" type="x-shader/x-fragment"> 60 // Shader to test if the frame buffer positions within the output pixel are different for the five render passes 61 // Pass on frame buffer position in varying, change in vertex shader : vTargetPixelCoord = aPosInfo.xy; 62 // Set test_fshader in setupProgram() 63 64 precision mediump float; 65 66 // Inputs 67 varying vec2 vTargetPixelCoord; 68 69 const vec2 pixSize = vec2(2.0/32.0, 2.0/32.0); 70 71 void main() 72 { 73 // Coordinates within a framebuffer pixel [0, 1> 74 vec2 inPixelCoord = fract(vTargetPixelCoord / pixSize); 75 76 // Create different color dependent on the position inside the framebuffer pixel 77 float r = (inPixelCoord.x < 0.4) ? 0.2 : (inPixelCoord.x > 0.6) ? 0.8 : 0.5; 78 float g = (inPixelCoord.y < 0.4) ? 0.2 : (inPixelCoord.y > 0.6) ? 0.8 : 0.5; 79 80 gl_FragColor = vec4(r, g, 0.0, 1.0); 81 } 82 </script> 83 84 <script> 85 "use strict"; 86 87 // Test if gl_FragCoord.xy values are always of the form : 88 // (first framebuffer pixel index + 0.5, second framebuffer pixel index + 0.5) 89 // (if no multisampling) 90 91 // This is done by rendering a set of points which targets either the center of the 92 // output pixel or the center of one of the quadrants 93 94 // Constants 95 var floatsPerAttribute = 4; 96 97 // Globals 98 var wtu; 99 var gl; 100 var program; 101 var vxBuffer; 102 103 // Set data for one attribute (framebuffer.xy, pixel_index.xy) 104 function setPixelData(data, dIx, xx, yy, xSize, ySize, xOffset, yOffset) 105 { 106 // Frame buffer first coordinate [-1, 1] 107 data[dIx++] = (xx + 0.5) * xSize + xOffset - 1; 108 109 // Frame buffer second coordinate [-1, 1] 110 data[dIx++] = (yy + 0.5) * ySize + yOffset - 1; 111 112 // Frame buffer pixel first index 113 data[dIx++] = xx; 114 115 // Frame buffer pixel second index 116 data[dIx++] = yy; 117 118 return dIx; 119 } 120 121 // Create attribute data 122 function createAttributeData(xOffset, yOffset) 123 { 124 // Retrieve realised dimensions of viewport 125 var widthPx = gl.drawingBufferWidth; 126 var heightPx = gl.drawingBufferHeight; 127 var pixelCount = widthPx * heightPx; 128 129 // Pixel size in framebuffer coordinates 130 var pWidth = 2 / widthPx; 131 var pHeight = 2 / heightPx; 132 var data = new Float32Array(pixelCount * floatsPerAttribute); 133 var dIx = 0; 134 for (var yy = 0; yy < heightPx; ++yy) 135 for (var xx = 0; xx < widthPx; ++xx) 136 dIx = setPixelData(data, dIx, xx, yy, pWidth, pHeight, xOffset * pWidth, yOffset * pHeight); 137 138 if (dIx !== data.length) 139 wtu.error("gl-fragcoord-xy-values.html, createAttributeData(), index not correct at end"); 140 141 return data; 142 } 143 144 // Initialize test 145 function init() 146 { 147 description("tests gl_FragCoord.xy values"); 148 149 wtu = WebGLTestUtils; 150 gl = wtu.create3DContext("canvas", { antialias: false }); 151 program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosInfo"]); 152 vxBuffer = gl.createBuffer(); 153 154 gl.bindBuffer(gl.ARRAY_BUFFER, vxBuffer); 155 gl.enableVertexAttribArray(0); 156 gl.vertexAttribPointer(0, floatsPerAttribute, gl.FLOAT, false, 0, 0); 157 } 158 159 // Render data 160 function render(xOffset, yOffset, passMsg) 161 { 162 // Set attribute data 163 var data = createAttributeData(xOffset, yOffset); 164 gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW); 165 166 gl.clear(gl.COLOR_BUFFER_BIT); 167 gl.drawArrays(gl.POINTS, 0, data.length / floatsPerAttribute); 168 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from draw"); 169 var green = [0, 255, 0, 255]; 170 wtu.checkCanvas(gl, green, passMsg); 171 } 172 173 // Run tests 174 init(); 175 render(0, 0, "green : sampling at center of output pixel is correct"); 176 render(0.25, 0.25, "green : sampling in top right quadrant of output pixel is correct"); 177 render(-0.25, 0.25, "green : sampling in top left quadrant of output pixel is correct"); 178 render( 0.25, -0.25, "green : sampling in bottom right quadrant of output pixel is correct"); 179 render(-0.25, -0.25, "green : sampling in bottom left quadrant of output pixel is correct"); 180 var successfullyParsed = true; 181 </script> 182 <script src="../../../js/js-test-post.js"></script> 183 184 </body> 185 </html>