Realistic Neck Tattoo Binding
After the tutorial article from Maxim Kuzlin here, I realized that I was not satisfied with the implementation of the neck tattoo, I wanted it to look more realistic. That when you turn your head and distort the neck tattoo would also stretch and turn (Like on photos).
After some research around I found great tutorial from modelsbymike3d and reached a more or less satisfying result.
First of all, we need to create a neck binding with bones. I used Blender.
Then I used the great template from Maxim Kuzlin and reworked it a bit.
Placing our 3D neck binder object in the head binder we need to pull the bones behind it.
After that we will add a script to the bones hierarchy (Bone object) to make the neck binding repeat the movement of the head and the size of the tattoo was always the same.
// @input SceneObject sourceObject
// @input bool bindPosition
// @input bool bindScale
if (!script.sourceObject) {
print("ERROR: Source object to copy transform from is not set");
return;
}
var sceneObject = script.getSceneObject();
var transform = sceneObject.getTransform();
var bindedTransform = script.sourceObject.getTransform();
var initPosition = transform.getLocalPosition();
var initScale = transform.getLocalScale();
script.createEvent("UpdateEvent").bind(onUpdate);
function onUpdate() {
applyTransform();
}
function applyTransform() {
if (script.bindScale) {
var scale = bindedTransform.getWorldScale();
transform.setWorldScale(scale.mult(initScale));
}
if (script.bindPosition) {
var position = bindedTransform.getWorldPosition();
transform.setWorldPosition(position.add(initPosition));
}
}
And also, let's add the script of turns for the bone we need (in my case bone 002). In this way, the neck binder will repeat the movement of the neck. This script i found from modelsbymike3d and adjust it a bit. (Dont forget turn the value of Smooth speed to 1)
// -----JS CODE-----
// @input SceneObject target
// @input vec3 offset
// @input float smoothSpeed = 0.05
var transform = script.getTransform();
if (script.target) {
var targetTransform = script.target.getTransform();
} else {
print("SmoothFollow.js: Please assign the target");
}
//Bind Position
function onUpdateEvent(eventData) {
if (script.target) {
var desiredPosition = targetTransform.getWorldPosition().add(script.offset);
var smoothedPosition = vec3.lerp(
transform.getWorldPosition(),
desiredPosition,
script.smoothSpeed
);
transform.setWorldPosition(smoothedPosition);
}
}
//Bind Rotation
function onUpdateEvent(eventData) {
if (script.target) {
var desiredRotation = targetTransform.getWorldRotation();
var smoothedRotation = quat.lerp(
transform.getWorldRotation(),
desiredRotation,
script.smoothSpeed
);
transform.setWorldRotation(smoothedRotation);
}
}
var event = script.createEvent("UpdateEvent");
event.bind(onUpdateEvent);
In both scripts, we add a head binder to the SorceObject (in my case, it's a Pivot).
It remains only to attach the tattoo texture to our 3d object. I used a 1024x1024 texture and just matched the picture as I needed in photoshop.
After that you can apply face tattoo, grain, post effect and even beard ;)
If you have any questions don't hesitate to ask.
Since I'm not good with code, it doesn't look very acceptable but it works :)
If you have any suggestions on how to optimize the code, I would appreciate it.
Also, you can try it here
Thanks for your attention.
Fantastic work! I tried it out and it works extremely well.
modelsbymike3d thank you man! deeply appreciate. and thanx for your tutorial ;)
This looks great! Thank you for sharing. I'm eager to try this out tomorrow :)
Maya🦋 Thank you!
Great job man I appreciate 👍🏻 Jorik Rosa
Great job, Thanks
Jasnoor Singh🔺 Maha thank you guys
Awesome tutorial keep it up bro ✨
Shcreation4 thank you!!! Ill do my best
Jorik Rosa Such a great tut! Could you include the bones file for those of us who have very little experience in that department?