2016-07-16 3 views
0

J'ai un maillage dans lequel j'utilise un ShaderMaterial et j'utilise des uniformes THREE.ShaderLib.phong. J'ai lié la carte, bosse & la texture des cartes séculaires ainsi et tout cela fonctionne très bien. Voici mon code.Combinaison de la diffusion THREE.ShaderLib.phong et subsurface dans 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); 

Voici le résultat obtenu.

enter image description here

I ont un code de diffusion du sous-sol séparé pour le maillage. Voici mon code.

<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> 

code de base Jolie je l'ai trouvé ici Shader - Simple SSS lighting issue. Et mon code matériel.

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, 
}); 

Voici le résultat obtenu avec la diffusion souterraine.

enter image description here

Maintenant, je suis en train de combiner ces deux. J'ai essayé THREE.UniformsUtils.merge de fusionner les deux uniformes et je suis assez sûr que la façon dont j'ai combiné les codes de vertex et fragment shader est fausse. Comme c'est une chaîne que je viens de copier collé à la fois dans les balises de script et je ne suis pas sûr que ce soit la bonne façon de le faire. Alors est-ce possible en premier lieu? Si oui que quelqu'un peut me guider à ce sujet. J'ai assez de connaissances avec javascript et j'ai commencé à avoir un coup de troisJS mais je n'ai aucune connaissance quand il s'agit d'ouvrir GL.

Toute aide est appréciée.

Merci.

Répondre

1

Vertex et fragment shader sont la façon dont vous parlez à votre pipeline GPU et la fusion de la chaîne deux ne donnera rien tant que vous n'avez pas vraiment compris le mécanisme derrière cela.

Donc, Phong Shading est la façon dont vous lisez le specular + diffused + ambient dans votre fragment shader pour l'ensemble des sommets sur lesquels vous voulez appliquer.

enter image description here [Source: wiki]

Maintenant Subsurface Scattering est moyen par lequel on considère l'interaction lumière dans le matériau où vous avez lu que normalement l'interaction lumière avec du matériel

enter image description here

[Source: Link]

Vous pouvez lire le Chapter-16 Nvidia cela résoudre tous les problèmes de mathématiques pour votre solution.

J'ai créé votre solution pour la diffusion sous la surface, vous pouvez commander le formulaire Git. C'est SSS basé sur la carte de profondeur. Le code est inspiré du code pixelnerve.

En bref ce que vous essayez de fusionner TROIS.Phong et Subsurface Scattering vous permettent d'étendre le même exemple de code pour votre environnement en écrivant votre fragment shader personnalisé (sommet que vous pouvez prendre directement).

+0

merci pour l'explication détaillée. J'ai vérifié l'exemple de pixelnerve erlier et j'ai utilisé votre projet pour expérimenter avec des shaders de fragments. J'ai atteint un point où je peux ajouter des textures normales avec la diffusion de subsurface mais trouver difficile de définir la carte de bosse et spéculaire. Y a-t-il des liens que vous pouvez suggérer pour cela? –

+0

@AniketBetkikar ahh je vois que vous voulez dire comme ça http://softimage.wiki.softimage.com/xsidocs/mat_sss_shaders_AddingBumpandDisplacementMaps.htm image de vache avec bump map sûr que c'est faisable, vous pouvez explorer cela ou par dimanche essayer de mettre à jour le même git lien pour le shader. –