5

パーリン ノイズを含むディスプレイスメント マップを球体に適用して、小惑星を作成しようとしています。球の極が歪んでいることを除いて、すべてが期待どおりに機能します。極の頂点が切り離されているように見えます。

Frontview: 期待 小惑星の正面図 どおりに見えます 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 );

コードが球の代わりに 20 面体を使用しているのを見ましたが、球でも同じことが起こっています。

4

1 に答える 1

7

は使用しないでください。r.57 ではバグがありIcosahedronGeometryますSphereGeometry代わりにを使用してください。

問題は、ディスプレイスメント マップです。縫い目全体に隙間ができているようです。

垂直方向の継ぎ目を修正するには、ディスプレイスメント マップの右端と左端の値が同じである必要があります。

極を固定するには、上端で一定の値を持ち、下端で一定の値を持つ必要があります。

于 2013-04-08T14:21:55.973 に答える