У меня есть сетка, в которой я использую 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);
Ниже приводится результат.
У меня есть отдельный код подповерхностного рассеяния для сетки. Ниже мой код.
<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,
});
Ниже приводится результат, который я получаю при рассеянии подповерхностного слоя.
Теперь я пытаюсь объединить эти два. Я попробовал THREE.UniformsUtils.merge, чтобы объединить обе формы, и я уверен, что способ, которым я совмещал вершинные и фрагментарные шейдерные коды, неверен. Начиная с его строки, которую я просто копировал в обоих тегах сценария, и я не уверен, что это правильный способ сделать это. Так это возможно в первую очередь? Если да, то может ли кто-нибудь направить меня на это. У меня есть достаточное количество знаний с javascript, и я начал набирать 3JS, но имел нулевые знания, когда дело доходило до открытия GL.
Любая помощь приветствуется.
спасибо.
Благодарим вас за подробное объяснение. Я проверил пример с pixelnerve erlier, и у меня есть ваш проект, чтобы экспериментировать с шейдерами фрагментов. Я достиг точки, в которой я могу добавить нормальные текстуры с подповерхностным рассеянием, но трудно установить рельефную и зеркальную карту. Есть ли ссылки, которые вы можете предложить для этого? –
@AniketBetkikar ahh, я вижу, что вы имеете в виду вот это http://softimage.wiki.softimage.com/xsidocs/mat_sss_shaders_AddingBumpandDisplacementMaps.htm Изображение коровы с рельефной картой уверено, что это выполнимо, вы можете исследовать это или в воскресенье попробуйте обновить тот же git для шейдера. –