Source code
Revision control
Copy as Markdown
Other Tools
<!--
Copyright (c) 2019 The Khronos Group Inc.
Use of this source code is governed by an MIT-style license that can be
found in the LICENSE.txt file.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>gl-fragcoord Test</title>
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
<script src="../../../js/js-test-pre.js"></script>
<script src="../../../js/webgl-test-utils.js"> </script>
</head>
<body>
<canvas id="canvas" width="32" height="32">
</canvas>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
// Inputs
attribute vec4 aPosInfo;
// Outputs
varying vec2 vTargetPixelCoord;
void main()
{
vTargetPixelCoord = aPosInfo.zw;
gl_PointSize = 1.0;
gl_Position = vec4(aPosInfo.xy, 0.0, 1.0);
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
// Inputs
varying vec2 vTargetPixelCoord;
// Colors used to signal correctness
const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);
void main()
{
// Check pixel index
bool pixelIxValid = (floor(gl_FragCoord.xy) == vTargetPixelCoord);
// Check fractional part of coordinates
bool fracCoordValid = all(lessThan(abs(fract(gl_FragCoord.xy) - vec2(0.5)), vec2(0.0001)));
gl_FragColor = (pixelIxValid && fracCoordValid) ? green : red;
}
</script>
<script id="test_fshader" type="x-shader/x-fragment">
// Shader to test if the frame buffer positions within the output pixel are different for the five render passes
// Pass on frame buffer position in varying, change in vertex shader : vTargetPixelCoord = aPosInfo.xy;
// Set test_fshader in setupProgram()
precision mediump float;
// Inputs
varying vec2 vTargetPixelCoord;
const vec2 pixSize = vec2(2.0/32.0, 2.0/32.0);
void main()
{
// Coordinates within a framebuffer pixel [0, 1>
vec2 inPixelCoord = fract(vTargetPixelCoord / pixSize);
// Create different color dependent on the position inside the framebuffer pixel
float r = (inPixelCoord.x < 0.4) ? 0.2 : (inPixelCoord.x > 0.6) ? 0.8 : 0.5;
float g = (inPixelCoord.y < 0.4) ? 0.2 : (inPixelCoord.y > 0.6) ? 0.8 : 0.5;
gl_FragColor = vec4(r, g, 0.0, 1.0);
}
</script>
<script>
"use strict";
// Test if gl_FragCoord.xy values are always of the form :
// (first framebuffer pixel index + 0.5, second framebuffer pixel index + 0.5)
// (if no multisampling)
// This is done by rendering a set of points which targets either the center of the
// output pixel or the center of one of the quadrants
// Constants
var floatsPerAttribute = 4;
// Globals
var wtu;
var gl;
var program;
var vxBuffer;
// Set data for one attribute (framebuffer.xy, pixel_index.xy)
function setPixelData(data, dIx, xx, yy, xSize, ySize, xOffset, yOffset)
{
// Frame buffer first coordinate [-1, 1]
data[dIx++] = (xx + 0.5) * xSize + xOffset - 1;
// Frame buffer second coordinate [-1, 1]
data[dIx++] = (yy + 0.5) * ySize + yOffset - 1;
// Frame buffer pixel first index
data[dIx++] = xx;
// Frame buffer pixel second index
data[dIx++] = yy;
return dIx;
}
// Create attribute data
function createAttributeData(xOffset, yOffset)
{
// Retrieve realised dimensions of viewport
var widthPx = gl.drawingBufferWidth;
var heightPx = gl.drawingBufferHeight;
var pixelCount = widthPx * heightPx;
// Pixel size in framebuffer coordinates
var pWidth = 2 / widthPx;
var pHeight = 2 / heightPx;
var data = new Float32Array(pixelCount * floatsPerAttribute);
var dIx = 0;
for (var yy = 0; yy < heightPx; ++yy)
for (var xx = 0; xx < widthPx; ++xx)
dIx = setPixelData(data, dIx, xx, yy, pWidth, pHeight, xOffset * pWidth, yOffset * pHeight);
if (dIx !== data.length)
wtu.error("gl-fragcoord-xy-values.html, createAttributeData(), index not correct at end");
return data;
}
// Initialize test
function init()
{
description("tests gl_FragCoord.xy values");
wtu = WebGLTestUtils;
gl = wtu.create3DContext("canvas", { antialias: false });
program = wtu.setupProgram(gl, ["vshader", "fshader"], ["aPosInfo"]);
vxBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vxBuffer);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, floatsPerAttribute, gl.FLOAT, false, 0, 0);
}
// Render data
function render(xOffset, yOffset, passMsg)
{
// Set attribute data
var data = createAttributeData(xOffset, yOffset);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, data.length / floatsPerAttribute);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors from draw");
var green = [0, 255, 0, 255];
wtu.checkCanvas(gl, green, passMsg);
}
// Run tests
init();
render(0, 0, "green : sampling at center of output pixel is correct");
render(0.25, 0.25, "green : sampling in top right quadrant of output pixel is correct");
render(-0.25, 0.25, "green : sampling in top left quadrant of output pixel is correct");
render( 0.25, -0.25, "green : sampling in bottom right quadrant of output pixel is correct");
render(-0.25, -0.25, "green : sampling in bottom left quadrant of output pixel is correct");
var successfullyParsed = true;
</script>
<script src="../../../js/js-test-post.js"></script>
</body>
</html>