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 如何扭曲着色器矩阵以匹配3d场景中的等轴测透视?_Three.js_Glsl_Shader_Fragment Shader_Isometric - Fatal编程技术网

Three.js 如何扭曲着色器矩阵以匹配3d场景中的等轴测透视?

Three.js 如何扭曲着色器矩阵以匹配3d场景中的等轴测透视?,three.js,glsl,shader,fragment-shader,isometric,Three.js,Glsl,Shader,Fragment Shader,Isometric,我将着色器作为纹理应用于等轴测场景中的平面。平面以x、z标注水平放置。我无法使着色器模式与场景中的等轴测透视图匹配 下面是一个示例,其中着色器通过在方向上以均匀方式传递来随平面旋转(类似于常规纹理) 以下是着色器纹理的“2d”(正交)投影: var TWO_PI=Math.PI*2; var-PI=Math.PI; 变量宽度=窗内高度-50; 变量高度=window.innerHeight-50; var aspect=宽度/高度; 可变平面尺寸=宽度*0.75; var clock=新的三个

我将着色器作为纹理应用于等轴测场景中的平面。平面以x、z标注水平放置。我无法使着色器模式与场景中的等轴测透视图匹配

下面是一个示例,其中着色器通过在方向上以均匀方式传递来随平面旋转(类似于常规纹理)

以下是着色器纹理的“2d”(正交)投影:

var TWO_PI=Math.PI*2;
var-PI=Math.PI;
变量宽度=窗内高度-50;
变量高度=window.innerHeight-50;
var aspect=宽度/高度;
可变平面尺寸=宽度*0.75;
var clock=新的三个时钟();
摄像机、场景、渲染器;
var平面、geom平面、mat平面;
函数init(){
//------现场
场景=新的三个。场景();
//-------飞机
var plane_w=平面尺寸;
var plane_h=平面尺寸;
var geom_平面=新的三个平面几何图形(平面w,
平面图,
0);
var mat_plane=新的三网格基本材料({
颜色:0xffff00,
侧面:三个。双面
});
var shaderMaterial_plane=新的3.shaderMaterial({
制服:{
决议:{
值:新的3.Vector2(planeSize,planeSize)
},
u_旋转_x:{
值:performance.now()*0.001
},
u_旋转_y:{
值:performance.now()*0.001
}
},
vertexShader:document.getElementById('vertexShader').textContent,
fragmentShader:document.getElementById('fragmentShader').textContent,
混合:3.5%混合,
深度测试:正确,
透明:正确
});
平面=新的三个网格(几何平面、着色器材质平面);
场景。添加(平面);
//-------凸轮
摄像机=新的三个正交摄像机(宽度/-2,宽度/2,高度/2,高度/-2,1,5000);
摄像机。位置。设置(0,0,平面尺寸);
摄像机。注视(场景。位置);
//-------渲染器
renderer=new THREE.WebGLRenderer({
反别名:假,
阿尔法:是的
});
设置大小(宽度、高度);
renderer.setClearColor(0x000000);
document.body.appendChild(renderer.doElement);
}
函数animate(){
请求动画帧(动画);
var time=performance.now()*0.001;
plane.material.uniforms.u_旋转_x.value=Math.sin(时间*0.2);
plane.material.uniforms.u_rotation_y.value=数学cos(时间*0.2);
var delta=clock.getDelta();
render();
}
函数render(){
渲染器。渲染(场景、摄影机);
}
init();
制作动画()

可变vec2 vUv;
void main(){
vUv=紫外线;
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
均匀vec2 u_分辨率;//画布大小(宽度、高度)
均匀浮动u_旋转_x;
均匀浮动旋转;
mat2旋转2D(矢量2_角){
返回mat2(_angles.x,
-_Angels.x,
_Angels.y,
_角度(y);
}
浮点映射(浮点值、浮点最小值1、浮点最大值1、浮点最小值2、浮点最大值2){
返回min2+(值-min1)*(max2-min2)/(max1-min1);
}
void main(){
vec2 st=gl_FragCoord.xy/u_resolution.xy;
vec3颜色=vec3(1.0,1.0,1.0);
浮动梯度长度=0.2;
浮点数t=18。;
//移动矩阵以将旋转轴心点设置为中心
st-=vec2(0.5);
//轮换
vec2 u_旋转=vec2(u_旋转x,u_旋转y);
st=旋转2d(u_旋转)*st;
//向后移动矩阵
st+=vec2(0.5);
//应用渐变图案
vec2p=vec2(楼层(gl_FragCoord.x)、楼层(gl_FragCoord.y));
浮子pp=夹具(gl_FragCoord.y,-0.5,st.y);
float val=mod((pp+t),梯度长度);
浮点alpha=贴图(val,0.0,渐变长度,1.0,0.0);
gl_FragColor=vec4(颜色,α);
}
非常有趣的问题(+1)。如何将单位圆转换为椭圆,并使用90度偏移的基向量内接在其中

忽略此处的矩阵数学GL/GLSL/C++示例:

CPU侧绘图:

//GLSL等轴测视图
浮盘[2]={0.5,0.5};
浮点u[2]={1.0,0.0};
float v[2]={0.5,0.5};
常数浮动度=M_PI/180.0;
常数浮点da=1.0*deg;;
静态浮动a=0.0;
u[0]=1.0*cos(a);
u[1]=0.5*sin(a);
v[0]=1.0*cos(a+90.0*deg);
v[1]=0.5*sin(a+90.0*deg);
a+=da;如果(a>=2.0*M_-PI)a-=2.0*M_-PI;
glUseProgram(程序id);
id=glGetUniformLocation(程序id,“缩放”);glUniform1f(id,0.5);
id=glGetUniformLocation(程序id,“pan”);glUniform2fv(id,1,pan);
id=glGetUniformLocation(程序id,“u”);glUniform2fv(id,1,u);
id=glGetUniformLocation(程序id,“v”);glUniform2fv(id,1,v);
glBegin(GL_QUADS);
gl3f(1,1,1);
浮动x=0.0,y=0.0;
glVertex2f(x+0.0,y+0.0);
glVertex2f(x+0.0,y+1.0);
glVertex2f(x+1.0,y+1.0);
glVertex2f(x+1.0,y+0.0);
格伦德();
glUseProgram(0);
顶点:

#版本120
//顶点
均匀vec2pan=vec2(0.5,0.5);//原点[网格单元]
均匀浮动缩放=0.5;//规模
均匀vec2u=vec2(1.0,0.0);//基向量
均匀vec2v=vec2(0.5,0.5);
可变vec2位置;//位置[网格单元]
void main()
{
pos=gl_顶点.xy;
vec2 a=缩放*(gl_顶点.xy平移);
gl_位置=vec4((u*a.x)+(v*a.y),0.0,1.0);
}
片段:

#版本120
//碎片
可变vec2位置;//纹理坐标
void main()
{
浮动a;
a=2.0*(位置x+y);
a-=楼层(a);
gl_FragColor=vec4(a,a,a,1.0);
}
最后预览:

重要的内容在顶点着色器中。因此,只需使用
u,v
基向量,即可通过公式将世界2D转换为等轴测2D位置:

isometric = world.x*u + world.y*v

剩下的就是
pan
zoom

解决方案非常简单。我发现我的问题是a,原文包含一个例子(也在下面解释)
uniform float width;
uniform float height;
varying float x;
varying float y;
void main() {
    // Get normalized position
    x = position.x / width;
    y = position.y / height;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
varying float x; // -0.5 to 0.5
varying float y; // -0.5 to 0.5
void main() {
    gl_FragColor = vec4(x, y, 0.0, 1.0);
}