three.js - 为什么我在 Three.js 中实现的置换贴图会断开球体极点处的顶点?

标签 three.js shader glsles

我试图通过将带有柏林噪声的置换贴图应用于球体来创建小行星。除了球体的两极扭曲之外,一切都按预期工作。看起来好像极点上的顶点是断开的。

前 View :看起来符合预期
Asteroid frontview
俯 View :看起来很丑;-)
Asteroid topview

起初,我认为这与我的置换贴图以及我将其应用于球面这一事实有关,但如果我将其应用于立方体,则面之间也会存在间隙。

我不确定,我能做些什么来弥补这些差距。在后面的步骤中,置换贴图一般应该通过渲染到纹理并使用随机种子生成噪声,因此我不能使用 Blender 或 Photoshop 等外部程序来修改置换贴图。我在着色器中做错了什么,还是这是“正常”行为?我能做些什么来避免这种情况吗?我读过立方体贴图。这可能是一个解决方案吗?如果是这样,是否有适用于 Three.js r57 或更高版本的工作示例?

这是我的着色器代码:

 vertexShader: [
    'uniform sampler2D displacementMap;',
    'varying vec3 vColor;',

    'void main() {',
        'vec4 newVertexPos;',
        'vec4 dv;',
        'float df;',

        'dv = texture2D( displacementMap, uv.xy );',
        'df = 0.30*dv.x + 0.59*dv.y + 0.11*dv.z;',
        '//newVertexPos = vec4(normal * df * 1.0, 0.0) + vec4( position, 1.0 );',
        'newVertexPos = vec4( normalize( position ) * df * 1.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" )

这是制服和球体代码:
asteroidMaterial = new THREE.ShaderMaterial( {
    uniforms: {
        //"displacementMap": { type: "t", value: rtTexture },
        "displacementMap": { type: "t", value: THREE.ImageUtils.loadTexture( 'txt/asteroid1.png' ) },
    },
    vertexShader: asteroidShader.vertexShader,
    fragmentShader: asteroidShader.fragmentShader,
    blending: THREE.NormalBlending,
    depthWrite: false,
    depthTest: true,
    transparent: true,
    overdraw: true,
    //wrapS: THREE.RepeatWrapping,
    //wrapT: THREE.RepeatWrapping,
    minFilter: THREE.NearestFilter,
    magFilter: THREE.NearestFilter,
} );
var asteroidGeometry = new THREE.IcosahedronGeometry( 100, 4 );
asteroidGeometry.dynamic = true;
var asteroid = new THREE.Mesh( asteroidGeometry, asteroidMaterial );
asteroid.position = new THREE.Vector3( 0, 0, 200 );
asteroid.visible = true;
scene.add( asteroid );

我刚刚看到,代码使用二十面体而不是球体,但同样的事情也发生在球体上。

最佳答案

请勿使用 IcosahedronGeometry ,是buggy在 r.57。使用 SphereGeometry , 反而。

问题是你的置换贴图。看起来你在整个接缝处都有间隙。

要修复垂直接缝,置换贴图右边缘的值必须与其左边缘的值相同。

要固定极点,顶部边缘必须具有恒定值,底部边缘必须具有恒定值。

关于three.js - 为什么我在 Three.js 中实现的置换贴图会断开球体极点处的顶点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15876848/

相关文章:

shader - 浮点均匀舍入是否存在 GLSL 问题

ios - 前两个片段着色器输出不同

javascript - aframe raycaster 可以定制成这样吗

javascript - Three.js - ply 文件 - 为什么是无色的?

c++ - 如果我将 glUniform1f 调用放在渲染循环之前,则不会存储统一值

graphics - 从计算着色器访问帧缓冲区

c++ - 由于缺乏对纹理坐标的理解,场景体素化不起作用

javascript - 将纹理添加到自定义 Three.js 几何体

javascript - 在 Three.js 中从 Base64 加载纹理

opengl - 将 GL ES 2.0 着色器移植到桌面 GLSL(我应该吗?)