我正在编写一个顶点置换着色器。我成功地将平面的顶点映射到具有GLSL着色器和Three.js的视频的亮度值,但GLSL着色器以径向方式映射值,这可能适合于纹理化球体,但不适用于此平面。中心向外有径向扭曲。如何修复此径向扭曲?
RuttEtraShader = {
uniforms: {
"tDiffuse": { type: "t", value: null },
"opacity": { type: "f", value: 1.0 }
},
vertexShader: [
'uniform sampler2D tDiffuse;',
'varying vec3 vColor;',
"varying vec2 vUv;",
'void main() {',
'vec4 newVertexPos;',
'vec4 dv;',
'float df;',
"vUv = uv;",
'dv = texture2D( tDiffuse, vUv.xy );',
'df = 1.33*dv.x + 1.33*dv.y + 16.33*dv.z;',
'newVertexPos = vec4( normalize(position) * df * 10.3, 0.0 ) + vec4( position, 1.0 );',
'vColor = vec3( dv.x, dv.y, dv.z );',
'gl_Position = projectionMatrix * modelViewMatrix * newVertexPos;',
'}'
].join("\n"),
fragmentShader: [
'varying vec3 vColor;',
'void main() {',
'gl_FragColor = vec4( vColor.rgb, 1.0 );',
'}'
].join("\n")
};
texture = new THREE.Texture( video );
texture.minFilter = THREE.LinearFilter;
texture.magFilter = THREE.LinearFilter;
texture.format = THREE.RGBFormat;
texture.generateMipmaps = true;
videoMaterial = new THREE.ShaderMaterial( {
uniforms: {
"tDiffuse": { type: "t", value: texture },
},
vertexShader: RuttEtraShader.vertexShader,
fragmentShader: RuttEtraShader.fragmentShader,
depthWrite: false,
depthTest: true,
transparent: true,
overdraw: false
} );
videoMaterial.renderToScreen = true;
geometry = new THREE.PlaneGeometry(720, 480, 720, 480);
geometry.overdraw = false;
geometry.dynamic = true;
mesh = new THREE.Mesh( geometry, videoMaterial );
mesh.position.x = 0;
mesh.position.y = 0;
mesh.position.z = 0;
mesh.visible = true;
scene.add( mesh );
答案 0 :(得分:1)
由于您使用相对于标准化设备坐标(NDC)中的点(0,0,0)的方向向量,您的位移从屏幕中心辐射。
如果不重新定义任何矩阵,您可以使用newVertexPos = vec4( normalize(position - origin) * df * 10.3, 0.0 ) + vec4( position, 1.0 );
来解决此问题,其中origin
是您想要辐射的点。在NDC中,vec3 origin = vec3 (-1.0,-1.0,0.0)
将从左下角辐射出所有内容。
但是,如果仅进行此更改,仍会有非常明显的径向位移。您可能会考虑的另一件事是使用非均匀缩放的位移。您可以使用* df * 10.3
而不是* df * vec3 (1.0, 1.0, 10.3)
。这将使Z位移 更加明显。
您可以混合使用这两种方法来找到最佳效果。我怀疑增加Z位移的比例会产生你想要的结果,但是理解为什么位移从屏幕中心辐射出来总是有帮助的。
我感觉你的飞机可能位于Z = 0,所以除非你向前/向前移动,否则Z位移总是为0。如果你向position.z添加1.0,它会将它移动到far平面,如果你从position.z中减去1.0,它会将它移动到近平面。