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 体积固定步长光线行进中的抖动_Three.js_Glsl_Webgl_Shader - Fatal编程技术网

Three.js 体积固定步长光线行进中的抖动

Three.js 体积固定步长光线行进中的抖动,three.js,glsl,webgl,shader,Three.js,Glsl,Webgl,Shader,我的着色器遇到了一个bug。对于顶点: varying vec3 worldPosition; varying vec3 viewDirection; void main() { gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); worldPosition = vec3(modelMatrix * vec4(position, 1.0)); viewDirection = n

我的着色器遇到了一个bug。对于顶点:

varying vec3 worldPosition;
varying vec3 viewDirection;

void main() {
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);

    worldPosition = vec3(modelMatrix * vec4(position, 1.0));
    viewDirection = normalize(worldPosition - cameraPosition);

}
对于片段:

uniform float time;
varying vec3 worldPosition;
varying vec3 viewDirection;

/// utilities

bool sphereHit (vec3 p)
{
    return distance(p,vec3(0,0,0)) < 1.0;
}

#define STEP_SIZE 0.01

bool raymarchHit (vec3 in_position, vec3 direction)
{
    for (int i = 0; i < 2000; i++)
    {
    if ( sphereHit(in_position) )
        return true;

        in_position += direction * STEP_SIZE;
    }
    return false;
}

void main() {
    if(raymarchHit(worldPosition, viewDirection)){
        gl_FragColor = vec4(1.0,0.0,0.0,1.0); 
    }else{
        gl_FragColor = vec4(0.0,0.0,1.0,0.5); 
    }


}
统一浮动时间;
不同的世界地位;
改变方向;
///公用事业
boolspherehit(vec3p)
{
返回距离(p,vec3(0,0,0))<1.0;
}
#定义步长大小0.01
布尔-雷马尔希特(vec3处于_位置,vec3方向)
{
对于(int i=0;i<2000;i++)
{
if(球形(在位置))
返回true;
在位置+=方向*步长;
}
返回false;
}
void main(){
if(raymarchHit(世界位置,视图方向)){
gl_FragColor=vec4(1.0,0.0,0.0,1.0);
}否则{
gl_FragColor=vec4(0.0,0.0,1.0,0.5);
}
}

我正试图设置一个光线推进着色器,所以我将其附加到一个旋转立方体上,以3J为单位,但不是一个固定的、面向摄影机的球体/圆,这是我的目标,我似乎得到了一个球体,该球体似乎因立方体的旋转而抖动(但实际上,包含网格本身的体积不应该真的很重要,对吗?)。我无法确定原因。

问题是由原因造成的,因为(来自)

可变变量按顶点设置,并以透视正确的方式进行插值 在正在渲染的基本体上

要使算法正常工作,必须插值光线的方向
noperspective

由于GLSL ES 1.00不提供,因此您必须找到解决方法

计算片段着色器中的光线:

void main(){
bool hit=raymarchHit(世界位置,标准化(世界位置-相机位置));
gl_FragColor=hit?vec4(1.0,0.0,0.0,1.0):vec4(0.0,0.0,1.0,0.5);
}
请参见示例:

var摄影机、场景、渲染器、网格、材质、统计信息;
类体积计量单位{
构造函数(vertexShader、fragmentShader){
this.clock=新的3.clock();
这件制服={
时间:{
类型:“float”,
价值:2.0
}
}
this.geometry=新的三个.BoxBufferGeometry(4.0、4.0、4.0);//宽度、高度、深度
this.material=新的3.ShaderMaterial({
制服:这个,制服,
fragmentShader:fragmentShader,
vertexShader:vertexShader,
透明:正确
})
this.mesh=new THREE.mesh(this.geometry,this.material);
scene.add(this.mesh);
}
更新(){
this.uniforms.time.value=this.clock.getElapsedTime();
这个.mesh.rotation.x+=0.01;
该.mesh.rotation.y+=0.01;
这个.mesh.rotation.z+=0.01;
}
}
函数init(){
//渲染器。
renderer=new THREE.WebGLRenderer();
//renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth、window.innerHeight);
//将渲染器添加到页面
document.body.appendChild(renderer.doElement);
//创建相机。
摄像头=新的三个透视摄像头(70,window.innerWidth/window.innerHeight,11000);
摄像机位置z=5;
//创建场景。
场景=新的三个。场景();
volVertexShader=`变化的HighpVec3世界位置;
//改变方向;
void main(){
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
worldPosition=vec3(modelMatrix*vec4(position,1.0));
//viewDirection=规格化(worldPosition-cameraPosition);
}`;
volFragShader=`均匀浮动时间;
不同的世界地位;
//改变方向;
///公用事业
boolspherehit(vec3p)
{
返回距离(p,vec3(0,0,0))<1.0;
}
#定义步长为0.1
布尔-雷马尔希特(vec3处于_位置,vec3方向)
{
对于(int i=0;i<100;i++)
{
if(球形(在位置))
返回true;
在位置+=方向*步长;
}
返回false;
}
void main(){
bool hit=raymarchHit(世界位置,标准化(世界位置-相机位置));
gl_FragColor=hit?vec4(1.0,0.0,0.0,1.0):vec4(0.0,0.0,1.0,0.5);
}`;
var volumetricnebulacenterpiect=新的VolumetricNebula_sp(volVertexShader,volFragShader);
//添加用于调整窗口大小的侦听器。
addEventListener('resize',onWindowResize,false);
//向页面添加统计信息。
//统计数据=新统计数据();
//document.body.appendChild(stats.dom);
函数animate(){
VolumeTricNebulaCenterPiect.update();
渲染器。渲染(场景、摄影机);
//stats.update();
请求动画帧(动画);
}
制作动画();
}
函数onWindowResize(){
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectMatrix();
renderer.setSize(window.innerWidth、window.innerHeight);
}
init()
body{padding:0;margin:0;}
画布{display:block;}

在这里添加了一个小把戏:啊,我明白了,我找到了一个临时解决办法,通过增加容器体积的顶点数,但这可以正确地修复它!谢谢