Full magazine available here:
Monday, March 23, 2015
Saturday, February 21, 2015
Latest experiments with NVIDIA's Optix
Video of my latests experiments with Optix for neuron morphologies (http://neuromorpho.org) and molecular vizualization (http://www.rcsb.org).
Saturday, December 27, 2014
Python + GLSL 3D Fractal Viewer
Because it's Xmas!
Pre-requiries: http://pyopengl.sourceforge.netSource code: https://github.com/cudaopencl/pyRayCaster
Vertex shader
#version 120
varying vec3 normal;
attribute vec2 a_position;
varying vec2 v_position;
void main()
{
normal = gl_NormalMatrix * gl_Normal;
gl_Position = vec4(a_position, 0.0, 1.0);
v_position = a_position;
}
Fragment shader:
#version 120
varying vec2 v_position;
uniform float u_fov = 0.0;
uniform float u_timer = 0.0;
uniform vec3 u_origin = vec3( 0.f, 0.f, -4.f );
uniform float u_rotation_x = 0.0;
uniform float u_rotation_y = 0.0;
uniform float u_rotation_z = 0.0;
vec3 rotate( in vec3 source, in vec3 angles )
{
vec3 cosAngles = vec3( cos(angles.x), cos(angles.y), cos(angles.z));
vec3 sinAngles = vec3( sin(angles.x), sin(angles.y), sin(angles.z));
float x,y,z;
vec3 returnValue = source;
// Y axis
z = source.z*cosAngles.y - source.x*sinAngles.y;
x = source.z*sinAngles.y + source.x*cosAngles.y;
returnValue.z = z;
returnValue.x = x;
// X axis
z = returnValue.z*cosAngles.x + returnValue.y*sinAngles.x;
y = returnValue.z*sinAngles.x - returnValue.y*cosAngles.x;
returnValue.z = z;
returnValue.y = y;
return returnValue;
}
vec4 calc_mandel(vec3 o, vec3 d, float t)
{
float X = o.x + d.x * t;
float Y = o.y + d.y * t;
float Z = o.z + d.z * t;
vec2 uv = vec2(X*0.2f+0.5f,Y*0.2f+0.5f);
float scale = 1.f; //512 / 512;
uv=((uv-0.5)*5.5);
uv.y*=scale;
uv.y+=0.0;
uv.x-=0.5;
vec2 z = vec2(0.0, 0.0);
vec3 c = vec3(0.0, 0.0, 0.0);
float v;
float I=0.f;
for(int i=0;(i<100);i++)
{
if(((z.x*z.x+z.y*z.y) >= 4.0+cos(u_timer*3.f))) break;
z = vec2(z.x*z.x - z.y*z.y, 2.0*sin(u_timer*2.6f)*z.y*z.x) + uv;
if((z.x*z.x+z.y*z.y) >= 2.0)
{
c.b=float(i)/20.0;
c.r=sin((float(i)/5.0));
}
I += 1.f+cos(u_timer);
}
if(I<Z)
return vec4(c.b,c.r,0.f,1.0);
else
return vec4(0.f,0.f,c.r,0.f);
}
vec4 wave( vec3 o, vec3 d, float t )
{
float x = o.x + d.x * t;
float y = o.y + d.y * t;
float z = o.z + d.z * t;
float h = cos(x+u_timer)*sin(z);
if(y<h) {
float a = 0.2f*(h/(1.f+t*2));
return vec4(a,a,a,0);
}
return vec4(0.f,0.f,0.f,0.f);
}
void main()
{
vec3 angles = vec3(u_rotation_x,u_rotation_y,u_rotation_z);
vec2 pos = v_position;
vec3 origin = u_origin;
origin.z = u_fov;
origin = rotate( origin, angles );
vec3 dir = (vec3(pos.x, pos.y, u_fov+2.f)-origin);
dir = rotate( dir, angles );
bool found=false;
vec4 color = vec4(0.f,0.f,0.f,0.f);
for( float t=1.f; t<10.f; t+=.5f)
{
//color += 5.f*wave(origin, dir, t);
color += 0.3f*calc_mandel(origin, dir, t);
}
gl_FragColor = color;
}
Python code:
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import shaders
import sys
SHADER_NAME = 'raycaster'WINDOW_NAME = 'RayCaster'
class Application:
def __init__(self):
self.geometryRotation = [0.0, 0.0, 0.0]
self.timer = 0 self.fov = -2.0 self.old = [0.0, 0.0, 0.0]
self.shader = None self.origin = [0.0, 0.0, -1.0]
@staticmethod def read_shader_from_file(filename):
file_handle = open(filename, 'r')
file_content = file_handle.read()
file_handle.close()
return file_content
def mouse(self, button, status, x, y):
self.old[0] = x
self.old[1] = y
def motion(self, x, y):
#self.fov += (self.old[1] - y) / 500.0 self.geometryRotation[1] -= (self.old[0] - x) / 100.0 self.geometryRotation[0] -= (self.old[1] - y) / 100.0 self.old[0] = x
self.old[1] = y
def keyboard(self, key, x, y):
print key + " pressed" if key == 'q':
sys.exit()
if key == 'r':
self.compile_shaders()
def compile_shaders(self):
print "Initializing shaders" vertex_shader = shaders.compileShader(
self.read_shader_from_file(
'shaders/' + SHADER_NAME + '.vert'), GL_VERTEX_SHADER)
fragment_shader = shaders.compileShader(
self.read_shader_from_file(
'shaders/' + SHADER_NAME + '.frag'), GL_FRAGMENT_SHADER)
self.shader = shaders.compileProgram(vertex_shader, fragment_shader)
glUseProgram(self.shader)
def run(self):
# self.shader = shaders.compileProgram(VERTEX_SHADER,FRAGMENT_SHADER) width = 512 height = 512 glutInit(sys.argv)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
glutInitWindowSize(width, height)
glutCreateWindow(WINDOW_NAME)
glClearColor(0.2, 0.2, 0.2, 1.0)
glShadeModel(GL_SMOOTH)
glEnable(GL_CULL_FACE)
glEnable(GL_DEPTH_TEST)
glutIdleFunc(self.display)
glutDisplayFunc(self.display)
glutMouseFunc(self.mouse)
glutMotionFunc(self.motion)
glutKeyboardFunc(self.keyboard)
glMatrixMode(GL_PROJECTION)
gluPerspective(45.0, float(width) / float(height), 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0)
glPushMatrix()
self.compile_shaders()
print "Entering main loop..." glutMainLoop()
def display(self):
self.timer += 0.01 loc = glGetUniformLocation(self.shader, 'u_timer')
glUniform1f(loc, self.timer)
loc = glGetUniformLocation(self.shader, 'u_rotation_x')
glUniform1f(loc, self.geometryRotation[0])
loc = glGetUniformLocation(self.shader, 'u_rotation_y')
glUniform1f(loc, self.geometryRotation[1])
loc = glGetUniformLocation(self.shader, 'u_rotation_z')
glUniform1f(loc, self.geometryRotation[2])
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
color = [1.0, 1.0, 1.0, 1.0]
glMaterialfv(GL_FRONT, GL_DIFFUSE, color)
# Draw scene glPushMatrix()
size = 1 depth = 0.0 glBegin(GL_QUADS)
glVertex3f(-size, -size, depth)
glNormal3f(0.0, 0.0, -1.0)
glVertex3f(size, -size, depth)
glNormal3f(0.0, 0.0, -1.0)
glVertex3f(size, size, depth)
glNormal3f(0.0, 0.0, -1.0)
glVertex3f(-size, size, depth)
glNormal3f(0.0, 0.0, -1.0)
glEnd()
glPopMatrix()
glutSwapBuffers()
if __name__ == '__main__':
app = Application()
app.run()
Sunday, October 12, 2014
Tuesday, August 26, 2014
Photo exhibition
Working on photo exhibition based on my work on ray-tracing. Generating ultra definition pictures on good old GTX 480.
Saturday, July 19, 2014
Thursday, May 1, 2014
Material Editor for SoL-R
After a few interop issues between the GUI and the GPU library (CUDA and OpenCL), I finally got it working! The GUI makes it simple to manipulate materials on the fly, and validate texture mapping implementation (Bump, Normal, Specular, etc).
Saturday, April 26, 2014
Saturday, January 4, 2014
Subscribe to:
Posts (Atom)