Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@tylermorganwall
Last active September 25, 2020 12:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tylermorganwall/673c4dda01f02afb63f590a16cc5aac0 to your computer and use it in GitHub Desktop.
Save tylermorganwall/673c4dda01f02afb63f590a16cc5aac0 to your computer and use it in GitHub Desktop.
Terminator Pig, rendered in R
library(rayrender)
#CSG Pig Elements
leg_scene = list(csg_cylinder(start = c(1,-0.6,0.5), end = c(1,1.,0.5), radius=0.25+0.01),
csg_cylinder(start = c(-1,-0.6,0.5), end = c(-1,1.,0.5), radius=0.25+0.01),
csg_cylinder(start = c(1,-0.6,-0.5), end = c(1,1.,-0.5), radius=0.25+0.01),
csg_cylinder(start = c(-1,-0.6,-0.5), end = c(-1,1.,-0.5), radius=0.25+0.01))
eye_scene = list(csg_sphere(x = 2, y = 2.5, z = 0.3, radius=0.25+0.01),
csg_sphere(x = 2, y = 2.5, z = -0.3, radius=0.25+0.01+0.01),
csg_sphere(x = 2.2, y = 2.5, z = 0.3, radius=0.1+0.01),
csg_sphere(x = 2.2, y = 2.5, z = -0.3, radius=0.1+0.01))
body_scene = csg_ellipsoid(y = 1, axes=c(2+0.01, 1+0.01, 1+0.01))
head_scene = csg_sphere(x = 1.5, y = 2, z = 0, radius=0.8+0.01)
nose_scene = csg_cylinder(start=c(2,2,0),end=c(2.6,2,0),radius=0.3)
nose_holes = list(csg_ellipsoid(x = 2.6, y = 2, z = 0.1, axes = c(0.05, 0.1, 0.05)),
csg_ellipsoid(x = 2.6, y = 2, z = -0.1, axes = c(0.05, 0.1, 0.05)),
csg_ellipsoid(x = 1.98+0.02, y = 1.6, z = 0, axes = c(0.2, 0.2, 0.3)))
mouth_hole = csg_ellipsoid(x = 1.98+0.02, y = 1.6, z = 0, axes = c(0.2, 0.2, 0.3))
#Blending values
blendval1 = 1
blendval2= 2
blendvaleye = 0.5
#Animation settings
vid_length = 360
cylinder_rad = unlist(tweenr::tween(c(10,0),n=vid_length, ease = "linear"))
base_y = unlist(tweenr::tween(c(0,0.5),n=vid_length, ease = "quadratic-in-out"))
vals = unlist(tweenr::tween(c(-4,-0.4),n=vid_length))#, ease = "quadratic-in-out"))
blend_vals1 = unlist(tweenr::tween(c(3,0.3),n=vid_length, ease = "linear"))
blend_vals2 = unlist(tweenr::tween(c(3,0.05),n=vid_length, ease = "linear"))
blendvals_eye = unlist(tweenr::tween(c(1,0.02),n=vid_length, ease = "linear"))
fov_vec = unlist(tweenr::tween(c(35,8),n=vid_length, ease = "quadratic-in-out"))
zval=unlist(tweenr::tween(c(14,-14),n=360,ease="quadratic-in-out"))
lookat_y =unlist(tweenr::tween(c(0,1),n=360,ease="quadratic-in-out"))
#Animate growing out of puddle
for(i in seq(1,360,by=1)) {
disk(radius=50,y=-1,
material=diffuse(checkercolor="grey20",color="white")) %>%
add_object(csg_object(
csg_combine(
csg_round(csg_group(list(
csg_cylinder(start=c(1,-0.8,0.5),end=c(1,-0.7,0.5), radius=cylinder_rad[i]),
csg_cylinder(start=c(-1,-0.8,0.5),end=c(-1,-0.7,0.5), radius=cylinder_rad[i]),
csg_cylinder(start=c(1,-0.8,-0.5),end=c(1,-0.7,-0.5), radius=cylinder_rad[i]),
csg_cylinder(start=c(-1,-0.8,-0.5),end=c(-1,-0.7,-0.5), radius=cylinder_rad[i]))),radius = 0.2),
csg_translate(
csg_combine(
csg_combine(
csg_group(eye_scene),
csg_combine(
csg_combine(
csg_combine(body_scene, head_scene, operation="blend", radius=blend_vals1[i]),
csg_group(leg_scene),
operation = "blend", radius=blend_vals1[i]),
csg_combine(nose_scene,csg_group(nose_holes),
operation="subtractblend",radius=0.1), operation="blend",radius=blend_vals1[i]),
operation="blend",radius=blendvals_eye[i]),
mouth_hole, operation = "subtractblend", radius = blendvals_eye[i]),y=vals[i]),
operation = "blend", radius=blend_vals2[i]),
material=metal())) %>%
render_scene(lookfrom=c(34,5,zval[i]),samples=128, clamp_value = 10,
lookat=c(0,lookat_y[i],0),aperture=0.4, width=800,height=800,
sample_method="stratified", fov=fov_vec[i],rotate_env = 0,
filename=glue::glue("terminatorpigfinal{i}"),verbose=TRUE,
environment_light = "blaubeuren_night_4k.hdr")
}
fov_vec2 = unlist(tweenr::tween(c(8,4),n=120, ease = "quadratic-in-out"))
zval2=unlist(tweenr::tween(c(-14,0),n=120,ease="quadratic-in-out"))
boxdown = unlist(tweenr::tween(c(5.25,1.79),n=120,ease="quadratic-in-out"))
boxrot = cospi(2*seq(0,360,length.out = 121)[-121]/180)
boxrot2 = sinpi(2*seq(0,360,length.out = 121)[-121]/180)
lookat_x =unlist(tweenr::tween(c(0,2),n=120,ease="quadratic-in-out"))
#Animate porkinator reveal
for(i in seq(1,120,by=1)) {
disk(radius=50,y=-1,
material=diffuse(checkercolor="grey20",color="white")) %>%
add_object(csg_object(csg_combine(
csg_combine(
csg_round(csg_group(list(
csg_cylinder(start=c(1,-0.8,0.5),end=c(1,-0.7,0.5), radius=cylinder_rad[360]),
csg_cylinder(start=c(-1,-0.8,0.5),end=c(-1,-0.7,0.5), radius=cylinder_rad[360]),
csg_cylinder(start=c(1,-0.8,-0.5),end=c(1,-0.7,-0.5), radius=cylinder_rad[360]),
csg_cylinder(start=c(-1,-0.8,-0.5),end=c(-1,-0.7,-0.5), radius=cylinder_rad[360]))),radius = 0.2),
csg_translate(
csg_combine(
csg_combine(
csg_group(eye_scene),
csg_combine(
csg_combine(
csg_combine(body_scene, head_scene, operation="blend", radius=blend_vals1[360]),
csg_group(leg_scene),
operation = "blend", radius=blend_vals1[360]),
csg_combine(nose_scene,csg_group(nose_holes),
operation="subtractblend",radius=0.1), operation="blend",radius=blend_vals1[360]),
operation="blend",radius=blendvals_eye[360]),
mouth_hole, operation = "subtractblend", radius = blendvals_eye[360]),y=vals[360]),
operation = "blend", radius=blend_vals2[360]),
csg_rotate(csg_box(y=boxdown[i], width=c(5,5,5)), pivot_point = c(0,boxdown[i],0), up = c(boxrot2[i]/8,1,boxrot[i]/8)),
operation = "subtractblend", radius = 0.5),
material=metal())) %>%
add_object(pig(y=-0.40, emotion="angry")) %>%
render_scene(lookfrom=c(34,5,zval2[i]),samples=128, clamp_value = 10,
lookat=c(lookat_x[i],lookat_y[360],0),aperture=0.4, width=800,height=800,
sample_method="stratified", fov=fov_vec[360],rotate_env = 0,
filename=glue::glue("pigfinal{i}"),verbose=TRUE,
environment_light = "blaubeuren_night_4k.hdr")
}
#Eyes glowing
eye_radius = unlist(tweenr::tween(c(0,0.07), ease = "exponential-in-out", n=30))
for(i in seq(1,30,by=1)) {
disk(radius=50,y=-1,
material=diffuse(checkercolor="grey20",color="white")) %>%
add_object(pig(y=-0.40, emotion="angry")) %>%
add_object(sphere(x = 2.24, y = 2.5-0.4, z = 0.3, radius=eye_radius[i],
material = light(intensity=100,color="red",importance_sample = FALSE))) %>%
add_object(sphere(x = 2.24, y = 2.5-0.4, z = -0.3, radius=eye_radius[i],
material = light(intensity=100,color="red",importance_sample = FALSE))) %>%
render_scene(lookfrom=c(34,5,zval2[120]),samples=512, clamp_value = 10,
lookat=c(lookat_x[120],lookat_y[360],0),aperture=0.4, width=800,height=800,
sample_method="stratified", fov=fov_vec[360],rotate_env = 0,
filename=glue::glue("pigfinaleyesglow{i}"),verbose=TRUE,
environment_light = "blaubeuren_night_4k.hdr")
}
#Zoom in eye
last_look_x = unlist(tweenr::tween(c(lookat_x[120],2.24), n=60, ease="cubic-in"))
last_look_y = unlist(tweenr::tween(c(lookat_y[360],2.1), n=60, ease="cubic-in"))
last_look_z = unlist(tweenr::tween(c(0,0.3), n=60, ease="cubic-in"))
last_fov = unlist(tweenr::tween(c(fov_vec[360],0.1), n=60, ease="cubic-in"))
for(i in seq(1,60,by=1)) {
disk(radius=50,y=-1,
material=diffuse(checkercolor="grey20",color="white")) %>%
add_object(pig(y=-0.40, emotion="angry")) %>%
add_object(sphere(x = 2.24, y = 2.5-0.4, z = 0.3, radius=eye_radius[30],
material = light(intensity=100,color="red",importance_sample = FALSE))) %>%
add_object(sphere(x = 2.24, y = 2.5-0.4, z = -0.3, radius=eye_radius[30],
material = light(intensity=100,color="red",importance_sample = FALSE))) %>%
render_scene(lookfrom=c(34,5,zval2[120]),samples=512, clamp_value = 10,
lookat=c(last_look_x[i],last_look_y[i],last_look_z[i]),aperture=0.4, width=800,height=800,
sample_method="stratified", fov=last_fov[i],rotate_env = 0,
filename=glue::glue("pigfinaleyes{i}"),verbose=TRUE,
environment_light = "blaubeuren_night_4k.hdr")
}
#Laser Beam text
library(rayimage)
tri_crop = c(rep(1,20),seq(1,800,length.out = 50),rep(800,50))
black_transparency = c(rep(0,90), unlist(tweenr::tween(c(0,1),n=30,ease="cubic-in-out")))
for(i in seq(1,120,by=1)) {
textoverlay = png::readPNG("terminator_text_overlay.png")
textoverlay[,tri_crop[i]:800,4] = 0
black_overlay = array(0, dim = c(800,800,4))
black_overlay[,,4] = black_transparency[i]
tri_image = png::readPNG(glue::glue("tritest{i}.png"))
tri_image %>%
add_image_overlay(black_overlay) %>%
add_image_overlay(textoverlay,filename = glue::glue("laser_text{i}.png"))
}
for(i in seq(1,30,by=1)) {
black_overlay = array(0, dim = c(800,800,4))
black_overlay[,,4] = black_transparency[120]
"tritest120.png" %>%
add_image_overlay(black_overlay) %>%
add_image_overlay(textoverlay,filename = glue::glue("laser_text{i+120}.png"))
}
#Black overlay
black_transparency2 = c(rep(0,30), unlist(tweenr::tween(c(0,1),n=30,ease="cubic-in-out")))
for(i in 1:60) {
if (i < 30) {
png::writePNG(png::readPNG("terminatorpigfinal570.png"),
glue::glue("terminatorpigfinal{570+i}.png"))
} else {
black_overlay = array(0, dim = c(800,800,4))
black_overlay[,,4] = black_transparency2[i]
"terminatorpigfinal570.png" %>%
add_image_overlay(black_overlay, filename = glue::glue("terminatorpigfinal{570+i}.png"))
}
}
#Combine all frames to one common filename
for(i in 1:210) {
if(i < 121) {
png::writePNG(png::readPNG(glue::glue("pigfinal{i}.png")),glue::glue("terminatorpigfinal{i+360}.png"))
} else if (i < 151) {
png::writePNG(png::readPNG(glue::glue("pigfinaleyesglow{i-120}.png")),glue::glue("terminatorpigfinal{i+360}.png"))
} else {
png::writePNG(png::readPNG(glue::glue("pigfinaleyes{i-150}.png")),glue::glue("terminatorpigfinal{i+360}.png"))
}
}
av::av_encode_video(glue::glue("terminatorpigfinal{1:570}.png"),
output = "terminator_pig.mp4", framerate = 30)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment