Flying Book : Sketch#55

Diablo3PukeFanArt12


For this challenge, I wanna make this:

:face_vomiting: :face_vomiting: :face_vomiting:

3 Likes

I followed along this tutorial:

and made a shader graph in unity that read the texture via uv scrolling. (The scrolling is controlled by a custom vertex stream in the particle system, my graph is specifically for making mesh particles animate.)
Here’s the skull in unity with the working animation texture shader
woo vertex animation for unity 2
and the skull in blender
PukeFaceInBlender

I’m not sure why the forehead flashes green? that doesn’t show up in my gif editor or in the softwares :confused:

Draft before timing pass and texture and stuff, just breaking the effect into piece I can work with

Draft

3 Likes

it looks very cool so far!

1 Like

1st Timing Pass
TimingPass
WIP, Made a new super shader are closer to the one they described in this video: Technical Artist Bootcamp: The VFX of Diablo - YouTube
so it’d look closer to the original vid hopefully.
WIP1

3 Likes

WIP1

WIP2

Diablo3PukeFanArt2

Diablo3PukeFanArt9

Kinda want to make a nose a sneeze version but not sure if I got the time.

3 Likes

NoseSneezingColored2

import bpy
import bmesh
import mathutils
from mathutils import Vector, Color
#go to Properties Panel -> Render Properties -> Color Management -> View Transform -> Standard
#export the image with no compression, no non-uniform scaling, and no mip maps, use bilinear filter
def create_morph_us_set(obj):
    
    bm = bmesh.new()
    bm.from_mesh(obj.data)
    
    uv_layer = bm.loops.layers.uv.new("VAT_UV")
    
    pixel_size = 1.0 / len(bm.verts)
    
    i = 0
    for v in bm.verts:
        for l in v.link_loops:
            uv_data = l[uv_layer]
            uv_data.uv = mathutils.Vector((i * pixel_size, 0.0))
        i += 1
        
    bm.to_mesh(obj.data)
    
# Replace 'YourObjectName' with the name of your object
object_name = "Cube"

# Get the object by its name
obj = bpy.data.objects.get(object_name)

#define scale use to scale down the vertex movement when they exceed 1
scale = 6.0

if obj and obj.type == 'MESH':
    
    #generate the UV        
    create_morph_us_set(obj)
    
    # Access the mesh data of the object
    mesh_data = obj.data

    # Get the number of frames in the animation
    start_frame = bpy.context.scene.frame_start
    end_frame = bpy.context.scene.frame_end
    
    #create lists for position and normal 
    #initialize width
    pixels_coords = []
    pixels_normal = []
    width = 0
    
    # Iterate through the frames in the animation
    for frame in range(start_frame, end_frame + 1):
        # Set the current frame
        bpy.context.scene.frame_set(frame)
        
        # Get the dependency graph and evaluate the object
        depsgraph = bpy.context.evaluated_depsgraph_get()
        evaluated_object = obj.evaluated_get(depsgraph)
        
        # Get the mesh data of the evaluated object
        mesh_data = evaluated_object.data
        
        # Get the world transformation matrix of the object for the current frame
        world_matrix = obj.matrix_world
        
        # Iterate through the vertices and get their global positions for the current frame
        for vertex in mesh_data.vertices:
            # Get the local coordinates of the vertex
            local_coords = vertex.co.copy() 
            local_normal = vertex.normal.copy()
            # Convert the local coordinates to global coordinates using the world transformation matrix
            global_coords = world_matrix @ local_coords 
            global_normal = world_matrix @ local_normal
            # Get the index of the vertex
            #vertex_index = vertex.index

            #store the vector values into a list of floats
            for coord in global_coords:
                pixels_coords.append(((coord / scale) + 1) / 2) 
            for coord in global_normal:
                pixels_normal.append((coord + 1) / 2) 
            #add 1 for the alpha of each pixel
            pixels_coords.append(1.0)
            pixels_normal.append(1.0) 
            
            #print("Frame:", frame, "Vertex", vertex_index, "Global Coordinates:", global_coords)
    
    
    #get width
    width = len(obj.data.vertices)
    #initalize image
    image = bpy.data.images.new(object_name, width, end_frame + 1 - start_frame)
    image.colorspace_settings.is_data = True 
    #save image
    image.pixels = pixels_coords
    image.save_render(bpy.path.abspath("//") + object_name + '_position' + ".png", scene = bpy.context.scene)
    image.pixels = pixels_normal
    image.save_render(bpy.path.abspath("//") + object_name + '_normal' + ".png", scene = bpy.context.scene)

else:
    print("Object", object_name, "not found or not a mesh.")