2016-07-16 1 views
0

У меня есть сетка, в которой я использую ShaderMaterial, и я использую форму TREE.ShaderLib.phong. Я связал карту, bump & текстуры секулярных карт, и все это отлично работает. Ниже мой код.Сочетание THREE.ShaderLib.phong и подповерхностного рассеяния в ThreeJS

defines = {}; 
defines[ "USE_MAP" ] = ""; 
defines[ "USE_BUMPMAP" ] = ""; 
defines["USE_SPECULARMAP"] = ""; 

    var uniforms = THREE.UniformsUtils.clone(THREE.ShaderLib.phong.uniforms); 
    uniforms.map.value = THREE.ImageUtils.loadTexture('source/images/texture-pink.jpg'); 
    uniforms.bumpMap.value = THREE.ImageUtils.loadTexture('source/images/texture-pink-bump.jpg'); 
    uniforms.bumpScale.value = 0.02; 
    uniforms.specularMap.value = THREE.ImageUtils.loadTexture('source/images/texture-pink-specular.jpg'); 

    var parameters = { 
     fragmentShader:THREE.ShaderChunk["meshphong_frag"], 
     vertexShader:THREE.ShaderChunk["meshphong_vert"], 
     defines: defines, 
     uniforms: uniforms, 
     lights: true, 
     fog: false, 
     side: THREE.DoubleSide, 
     blending: THREE.NormalBlending, 
     transparent: (uniforms.opacity.value < 1.0), 
     derivatives : true 
    }; 

    material = new THREE.ShaderMaterial(parameters); 

Ниже приводится результат.

enter image description here

У меня есть отдельный код подповерхностного рассеяния для сетки. Ниже мой код.

<script id="vertexShader" type="x-shader/x-vertex"> 
     varying vec3 v_fragmentPos; 
     varying vec3 v_normal; 

     void main() { 

       vec4 mvPositions = modelViewMatrix * vec4(position, 1.0); 
       v_fragmentPos = (modelMatrix * vec4(position, 1.0)).xyz; 
       v_normal = (modelMatrix * vec4(normal, 0.0)).xyz; 
       gl_Position = projectionMatrix * mvPositions; 
     } 
    </script> 

<script id="fragment_shader" type="x-shader/x-fragment"> 
     varying vec3 v_fragmentPos; 
     varying vec3 v_normal; 
     uniform vec3 u_lightPos; 

     void main() { 

       vec3 _LightColor0 = vec3(1.0,0.5,0.5); 
       float _LightIntensity0 = 2.5; 
       vec3 translucencyColor = vec3(0.8,0.2,0.2); 
       vec3 toLightVector = u_lightPos - v_fragmentPos; 
       float lightDistanceSQ = dot(toLightVector, toLightVector); 
       vec3 lightDir = normalize(toLightVector); 
       float ndotl = max(0.0, dot(v_normal, lightDir)); 
       float inversendotl = step(0.0, dot(v_normal, -lightDir)); 
       vec3 lightColor = _LightColor0.rgb * ndotl/lightDistanceSQ * _LightIntensity0; 
       vec3 subsurfacecolor = translucencyColor.rgb * inversendotl/lightDistanceSQ * _LightIntensity0; 
       vec3 final = subsurfacecolor + lightColor; 
       gl_FragColor=vec4(final,1.0); 
     } 
    </script> 

Довольно базовый код, который я нашел здесь Shader - Simple SSS lighting issue. И мой материальный код.

sssUniforms = { 
    u_lightPos: {type: "v3",value: new THREE.Vector3()} 
}; 

var sssMaterial = new THREE.ShaderMaterial({ 
    uniforms: sssUniforms, 
    vertexShader: document.getElementById('vertexShader').textContent, 
    fragmentShader: document.getElementById('fragment_shader').textContent, 
}); 

Ниже приводится результат, который я получаю при рассеянии подповерхностного слоя.

enter image description here

Теперь я пытаюсь объединить эти два. Я попробовал THREE.UniformsUtils.merge, чтобы объединить обе формы, и я уверен, что способ, которым я совмещал вершинные и фрагментарные шейдерные коды, неверен. Начиная с его строки, которую я просто копировал в обоих тегах сценария, и я не уверен, что это правильный способ сделать это. Так это возможно в первую очередь? Если да, то может ли кто-нибудь направить меня на это. У меня есть достаточное количество знаний с javascript, и я начал набирать 3JS, но имел нулевые знания, когда дело доходило до открытия GL.

Любая помощь приветствуется.

спасибо.

ответ

1

Vertex и фрагментарный шейдер - это способ, которым вы говорите с конвейером GPU и слияние двух строк не приведет к чему-либо, пока вы не поймете механизм этого.

Таким образом, Phong Shading - это способ, в котором вы читаете зеркальный + диффузный + ambient в свой фрагментарный шейдер для набора вершин, на которые вы хотите применить.

enter image description here [Источник: вики]

Теперь недропользованию Рассеяние способ, с помощью которого вы считаете взаимодействия света в материал, где, как правило, вы читаете свет взаимодействия с материалом

enter image description here

[Источник: Link]

Вы можете прочитать Chapter-16 Nvidia, это решит всю математическую проблему для вашего решения.

Я создал ваше решение для рассеяния подповерхностного слоя, вы можете проверить форму Git. Это SSS на основе карты глубины.

Код вдохновляет pixelnerve.

In-short, что вы пытаетесь объединить ТРИ.Phong и Subsurface Scattering вместо этого вы можете расширить один и тот же пример кода для вашей среды, записывая свой пользовательский шейдер фрагментов (вершина, которую вы можете взять непосредственно).

+0

Благодарим вас за подробное объяснение. Я проверил пример с pixelnerve erlier, и у меня есть ваш проект, чтобы экспериментировать с шейдерами фрагментов. Я достиг точки, в которой я могу добавить нормальные текстуры с подповерхностным рассеянием, но трудно установить рельефную и зеркальную карту. Есть ли ссылки, которые вы можете предложить для этого? –

+0

@AniketBetkikar ahh, я вижу, что вы имеете в виду вот это http://softimage.wiki.softimage.com/xsidocs/mat_sss_shaders_AddingBumpandDisplacementMaps.htm Изображение коровы с рельефной картой уверено, что это выполнимо, вы можете исследовать это или в воскресенье попробуйте обновить тот же git для шейдера. –