2017-01-15 9 views
0

심플 렉스 노이즈를 사용하여 절차 적으로 구의 표면을 생성하려고 시도했지만 부드럽고 왜곡되지 않은 노이즈를 얻으려면 각 uv 픽셀을 다음과 같이 매핑해야한다고 생각했습니다. xyz 좌표. 포인트가 연속 보면 생성하는 동안 텍스처 솔기 주변의 심각한 왜곡이,2D uv 점을 3D xyz 영역에 부드럽게 매핑

function convert2d3d(r1, r2, x, y) { 
    let z = -1 + 2 * x/r1; 
    let phi = 2 * Math.PI * y/r1; 
    let theta = Math.asin(z); 
    return { 
     x: r2 * Math.cos(theta) * Math.cos(phi), 
     y: r2 * Math.cos(theta) * Math.sin(phi), 
     z: r2 * z, 
    } 
} 

및 텍스처가 가장 뻗어된다 : 나는 다음과 같은 것을 나의 마음에 드는으로, 몇 가지 다른 알고리즘을 시도

simplex noise

나는 UV 매핑이라고 불리는 것을 알고 있지만, 올바르게 구현하는 데 어려움을 겪고 있습니다. 심각한 왜곡, 또는 못생긴 이음새가 발생합니다. 구체를 렌더링하려면 Three.JS MeshPhongMaterial을 사용하고 있으며 노이즈는 noisejs입니다.

답변

1

THIS 같은 것을 원하십니까?
오른쪽 상단의 gui에서 장면 -> 기하학이 구체를 선택합니다.

의 UV :

이 위에 링크 된 데모에서

버텍스 쉐이더로 엉망 필요가 없습니다 : 위의 링크 된 데모에서

varying vec3 vPosition; 
void main() { 
    vPosition = normalize(position); 
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0); 
} 

조각 쉐이더 :

varying vec3 vPosition; 
uniform float scale; 

// 
// Description : Array and textureless GLSL 2D/3D/4D simplex 
//    noise functions. 
//  Author : Ian McEwan, Ashima Arts. 
// Maintainer : ijm 
//  Lastmod : 20110822 (ijm) 
//  License : Copyright (C) 2011 Ashima Arts. All rights reserved. 
//    Distributed under the MIT License. See LICENSE file. 
//    https://github.com/ashima/webgl-noise 
// 

vec3 mod289(vec3 x) { 
    return x - floor(x * (1.0/289.0)) * 289.0; 
} 

vec4 mod289(vec4 x) { 
    return x - floor(x * (1.0/289.0)) * 289.0; 
} 

vec4 permute(vec4 x) { 
    return mod289(((x*34.0)+1.0)*x); 
} 

vec4 taylorInvSqrt(vec4 r) 
{ 
    return 1.79284291400159 - 0.85373472095314 * r; 
} 

float snoise(vec3 v) 
    { 
    const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; 
    const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); 

// First corner 
    vec3 i = floor(v + dot(v, C.yyy)); 
    vec3 x0 = v - i + dot(i, C.xxx) ; 

// Other corners 
    vec3 g = step(x0.yzx, x0.xyz); 
    vec3 l = 1.0 - g; 
    vec3 i1 = min(g.xyz, l.zxy); 
    vec3 i2 = max(g.xyz, l.zxy); 

    // x0 = x0 - 0.0 + 0.0 * C.xxx; 
    // x1 = x0 - i1 + 1.0 * C.xxx; 
    // x2 = x0 - i2 + 2.0 * C.xxx; 
    // x3 = x0 - 1.0 + 3.0 * C.xxx; 
    vec3 x1 = x0 - i1 + C.xxx; 
    vec3 x2 = x0 - i2 + C.yyy; // 2.0*C.x = 1/3 = C.y 
    vec3 x3 = x0 - D.yyy;  // -1.0+3.0*C.x = -0.5 = -D.y 

// Permutations 
    i = mod289(i); 
    vec4 p = permute(permute(permute( 
      i.z + vec4(0.0, i1.z, i2.z, 1.0)) 
      + i.y + vec4(0.0, i1.y, i2.y, 1.0)) 
      + i.x + vec4(0.0, i1.x, i2.x, 1.0)); 

// Gradients: 7x7 points over a square, mapped onto an octahedron. 
// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) 
    float n_ = 0.142857142857; // 1.0/7.0 
    vec3 ns = n_ * D.wyz - D.xzx; 

    vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) 

    vec4 x_ = floor(j * ns.z); 
    vec4 y_ = floor(j - 7.0 * x_); // mod(j,N) 

    vec4 x = x_ *ns.x + ns.yyyy; 
    vec4 y = y_ *ns.x + ns.yyyy; 
    vec4 h = 1.0 - abs(x) - abs(y); 

    vec4 b0 = vec4(x.xy, y.xy); 
    vec4 b1 = vec4(x.zw, y.zw); 

    //vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0; 
    //vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0; 
    vec4 s0 = floor(b0)*2.0 + 1.0; 
    vec4 s1 = floor(b1)*2.0 + 1.0; 
    vec4 sh = -step(h, vec4(0.0)); 

    vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; 
    vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; 

    vec3 p0 = vec3(a0.xy,h.x); 
    vec3 p1 = vec3(a0.zw,h.y); 
    vec3 p2 = vec3(a1.xy,h.z); 
    vec3 p3 = vec3(a1.zw,h.w); 

//Normalise gradients 
    vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); 
    p0 *= norm.x; 
    p1 *= norm.y; 
    p2 *= norm.z; 
    p3 *= norm.w; 

// Mix final noise value 
    vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); 
    m = m * m; 
    return 42.0 * dot(m*m, vec4(dot(p0,x0), dot(p1,x1), 
           dot(p2,x2), dot(p3,x3))); 
    } 

void main() { 
    float n = snoise(vPosition * scale); 
    gl_FragColor = vec4(1.0 * n, 1.0 * n, 1.0 * n, 1.0); 
} 

은 위 소요 scale float 유형의 유니폼.

function convert2d3d(r, x, y) { 
    let lat = y/r * Math.PI - Math.PI/2; 
    let long = x/r * 2 * Math.PI - Math.PI; 

    return { 
     x: Math.cos(lat) * Math.cos(long), 
     y: Math.sin(lat), 
     z: Math.cos(lat) * Math.sin(long), 
    } 
} 

R × 크기 R의 사각형 질감에 포인트를 지정해 : 텍스처 대 프로와 WebGL이의 단점을 무게

var uniforms = { 
    scale: { type: "f", value: 10.0 } 
}; 

ShaderMaterial demos

+0

좋은 대답입니다. WebGL을 Three.JS와 함께 사용하는 것을 고려하지 않았습니다. 가능한 한 생각조차하지 않아서, 따라서 회선을 고려한 것입니다. 지금은 자바 스크립트에서 데이터를보다 쉽게 ​​사용할 수 있으므로 텍스처를 생성하는 작업을 계속 진행할 것입니다. 내가 아는 한 WebGL을 사용하면 임의 액세스가 어려울 수 있습니다. –

+1

[이 매트릭스 쉐이더] (http://blog.2pha.com/demos/threejs/shaders/matrix.html)의 값으로 플레이 할 때 볼 수있는 것처럼 유니폼을 통해 쉐이더에 데이터를 보내는 것은 쉽습니다 애니메이션 효과를 사용하면 성능이 훨씬 향상됩니다. – 2pha

1

, 나는 다음과 같은 기능을 사용하여 결정 , 위도/경도로 변환하여 텍스처가 반경 1의 구에 매핑되는 3D 좌표를 반환합니다.

나는 함수를 a blog post on inear.se 그것을 통해도를 사용하도록 변환합니다. 나는 대안을 보여준 답이없고, 내가 필요한 것을 찾도록 도와주는 2phas 응답이 없다면 그것을 관리하지 않을 것이다. 그것은 추한 지금

green-black globe

을, 그러나 이것은 첫 번째 단계였다 : 여기 모습입니다.