Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 删除GLSL着色器生成的莫尔图案_Three.js_Glsl_Webgl - Fatal编程技术网

Three.js 删除GLSL着色器生成的莫尔图案

Three.js 删除GLSL着色器生成的莫尔图案,three.js,glsl,webgl,Three.js,Glsl,Webgl,我已经设置了这个最小的测试用例,您可以很容易地看到通过使用自定义片段着色器()对振荡红色进行欠采样而产生的莫尔图案 使用GLSL删除此类图案的一般技术是什么?我假设它涉及到衍生工具扩展,但我一直不太明白如何实现它。我想我基本上要做反走样 var canvas=document.getElementById('canvas'); var scene=new THREE.scene(); var renderer=new THREE.WebGLRenderer({canvas:canvas,ant

我已经设置了这个最小的测试用例,您可以很容易地看到通过使用自定义片段着色器()对振荡红色进行欠采样而产生的莫尔图案

使用GLSL删除此类图案的一般技术是什么?我假设它涉及到衍生工具扩展,但我一直不太明白如何实现它。我想我基本上要做反走样

var canvas=document.getElementById('canvas');
var scene=new THREE.scene();
var renderer=new THREE.WebGLRenderer({canvas:canvas,antialas:true});
var摄像机=新的三视角摄像机(75,canvas.clientWidth/canvas.clientWidth,11000);
var几何=新的三种。球墨法(50,50,50);
var material=新的3.ShaderMaterial({
vertexShader:document.getElementById('vertex-shader').textContent,
fragmentShader:document.getElementById('fragment-shader').textContent
});
var sphere=新的三个网格(几何体、材质);
场景。添加(球体);
摄像机位置z=100;
var周期=30;
var clock=新的三个时钟();
render();
函数render(){
请求动画帧(渲染);
if(canvas.width!==canvas.clientWidth | | canvas.height!==canvas.clientHeight){
renderer.setSize(canvas.clientWidth、canvas.clientHeight、false);
camera.aspect=canvas.clientWidth/canvas.clientHeight;
camera.updateProjectMatrix();
}
sphere.rotation.y-=clock.getDelta()*2*Math.PI/周期;
渲染器。渲染(场景、摄影机);
}
html,主体,#画布{
保证金:0;
填充:0;
宽度:100%;
身高:100%;
溢出:隐藏;
}

可变vec2 vUv;
void main(){
vUv=紫外线;
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
#定义毛头6.2831853071795864769252867665590
可变vec2 vUv;
void main(){
浮点数w=sin(500.0*M_头*vUv.x)/2.0+0.5;
vec3颜色=vec3(w,0.0,0.0);
gl_FragColor=vec4(颜色,1.0);
}

不幸的是,这里的莫尔图案是高对比度线接近边缘的结果。换句话说,没有好的方法可以让1或2像素宽的高对比度线平滑地移动到下一个像素上,而不引入这些伪影,或者使线变得模糊难以区分

你提到了导数的扩展,事实上,这个扩展可以用来计算你的UV在屏幕空间中的变化有多快,从而计算出需要多少模糊来解决这个问题。在下面示例的修改版本中,我尝试使用
fwidth
在噪声变差的地方将球体变成红色。尝试玩一些定义为常量的浮动,看看你能找到什么

var canvas=document.getElementById('canvas');
var scene=new THREE.scene();
var renderer=new THREE.WebGLRenderer({canvas:canvas,antialas:true});
var摄像机=新的三视角摄像机(75,canvas.clientWidth/canvas.clientWidth,11000);
var几何=新的三种。球墨法(50,50,50);
var material=新的3.ShaderMaterial({
vertexShader:document.getElementById('vertex-shader').textContent,
fragmentShader:document.getElementById('fragment-shader').textContent
});
var sphere=新的三个网格(几何体、材质);
场景。添加(球体);
摄像机位置z=100;
var周期=30;
var clock=新的三个时钟();
render();
函数render(){
请求动画帧(渲染);
if(canvas.width!==canvas.clientWidth | | canvas.height!==canvas.clientHeight){
renderer.setSize(canvas.clientWidth、canvas.clientHeight、false);
camera.aspect=canvas.clientWidth/canvas.clientHeight;
camera.updateProjectMatrix();
}
sphere.rotation.y-=clock.getDelta()*2*Math.PI/周期;
渲染器。渲染(场景、摄影机);
}
html,主体,#画布{
保证金:0;
填充:0;
宽度:100%;
身高:100%;
溢出:隐藏;
}

可变vec2 vUv;
void main(){
vUv=紫外线;
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
#扩展GL_OES_标准_衍生工具:启用
#定义毛头6.2831853071795864769252867665590
可变vec2 vUv;
void main(){
浮点数=200.0;
浮子厚度=0.0;
浮子混合区=2.8;
//松散地基于https://github.com/AnalyticalGraphicsInc/cesium/blob/1.16/Source/Shaders/Materials/GridMaterial.glsl#L17-L34
float scaledWidth=fract(行数*vUv.s);
scaledWidth=abs(scaledWidth-地板(scaledWidth+0.5));
vec2 dF=fwidth(vUv)*测线计数;
浮点值=1.0-平滑步长(dF.s*厚度,dF.s*(厚度+混合区域),缩放宽度);
gl_FragColor=vec4(值,0.0,0.0,1.0);
}

@WacławJasper使用uv坐标只是获得这种效果的一种简单方法。接缝本身并没有造成问题,否则您只能看到接缝本身周围的问题。谢谢您的回答!我唯一能要求的是关于这类事情的各种技术的进一步信息或文档?就我所知,这是唯一的解决方案:基于像素的显示器无法显示高于像素密度的频率。在上面的代码中,
thickness
blendregion
由于
fwidth
而在屏幕空间像素中指定,这意味着当线间距小于~3像素时,线开始重叠。如果小于这个值,那么线条只有1个像素,间距只有1个像素,当线条没有固定在像素网格上时,事情就会变得一团糟。顺便说一句,这段代码所基于的逻辑在Cozzi和Ring的《虚拟球体的3D引擎设计》一书中有更全面的描述,清单4.13。