A somewhat optimized sketch, makes use of processing pixel array functionality, takes a little time to "warm-up". Original used P3D mode, probably should have been P2D (apparently better than default for pixel array type sketches)....
##################################################
# amp_zoom_in.rb
# adapted from a sketch at http://www.biothing.org
##################################################
attr_reader :col, :a, :b, :c, :k, :amp, :time
def setup()
size(640, 480, P2D)
color_mode(RGB, 1.0)
frame_rate(4)
load_pixels()
reset
end
def draw()
@time += 0.1 #step ahead in time with each frame
#now go through each pixel in the window:
(0...width).each do |x|
(0...height).each do |y|
#create values with trig functions, noise, etc acting on x,y and time.
#experiment with how these values are modulating over time.
@a = dist(x, y, width/2, height/2)
@b= (cos(x/360.0 + time)).abs # frequency larger means less
@c = noise(y/180.0*cos(time/20.0)) # inteference, larger means less
@amp = k # amplitude
@col = color((cos(a/120.0 + b + c * 10.0).abs)) * amp
#combine values into a color somehow. again the possibilities are limitless
begin
pixels[y * width + x] = col
rescue
reset
end
end
end
update_pixels()
@k += 1
end
def reset
@k = 0
@time = 0
end
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Saturday, 30 October 2010
Revisiting My Voronoi Application
I had the idea for sometime to optimize this application. As before the application uses Lee Byrons library which in turn depends on John Lloyds QuickHull3D library (both can be accessed at the Lee Byron link). One day I might re-write the application to use a 3D mesh library directly. The major optimization here is to use processings built in pixels array functionality. The app will work best if the aspect ratio of the image is the same as the frame size (1:1 is probably optimal?). I have introduced an auto-scale feature that seems to work...
Use the view raw feature (below) if you want to copy the code.
Use the view raw feature (below) if you want to copy the code.
Labels:
portrait application,
voronoi mesh
Thursday, 14 October 2010
Creating simple animations using the SunflowAPIAPI library and jruby
Here I explore the animation possibilities of the SunflowAPIAPI library (nothing on the scale of the one by amnon.owed).
It is very simple to use ruby syntax to create different views of a scene by changing the camera position, and use sunflow to render each image. Rather than modify each frame, I had the idea of using 20 incremental views, and crudely converting them to 200 frames by copying each view 10 times. I then used mencoder to stitch the frames together to produce a short movie. Here is the result:-
# hair.rb NB: run this script directly with jruby
require 'library/sunflow_api/library/sunflow_api.jar'
require 'library/sunflow/library/sunflow.jar'
require 'library/sunflow/library/janino.jar'
require 'library/sunflow/library/commons-compiler.jar'
class BasicHair
API = Java::Com::briansteen::SunflowAPIAPI
SMath = Java::Org::sunflow::math
JColor = java.awt.Color
attr_reader :width, :height, :n_particles, :sunflow
def initialize width = 640, height = 480, cam_x = 0
@width = width
@height = height
@n_particles = 20
# create a new API instance
@sunflow = API.new
# set width and height
@sunflow.set_width(width)
@sunflow.set_height(height)
# set background color
@sunflow.set_background(1, 1, 1)
# set camera
@sunflow.set_camera_position(cam_x, 7, 5)
@sunflow.set_camera_target(2, 0.5, 0)
@sunflow.set_thinlens_camera("thinLensCamera", 50, width/height)
# set basic light
@sunflow.set_point_light("myPointLight", SMath::Point3.new(0, 5, 5),
JColor.new(255, 255, 255))
@sunflow.set_directional_light("myDirectionalLight", SMath::Point3.new(-2, 3, 0),
SMath::Vector3.new(0, 0, 0), 3, JColor.new(1, 1, 1))
# @sunflow.setSphereLight("mySphereLight", SMath::Point3.new(0, 30, -5),
# JColor.new(0, 0, 255), 32, 10)
# draw a ground plane
@sunflow.draw_plane("ground", SMath::Point3.new(0, 0, 0), SMath::Vector3.new(0, 1, 0))
# coordinates array
@sunflow.draw_box("boxname", 0, 0, 0, 1)
end
def create_scene
hair_widths = [0.025]
# create particle coordinates
350.times do |j|
# particle start position
particle_x = Math.cos(j * 0.5) * j * 0.0015
particle_y = 0
particle_z = Math.sin(j * 0.5) * j * 0.0015
hair_coordinates = Array.new(n_particles * 3)
array_index = -1
n_particles.times do |i|
particle_x += 0.1 + Math.cos(i * 0.15 + j * 0.05) * 0.13
particle_y -= Math.sin(particle_z * 0.01 + j * 0.05) * 0.125 +
Math.cos(i * 0.5 + particle_y) * 0.125
particle_z += Math.sin(i) * 0.25 + particle_y * 0.01
hair_coordinates[array_index += 1] = particle_x
hair_coordinates[array_index += 1] = particle_y
hair_coordinates[array_index += 1] = particle_z
end
# set ambient occlusion shader
@sunflow.setAmbientOcclusionShader("myAmbientOcclusionShader#{j}", JColor.new(55, 55, 55),
JColor.new(0, 0, 0), 16, 1)
# set glass shader
# @sunflow.setGlassShader("myGlassShader", JColor.new(1, 1, 1), 2.5, 3, JColor.new(1, 1, 1))
# set shiny-diffuse shader
# @sunflow.setShinyDiffuseShader("myShinyShader", JColor.new(55, 55, 55), 0.8)
# draw object
@sunflow.draw_hair("hair#{j}", n_particles - 2, hair_coordinates.to_java(:float),
hair_widths.to_java(:float))
end
end
def render_scene filename = nil
sunflow.setIrradianceCacheGIEngine(32, 0.4, 1, 15, nil)
# render
sunflow.render() unless filename
if filename
begin # test for dodgy filename/path
file = File.new(filename, "w")
file.close
sunflow.render(filename) # save as png image
rescue
puts "Warning #{filename} is not writable"
end
end
end
end
20.times do |i|
hair = BasicHair.new 640, 480, i # preferred render size for vimeo
hair.create_scene
hair.render_scene "/home/tux/ruby_sunflow/frame-#{i}.png" # default is to render in sunflow frame ie not to file
end
It is very simple to use ruby syntax to create different views of a scene by changing the camera position, and use sunflow to render each image. Rather than modify each frame, I had the idea of using 20 incremental views, and crudely converting them to 200 frames by copying each view 10 times. I then used mencoder to stitch the frames together to produce a short movie. Here is the result:-
Changing the camera Sunflow Hair from monkstone on Vimeo.
# hair.rb NB: run this script directly with jruby
require 'library/sunflow_api/library/sunflow_api.jar'
require 'library/sunflow/library/sunflow.jar'
require 'library/sunflow/library/janino.jar'
require 'library/sunflow/library/commons-compiler.jar'
class BasicHair
API = Java::Com::briansteen::SunflowAPIAPI
SMath = Java::Org::sunflow::math
JColor = java.awt.Color
attr_reader :width, :height, :n_particles, :sunflow
def initialize width = 640, height = 480, cam_x = 0
@width = width
@height = height
@n_particles = 20
# create a new API instance
@sunflow = API.new
# set width and height
@sunflow.set_width(width)
@sunflow.set_height(height)
# set background color
@sunflow.set_background(1, 1, 1)
# set camera
@sunflow.set_camera_position(cam_x, 7, 5)
@sunflow.set_camera_target(2, 0.5, 0)
@sunflow.set_thinlens_camera("thinLensCamera", 50, width/height)
# set basic light
@sunflow.set_point_light("myPointLight", SMath::Point3.new(0, 5, 5),
JColor.new(255, 255, 255))
@sunflow.set_directional_light("myDirectionalLight", SMath::Point3.new(-2, 3, 0),
SMath::Vector3.new(0, 0, 0), 3, JColor.new(1, 1, 1))
# @sunflow.setSphereLight("mySphereLight", SMath::Point3.new(0, 30, -5),
# JColor.new(0, 0, 255), 32, 10)
# draw a ground plane
@sunflow.draw_plane("ground", SMath::Point3.new(0, 0, 0), SMath::Vector3.new(0, 1, 0))
# coordinates array
@sunflow.draw_box("boxname", 0, 0, 0, 1)
end
def create_scene
hair_widths = [0.025]
# create particle coordinates
350.times do |j|
# particle start position
particle_x = Math.cos(j * 0.5) * j * 0.0015
particle_y = 0
particle_z = Math.sin(j * 0.5) * j * 0.0015
hair_coordinates = Array.new(n_particles * 3)
array_index = -1
n_particles.times do |i|
particle_x += 0.1 + Math.cos(i * 0.15 + j * 0.05) * 0.13
particle_y -= Math.sin(particle_z * 0.01 + j * 0.05) * 0.125 +
Math.cos(i * 0.5 + particle_y) * 0.125
particle_z += Math.sin(i) * 0.25 + particle_y * 0.01
hair_coordinates[array_index += 1] = particle_x
hair_coordinates[array_index += 1] = particle_y
hair_coordinates[array_index += 1] = particle_z
end
# set ambient occlusion shader
@sunflow.setAmbientOcclusionShader("myAmbientOcclusionShader#{j}", JColor.new(55, 55, 55),
JColor.new(0, 0, 0), 16, 1)
# set glass shader
# @sunflow.setGlassShader("myGlassShader", JColor.new(1, 1, 1), 2.5, 3, JColor.new(1, 1, 1))
# set shiny-diffuse shader
# @sunflow.setShinyDiffuseShader("myShinyShader", JColor.new(55, 55, 55), 0.8)
# draw object
@sunflow.draw_hair("hair#{j}", n_particles - 2, hair_coordinates.to_java(:float),
hair_widths.to_java(:float))
end
end
def render_scene filename = nil
sunflow.setIrradianceCacheGIEngine(32, 0.4, 1, 15, nil)
# render
sunflow.render() unless filename
if filename
begin # test for dodgy filename/path
file = File.new(filename, "w")
file.close
sunflow.render(filename) # save as png image
rescue
puts "Warning #{filename} is not writable"
end
end
end
end
20.times do |i|
hair = BasicHair.new 640, 480, i # preferred render size for vimeo
hair.create_scene
hair.render_scene "/home/tux/ruby_sunflow/frame-#{i}.png" # default is to render in sunflow frame ie not to file
end
Labels:
animation,
jruby,
sunflow raytracing
Sunday, 3 October 2010
Performance tune-ups (or not) for jruby sunflow raytracing
When I realised that sunflow is multi-threaded I thought there may be some performance tune-ups possible.
These are the steps I tried:-
I'm not sure what effect if any updating the janino compiler has but to my mind it makes the application a bit more future-proof (there is the option to upgrade from java 1.4 syntax see janino web site). The windows 0.073 version of sunflow is claimed to be faster on the basis of a native compiler, I doubt it.
Using the server option is a good thing, regular java uses it by default, I'm not sure about jruby. Because --server is a proxy for -J-server, suggest to me that you may need this option since it has been made easier to use?
Using the --fast option ensures pre-compilation (amongst other speed-ups) which must be good thing here?
Allocating increased memory is the only thing the sunflow.sh script does. Running the sunflow.jar directly (java -jar sunflow.jar) requests > 800 mb heap space to run.
The thread pooling is used to prevent wasteful ruby green threads being spawned. Both cores on my dual core linux box were kept running flat out according to my conky readout.
Now the difference between none of these measures, and running with the speed-ups seemed to be noticeable, so I thought I would measure it?
Conclusion
Now I've done a bit of measurement I'm not so sure perhaps it was the janino compiler change after all?
The --server command certainly makes no difference for me, default is --server.
Well it turns out it is all in the imagination when I measured the different compilers with or without any "performance" options performance was much the same...
However I was very impressed with the new StructureSynth built in ray tracing facility, which has apparently been been built with efficiency in mind, the default setting is for 4 processors (2 real, 2 virtual). Apparently povray lags behind in that regard?
These are the steps I tried:-
- I've updated my sunflow to use the latest janino compiler, only a small amount of re-factoring was required essentially deprecating two types of error and revising one because it has been re-factored to the commons-compiler.
- I'm using the --server option
- I'm using the --fast option
- I've increased the heap space -J-Xmx1024m
- I've enabled thread pooling -J-Djruby.thread.pooling=true
I'm not sure what effect if any updating the janino compiler has but to my mind it makes the application a bit more future-proof (there is the option to upgrade from java 1.4 syntax see janino web site). The windows 0.073 version of sunflow is claimed to be faster on the basis of a native compiler, I doubt it.
Using the server option is a good thing, regular java uses it by default, I'm not sure about jruby. Because --server is a proxy for -J-server, suggest to me that you may need this option since it has been made easier to use?
Using the --fast option ensures pre-compilation (amongst other speed-ups) which must be good thing here?
Allocating increased memory is the only thing the sunflow.sh script does. Running the sunflow.jar directly (java -jar sunflow.jar) requests > 800 mb heap space to run.
The thread pooling is used to prevent wasteful ruby green threads being spawned. Both cores on my dual core linux box were kept running flat out according to my conky readout.
Now the difference between none of these measures, and running with the speed-ups seemed to be noticeable, so I thought I would measure it?
Conclusion
Now I've done a bit of measurement I'm not so sure perhaps it was the janino compiler change after all?
The --server command certainly makes no difference for me, default is --server.
Well it turns out it is all in the imagination when I measured the different compilers with or without any "performance" options performance was much the same...
However I was very impressed with the new StructureSynth built in ray tracing facility, which has apparently been been built with efficiency in mind, the default setting is for 4 processors (2 real, 2 virtual). Apparently povray lags behind in that regard?
Labels:
jruby,
sunflow raytracing,
tune ups
Friday, 1 October 2010
SunflowAPIAPI test example using jruby
See previous post for how to setup java libraries. If you are mad like me, and have updated sunflow to use the latest janino compiler you should require the commons-compiler.jar as well.
# sunflow_test.rb NB: run this script directly with jruby
require 'library/sunflow_api/library/sunflow_api.jar'
require 'library/sunflow/library/sunflow.jar'
require 'library/sunflow/library/janino.jar'
class SunflowTest
API = Java::Com::briansteen::SunflowAPIAPI
SMath = Java::Org::sunflow::math
attr_reader :sunflow
def initialize width = 500, height = 500
@sunflow = API.new
sunflow.set_width(width)
sunflow.set_height(height)
sunflow.set_camera_position(0, 2.5, -5)
sunflow.set_camera_target(0, 0, 0)
sunflow.set_thinlens_camera("thinLensCamera", 50, width/height)
end
def create_scene
sunflow.draw_plane("ground", SMath::Point3.new(0,-3.5,0), SMath::Vector3.new(0, 1, 0))
sunflow.draw_sphere_flake("mySphereFlake", 20, SMath::Vector3.new(0, 1, 0), 1)
end
def render_scene filename = nil
sunflow.setPathTracingGIEngine 6
# render
sunflow.render unless filename
if filename
begin # test for dodgy filename/path
file = File.new(filename, "w")
file.close
sunflow.render(filename) # save as png image
rescue
puts "Warning #{filename} is not writable"
end
end
end
end
test = SunflowTest.new
test.create_scene
test.render_scene
# sunflow_test.rb NB: run this script directly with jruby
require 'library/sunflow_api/library/sunflow_api.jar'
require 'library/sunflow/library/sunflow.jar'
require 'library/sunflow/library/janino.jar'
class SunflowTest
API = Java::Com::briansteen::SunflowAPIAPI
SMath = Java::Org::sunflow::math
attr_reader :sunflow
def initialize width = 500, height = 500
@sunflow = API.new
sunflow.set_width(width)
sunflow.set_height(height)
sunflow.set_camera_position(0, 2.5, -5)
sunflow.set_camera_target(0, 0, 0)
sunflow.set_thinlens_camera("thinLensCamera", 50, width/height)
end
def create_scene
sunflow.draw_plane("ground", SMath::Point3.new(0,-3.5,0), SMath::Vector3.new(0, 1, 0))
sunflow.draw_sphere_flake("mySphereFlake", 20, SMath::Vector3.new(0, 1, 0), 1)
end
def render_scene filename = nil
sunflow.setPathTracingGIEngine 6
# render
sunflow.render unless filename
if filename
begin # test for dodgy filename/path
file = File.new(filename, "w")
file.close
sunflow.render(filename) # save as png image
rescue
puts "Warning #{filename} is not writable"
end
end
end
end
test = SunflowTest.new
test.create_scene
test.render_scene
Labels:
jruby,
sunflowAPIAPI
Subscribe to:
Posts (Atom)
Followers
About Me
- monkstone
- I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2