根据khronos group documentation,gl_FragCoord
指定要被着色像素 内的任何位置。
下面,我有一个着色器,可根据像素的模2对着色器着色。我们可以期望看到一种类似于棋盘格的细粒度图案,其中每个像素的颜色都不同于其相邻像素。但是,看起来大多数像素的gl_FragCoord.xy
并不是以像素为单位的坐标,而是看起来该值是一个非整数,它是像素的 scaling 坐标。
var canvas;
var scene;
var renderer;
var camera;
var shader;
var quad;
function init() {
let div = document.getElementById('div');
let newCanvas = document.createElement('CANVAS');
newCanvas.id = 'canvas';
let height = 360;
newCanvas.style.height = height + 'px';
let width = 1440;
newCanvas.style.width = width + 'px';
newCanvas.style.backgroundColor = 'black';
newCanvas.style['border-radius'] = '12px';
div.appendChild(newCanvas);
div.appendChild(document.createElement('BR'));
canvas = document.getElementById('canvas');
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({canvas: canvas});
camera = new THREE.OrthographicCamera(-0.5*width, 0.5*width, -0.5*height, 0.5*height, 1, 1000);
shader = new THREE.ShaderMaterial({
vertexShader: 'void main() { gl_Position = vec4(position,1); }',
fragmentShader: 'void main(){ gl_FragColor = vec4(mod(gl_FragCoord.xy, 2.0), 0, 1); }'
});
quad = new THREE.Mesh(new THREE.PlaneGeometry(width, height), shader);
scene.add(quad);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
var button = document.getElementById('start');
button.onclick = function() { init(); animate(); }
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.js"></script>
<div align="center" id="div">
<button type="button" id="start" class="button" >Start</button>
</div>
</body>
</html>
我使用了一个非常宽的画布,并且在单击按钮后将该画布附加到了文档上,这似乎很奇怪,但这是在我正在开发的应用程序中实现的方式,所以我认为也许这些功能可能以某种方式导致了问题。
这是一个我从未遇到过的奇怪问题,因此我还没有真正想出任何方法来调试它。到目前为止,我唯一尝试过的操作就是更改四边形的高度和宽度,但这丝毫没有改变输出。
答案 0 :(得分:0)
我知道了!问题很简单:渲染器未设置为正确的大小(我以为默认大小是画布的大小,但是显然我错了。)
添加
renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
渲染器声明解决后。
var canvas;
var scene;
var renderer;
var camera;
var shader;
var quad;
function init() {
let div = document.getElementById('div');
let newCanvas = document.createElement('CANVAS');
newCanvas.id = 'canvas';
let height = 360;
newCanvas.style.height = height + 'px';
let width = 1440;
newCanvas.style.width = width + 'px';
newCanvas.style.backgroundColor = 'black';
newCanvas.style['border-radius'] = '12px';
div.appendChild(newCanvas);
div.appendChild(document.createElement('BR'));
canvas = document.getElementById('canvas');
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({canvas: canvas});
renderer.setSize(canvas.clientWidth, canvas.clientHeight, false);
camera = new THREE.OrthographicCamera(-0.5*width, 0.5*width, -0.5*height, 0.5*height, 1, 1000);
shader = new THREE.ShaderMaterial({
vertexShader: 'void main() { gl_Position = vec4(position,1); }',
fragmentShader: 'void main(){ gl_FragColor = vec4(mod(gl_FragCoord.xy, 2.0), 0, 1); }'
});
quad = new THREE.Mesh(new THREE.PlaneGeometry(width, height), shader);
scene.add(quad);
}
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
var button = document.getElementById('start');
button.onclick = function() { init(); animate(); }
<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.js"></script>
<div align="center" id="div">
<button type="button" id="start" class="button" >Start</button>
</div>
</body>
</html>