My mesh utilizes a ShaderMaterial with THREE.ShaderLib.phong uniforms. I have successfully linked the map, bump, and specular maps textures. The code snippet below demonstrates this:
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);
View the outcome https://i.sstatic.net/eSaCO.png.
Additionally, I have implemented separate subsurface scattering code for the mesh. The following code snippet demonstrates this:
<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>
The basic code referenced from Shader - Simple SSS lighting issue, paired with the material code:
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,
});
See the result of subsurface scattering https://i.sstatic.net/zWkHS.png.
Now, I am attempting to combine these two functionalities. While trying to merge the uniforms using THREE.UniformsUtils.merge, I suspect that my approach to combining the vertex and fragment shader codes might be incorrect. As they are strings, I directly copied and pasted them within script tags, unsure if this is the correct method. Is it even feasible to combine them in this manner? If so, could someone provide guidance on this matter? Although I have a decent understanding of JavaScript and have begun delving into Three.js, I lack knowledge in openGL.
Any assistance would be greatly appreciated.
Thank you.