2016-05-31 3 views
-1

Когда вы создаете сферу (на самом деле это также apolyhedron) или другой многогранник в API-интерфейсе WebGL, вы получите многогранник с плоским стилем, и вы придадите текстуре многограннику, он будет выглядеть уродливый с углом между двумя малыми гранями на многограннике. на самом деле, вы можете разделить поверхность, чтобы получить гладкую поверхность. и есть ли другой способ smooth the surface на polyhedron.just взгляд LILE как два изображения, как показано ниже. (две картины захват с помощью программного обеспечения блендер)гладкий край в программировании WebGL

polyhedron with flat style

polyhedron with smooth style

Вот мой код для создания сферы

function getSphere(r,segment_lat,segment_lon){ 
     var normalData = []; 
     var vertexData = []; 
     var textureCoord = []; 
     var vertexIndex = [], 
     for (var latNum = 0; latNum <= segment_lat; latNum++) { 
      var theta = latNum * Math.PI/segment_lat; 
      var sinTheta = Math.sin(theta); 
      var cosTheta = Math.cos(theta); 
     for (var lonNum = 0; lonNum <= segment_lon; lonNum++) { 
       var phi = lonNum * 2 * Math.PI/segment_lon; 
       var sinPhi = Math.sin(phi); 
       var cosPhi = Math.cos(phi); 
       var x = cosPhi * sinTheta; 
       var y = cosTheta; 
       var z = sinPhi * sinTheta; 
       var u = 1 - (lonNum/segment_lon); 
       var v = 1 - (latNum/segment_lat); 
       textureCoord.push(u); 
       textureCoord.push(v); 
       vertexData.push(r * x); 
       vertexData.push(r * y); 
       vertexData.push(r * z); 
      } 
     } 
     for (var latNum=0; latNum < segment_lat;latNum++) { 
      for (var lonNum=0; lonNum < segment_lon; lonNum++) { 
      var first = (latNum * (segment_lon + 1)) + lonNum; 
      var second = first + segment_lon + 1; 
      vertexIndex .push(first); 
      vertexIndex .push(second); 
      vertexIndex .push(first + 1); 
      vertexIndex .push(second); 
      vertexIndex .push(second + 1); 
      vertexIndex .push(first + 1); 
     } 
     } 
     return {'vertexData':vertexData,'vertexIndex':vertexIndex,'textureCoord':textureCoord,'normalDatas':normalData}; 
    }, 

пиксельного шейдера:

 precision mediump float; 
     varying vec2 vTextureCoord; 
     uniform sampler2D uSampler; 

     void main(void) { 
      vec3 light = vec3(1,1,1); 
      vec4 textureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)); 
      gl_FragColor = vec4(textureColor.rgb*light,textureColor.a); 
      // gl_FragColor = vec4 (1,0,0,.8); 
     } 

Vertex Shader:

 attribute vec2 aTextureCoord; 
     attribute vec3 aVertexPosition; 
     // uniform mediump mat4 proj_inv; 
     uniform mediump mat4 modelViewMatrix; 
     uniform mediump mat4 projectMatrix; 
     varying highp vec2 vTextureCoord; 

     void main(void) { 
      //projectMatrix multi modelViewMatrix must be in vertex shader,or it will be wrong; 
      gl_Position = projectMatrix*modelViewMatrix*vec4(aVertexPosition, 1.0); 
      vTextureCoord = aTextureCoord; 
     } 
+0

Использование [Затенение фонтана] (https://en.wikipedia.org/wiki/Phong_shading). –

+0

WebGL не имеет API для создания сферы. Возможно, lib. Таким образом, независимо от того, является ли эта сфера гладкой или плоской, зависит от реализации lib. –

+0

Вы не получите плоскую сферу. WebGL не имеет сфер. [WebGL - это просто библиотека растеризации] (http://webglfundamentals.org/webgl/lessons/webgl-how-it-works.html). Сферы, как показано на рисунке, требуют, чтобы вы предоставили код или использовали библиотеку. На самом деле, возможно, больше работы, чтобы получить плоские заштрихованные сферы в WebGL, чем не плоские затененные. Что вы пробовали? – gman

ответ

-1

Если я должен угадать ваш результат визуализации отличается от картины вы показали. То, что вы видите, является «плоской» сферой в одном однородном цвете, и вы хотите заштрихованную сферу, это правильно?

Если это так, вам нужно прочитать учебники о том, как работает освещение. В основном, угол между вектором просмотра и нормальным фрагментом используется для определения яркости каждого фрагмента. Фрагмент на сфере, на который вы смотрите прямо, имеет очень малый угол между вектором вида и его нормальным и, следовательно, его ярким. Фрагмент на едва видимом краю на сфере имеет большой угол между нормальным и видимым и тем самым становится темным.

В коде поколения кода вам также необходимо рассчитать нормали и передать эту информацию в gpu вместе с остальными. К счастью для сферы, нормаль легко вычислить: normal = normalize(position - center); или просто normalize(position), если предполагается, что центр находится в точке (0,0,0).

+0

О, таньоу, используйте метод, который у меня есть гладкая сфера, ThankYou – cughudson

+0

Этот ответ прост. Его (зажатый) ** косинус ** угла между нормалью поверхности и ** светом ** для [lambertian aka diffuse lighting] (https://en.wikipedia.org/wiki/Lambertian_reflectance), который * * not ** view зависимый: 'float diffuse = max (точка (нормальная, lightdir), 0.)'. Для зеркального освещения с использованием [blinn-phong] (https: //en.wikipedia.org/wiki/Blinn% E2% 80% 93Phong_shading_model) используется * наполовину вектор *, аппроксимированный нормализованным * light + view *: 'float specular = pow (max (dot (n, normalize (lightdir + view)), 0 .) specularExponent); 'Проверьте ссылку для полных реализаций. –

+0

Пожимайте плечами, вы технически верны. Но метод, который я изложил, дает желаемый эффект затенения. Основная точка, являющаяся углом между нормальным и некоторым вектором, используется для модуляции цвета каждого фрагмента. Я направил OP на осветительные обучающие программы, если он хочет внедрить более сложные модели освещения. –

Смежные вопросы