0

I'm writing a vertex displacement shader. I successfully mapped the vertices of a plane to the brightness values of a video with a GLSL Shader and Three.js, but the GLSL Shader is mapping the values in a radial fashion which might be appropriate for texturing a sphere, but not this plane. There is radial distortion coming from the center outward. How do I fix this radial distortion?

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 );
4

1 回答 1

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,除非你将它向后/向前移动。如果将 1.0 添加到 position.z ,它将移动到远平面,如果从 position.z 减去 1.0,它将移动到近平面。

于 2013-09-10T23:57:16.847 回答