pax_global_header 0000666 0000000 0000000 00000000064 12574032016 0014512 g ustar 00root root 0000000 0000000 52 comment=97af8d18cbf9b263c8a771909f5657b63908b8b6
virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/ 0000775 0000000 0000000 00000000000 12574032016 0023576 5 ustar 00root root 0000000 0000000 virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/.gitignore 0000664 0000000 0000000 00000000006 12574032016 0025562 0 ustar 00root root 0000000 0000000 *.swp
virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/.gitmodules 0000664 0000000 0000000 00000000251 12574032016 0025751 0 ustar 00root root 0000000 0000000 [submodule "space_view3d_virtual_reality/lib/python-ovrsdk"]
path = space_view3d_virtual_reality/lib/python-ovrsdk
url = https://github.com/dfelinto/python-ovrsdk.git
virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/README.md 0000664 0000000 0000000 00000004261 12574032016 0025060 0 ustar 00root root 0000000 0000000 # Virtual Reality Viewport
Addon to bring virtual reality devices to the Blender viewport.
This is work in progress/pre-alpha state, use at your own risk.
Prerequisite
============
Currently working on Blender Test Build 2.75: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.75
How to Use
==========
In the viewport press ``Space`` + ``Virtual Reality Viewport``.
And then press:
* ``Alt + F11`` (Window Fullscreen)
* ``Alt + F10`` (Fullscreen Area and Hide Panels)
Current State
=============
Video of plugin working:
[![Video of plugin in action](http://img.youtube.com/vi/saSn2qvW0aE/0.jpg)](https://www.youtube.com/watch?v=saSn2qvW0aE)
Installation
============
In a terminal paste the following commands:
```
$ git clone https://github.com/dfelinto/virtual_reality_viewport.git
$ cd virtual_reality_viewport
$ git submodule update --init --recursive --remote
$ zip -x __pycache__ -x */.git* -r9 space_view3d_virtual_reality.zip space_view3d_virtual_reality
```
Now install the space_view3d_virtual_reality.zip in Blender as an addon.
Update
======
The following commands are for Mac, some changes are needed for other OSs:
```
$ git pull origin
$ git submodule update --recursive --remote
$ rsync -rv --exclude=.DS_Store --exclude=.git --exclude=*.blend1 --exclude=*.blend2 --exclude=*.swp --exclude=*.swo space_view3d_virtual_reality ~/Library/Application\ Support/Blender/2.75/scripts/addons/
```
Optionally, instead of rsync you can generate a new ``.zip``, remove the previous version of the addon and re-install it.
Roadmap
=======
Oculus DK2 is currently working. The next step is to support view navigation (`Shift + F`) within the addon.
Later we can make it flexible enough to support other HMD devices.
There are a few things I still need to implement:
* Automatically go to clean fullscreen (Alt+F10) and fullwindow (Alt+F11)
Feel free to send pull requests to any of the above.
Credits
=======
Oculus DK2 Shader by Martins Upitis (which I guess based his work from elsewhere)
OculusVR wrapper by https://github.com/jherico/python-ovrsdk
Blender Addon - Dalai Felinto - http://www.dalaifelinto.com
virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality/ 0000775 0000000 0000000 00000000000 12574032016 0031451 5 ustar 00root root 0000000 0000000 __init__.py 0000664 0000000 0000000 00000017241 12574032016 0033510 0 ustar 00root root 0000000 0000000 virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality #====================== BEGIN GPL LICENSE BLOCK ======================
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#======================= END GPL LICENSE BLOCK ========================
#
bl_info = {
"name": "Virtual Reality Viewport",
"author": "Dalai Felinto",
"version": (0, 9),
"blender": (2, 7, 5),
"location": "Window Menu",
"description": "",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "3D View"}
import bpy
from bgl import (
Buffer,
GL_INT,
GL_RGBA,
)
from .opengl_helper import (
calculate_image_size,
create_image,
create_shader,
delete_image,
draw_callback_px,
resize,
)
from . import oculus
def get_context_3dview (context):
"""returns area and space"""
screen = context.screen
for area in screen.areas:
if area.type == 'VIEW_3D':
for region in area.regions:
if region.type == 'WINDOW':
return area, region
return None, None
def get_space_3dview(context):
area = context.area
for space in area.spaces:
if space.type == 'VIEW_3D':
return space
return None
def get_glsl_shader(shader_file):
import os
folderpath = os.path.dirname(os.path.abspath(__file__))
filepath = os.path.join(folderpath, 'shaders', shader_file)
f = open(filepath, 'r')
data = f.read()
f.close()
return data
class VirtualRealityViewportOperator(bpy.types.Operator):
""""""
bl_idname = "view3d.virtual_reality_toggle"
bl_label = "Toggle Virtual Reality Mode"
bl_description = ""
_enabled = True
_timer = None
_display_mode = None
_is_multiview = None
_space = None
@classmethod
def poll(cls, context):
camera = context.scene.camera
return camera and camera.type == 'CAMERA'
def modal(self, context, event):
if event.type == 'ESC':
return self.cancel(context)
if event.type == 'TIMER':
# bug, waiting for fix: "[#31026] context.region broken after QuadView on + off"
# http://projects.blender.org/tracker/index.php?func=detail&aid=31026&group_id=9&atid=498
if not context.region or \
not context.space_data or \
context.space_data.type != 'VIEW_3D':
return {'PASS_THROUGH'}
viewport_shade = context.space_data.viewport_shade
self._enabled = (viewport_shade != 'RENDERED')
if (self.width != context.region.width) or (self.height != context.region.height):
resize(self, context)
self.oculus.update()
return {'PASS_THROUGH'}
def invoke(self, context, event):
"""
* Create a fullscreen window with the editor in fullscreen with clean UI.
* Views should be on, and this window should have stereo 3d mode set to side-by-side
* Also you should lock a camera to the viewport to make sure you always look nicely
* Sync the Oculus rotation + translation to the Blender camera
* Now the opengl fun ... create a GLSL screen shader to run the warping distortions.
"""
if context.area.type == 'VIEW_3D':
scene = context.scene
window = context.window
self.oculus = oculus.Oculus(scene.camera, self.report)
if not self.oculus.isAvailable():
return {'CANCELLED'}
self._display_mode = window.stereo_3d_display.display_mode
window.stereo_3d_display.display_mode = 'SIDEBYSIDE'
#if bpy.ops.wm.window_fullscreen_toggle.poll():
# bpy.ops.wm.window_fullscreen_toggle()
self._render = scene.render, scene.render.use_multiview, scene.render.resolution_x, scene.render.resolution_y
scene.render.use_multiview = True
scene.render.resolution_x = 1920
scene.render.resolution_y = 1080
#if bpy.ops.screen.screen_full_area.poll():
# bpy.ops.screen.screen_full_area(use_hide_panels=True)
space = get_space_3dview(context)
self._space = space, space.show_only_render, space.stereo_3d_camera, space.region_3d.view_perspective
space.show_only_render = True
space.stereo_3d_camera = 'S3D'
space.region_3d.view_perspective = 'CAMERA'
if bpy.ops.view3d.view_center_camera.poll():
bpy.ops.view3d.view_center_camera()
self._timer = context.window_manager.event_timer_add(1.0/75.0, context.window) # 75 Hz
self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, (self, context), 'WINDOW', 'POST_VIEW')
context.window_manager.modal_handler_add(self)
self.viewport = Buffer(GL_INT, 4)
self.width = context.region.width
self.height = context.region.height
# power of two dimensions
self.buffer_width, self.buffer_height = calculate_image_size(self.width, self.height)
# images to dump the screen buffers
self.color_id = create_image(self.buffer_width, self.buffer_height, GL_RGBA)
# glsl shaders
fragment_shader = get_glsl_shader(self.oculus.shader_file)
self.program_shader = create_shader(fragment_shader)
return {'RUNNING_MODAL'}
else:
self.report({'WARNING'}, "View3D not found, cannot run operator")
return {'CANCELLED'}
def cancel(self, context):
if self._handle:
bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
del self._handle
if self._timer:
context.window_manager.event_timer_remove(self._timer)
del self._timer
self.oculus.quit()
self.quit()
# set back the original values
try:
context.window.stereo_3d_display.display_mode = self._display_mode
render, use_multiview, resolution_x, resolution_y = self._render
render.use_multiview = use_multiview
render.resolution_x = resolution_x
render.resolution_y = resolution_y
space, show_only_render, stereo_3d_camera, view_perspective = self._space
space.show_only_render = show_only_render
space.stereo_3d_camera = stereo_3d_camera
if space.region_3d:
space.region_3d.view_perspective = view_perspective
except Exception as err:
self.report({'ERROR'}, str(err))
return {'CANCELLED'}
def quit(self):
"""garbage colect"""
if self.color_id:
delete_image(self.color_id)
def is_stereo_left(self, context):
""""""
space = get_space_3dview(context)
return space.stereo_3d_eye == 'LEFT'
def register():
bpy.utils.register_class(VirtualRealityViewportOperator)
def unregister():
bpy.utils.unregister_class(VirtualRealityViewportOperator)
if __name__ == '__main__':
register()
virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality/lib/ 0000775 0000000 0000000 00000000000 12574032016 0032217 5 ustar 00root root 0000000 0000000 python-ovrsdk/ 0000775 0000000 0000000 00000000000 12574032016 0034767 5 ustar 00root root 0000000 0000000 virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality/lib oculus.py 0000664 0000000 0000000 00000007113 12574032016 0033260 0 ustar 00root root 0000000 0000000 virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality class Oculus():
def __init__(self, camera, report):
self._report = report
self._available = True
self._hmd = None
self._description = None
self._camera = camera
self._version = 2 # DK2 by default
self._matrix_world = camera.matrix_world.copy()
self._lens = camera.data.lens
self._checkModule()
self._start()
def isAvailable(self):
return self._available
def _checkModule(self):
"""if library exists append it to sys.path"""
import sys
import os
addon_path = os.path.dirname(os.path.abspath(__file__))
oculus_path = os.path.join(addon_path, "lib", "python-ovrsdk")
if oculus_path not in sys.path:
sys.path.append(oculus_path)
def _start(self):
try:
from oculusvr import (
Hmd,
cast,
POINTER,
ovrHmdDesc,
ovrVector3f,
)
Hmd.initialize()
except SystemError as err:
self._error("Oculus initialization failed, check the physical connections and run again")
return
if Hmd.detect() == 1:
self._hmd = Hmd()
self._description = cast(self._hmd.hmd, POINTER(ovrHmdDesc)).contents
self._frame = 0
self._eyes_offset = [ ovrVector3f(), ovrVector3f() ]
self._eyes_offset[0] = 0.0, 0.0, 0.0
self._eyes_offset[1] = 0.0, 0.0, 0.0
self._hmd.configure_tracking()
self._setVersion(self._description.ProductName)
self._camera.data.lens = 16
else:
self._error("Oculus not connected")
def _error(self, message):
self._report({'ERROR'}, message)
self._available = False
def update(self):
# update the camera
matrix = self._getMatrix()
if not matrix:
return
self._camera.matrix_world = self._matrix_world * matrix
def quit(self):
from oculusvr import Hmd
if self._camera:
self._camera.matrix_world = self._matrix_world
self._camera.data.lens = self._lens
if Hmd.detect() == 1:
self._hmd.destroy()
self._hmd = None
Hmd.shutdown()
def _setVersion(self, product_name):
try:
if product_name.find(b'DK2') != -1:
self._version = 2
elif product_name.find(b'DK1') != -1:
self._version = 1
else:
raise Exception
except:
print("Error guessing device version (\"{0}\")".format(product_name))
@property
def shader_file(self):
if self._version == 1:
return 'oculus_dk1.glsl'
else:
return 'oculus_dk2.glsl'
def _getMatrix(self):
from oculusvr import Hmd
from mathutils import (
Quaternion,
Matrix,
)
if self._hmd and Hmd.detect() == 1:
self._frame += 1
poses = self._hmd.get_eye_poses(self._frame, self._eyes_offset)
# oculus may be returning the matrix for both eyes
# but we are using a single eye without offset
rotation_raw = poses[0].Orientation.toList()
position_raw = poses[0].Position.toList()
rotation = Quaternion(rotation_raw).to_matrix().to_4x4()
position = Matrix.Translation(position_raw)
matrix = position * rotation
return matrix
return None
opengl_helper.py 0000664 0000000 0000000 00000015771 12574032016 0034602 0 ustar 00root root 0000000 0000000 virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality import bpy
from bgl import *
from mathutils import Matrix, Euler
SpaceView3D = bpy.types.SpaceView3D
callback_handle = []
fragment_shader ="""
#version 120
uniform sampler2D color_buffer;
void main(void)
{
vec2 coords = gl_TexCoord[0].st;
vec4 foreground = texture2D(color_buffer, coords);
gl_FragColor = mix(foreground, vec4(1.0, 0.0, 0.0, 1.0), 0.5);
}
"""
# ##################
# GLSL Debug
# ##################
def print_shader_errors(shader):
""""""
log = Buffer(GL_BYTE, len(fragment_shader))
length = Buffer(GL_INT, 1)
print('Shader Code:')
glGetShaderSource(shader, len(log), length, log)
line = 1
msg = " 1 "
for i in range(length[0]):
if chr(log[i-1]) == '\n':
line += 1
msg += "%3d %s" %(line, chr(log[i]))
else:
msg += chr(log[i])
print(msg)
glGetShaderInfoLog(shader, len(log), length, log)
print("Error in GLSL Shader:\n")
msg = ""
for i in range(length[0]):
msg += chr(log[i])
print (msg)
def print_program_errors(program):
""""""
log = Buffer(GL_BYTE, 1024)
length = Buffer(GL_INT, 1)
glGetProgramInfoLog(program, len(log), length, log)
print("Error in GLSL Program:\n")
msg = ""
for i in range(length[0]):
msg += chr(log[i])
print (msg)
# ######################
# OpenGL Image Routines
# ######################
def resize(self, context):
"""we can run every frame or only when width/height change"""
# remove old textures
self.quit()
self.width = context.region.width
self.height = context.region.height
self.buffer_width, self.buffer_height = calculate_image_size(self.width, self.height)
# image to dump screen
self.color_id = create_image(self.buffer_width, self.buffer_height, GL_RGBA)
def calculate_image_size(width, height):
"""get a power of 2 size"""
buffer_width, buffer_height = 0,0
i = 0
while (1 << i) <= width:i+= 1
buffer_width = 1 << i
i = 0
while (1 << i) <= height:i+= 1
buffer_height = 1 << i
return buffer_width, buffer_height
def update_image(tex_id, viewport, target=GL_RGBA, texture=GL_TEXTURE0):
"""copy the current buffer to the image"""
glActiveTexture(texture)
glBindTexture(GL_TEXTURE_2D, tex_id)
glCopyTexImage2D(GL_TEXTURE_2D, 0, target, viewport[0], viewport[1], viewport[2], viewport[3], 0)
def create_image(width, height, target=GL_RGBA):
"""create an empty image, dimensions pow2"""
if target == GL_RGBA:
target, internal_format, dimension = GL_RGBA, GL_RGB, 3
else:
target, internal_format, dimension = GL_DEPTH_COMPONENT32, GL_DEPTH_COMPONENT, 1
null_buffer = Buffer(GL_BYTE, [(width + 1) * (height + 1) * dimension])
id_buf = Buffer(GL_INT, 1)
glGenTextures(1, id_buf)
tex_id = id_buf.to_list()[0]
glBindTexture(GL_TEXTURE_2D, tex_id)
glTexImage2D(GL_TEXTURE_2D, 0, target, width, height, 0, internal_format, GL_UNSIGNED_BYTE, null_buffer)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
if target == GL_DEPTH_COMPONENT32:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE)
glCopyTexImage2D(GL_TEXTURE_2D, 0, target, 0, 0, width, height, 0)
glBindTexture(GL_TEXTURE_2D, 0)
del null_buffer
return tex_id
def delete_image(tex_id):
"""clear created image"""
id_buf = Buffer(GL_INT, 1)
id_buf.to_list()[0] = tex_id
if glIsTexture(tex_id):
glDeleteTextures(1, id_buf)
# ##################
# GLSL Screen Shader
# ##################
def create_shader(source, program=None, type=GL_FRAGMENT_SHADER):
""""""
if program == None:
program = glCreateProgram()
shader = glCreateShader(type)
glShaderSource(shader, source)
glCompileShader(shader)
success = Buffer(GL_INT, 1)
glGetShaderiv(shader, GL_COMPILE_STATUS, success)
if not success[0]:
print_shader_errors(shader)
glAttachShader(program, shader)
glLinkProgram(program)
return program
def setup_uniforms(program, color_id, width, height, is_left):
""""""
uniform = glGetUniformLocation(program, "bgl_RenderedTexture")
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, color_id)
if uniform != -1: glUniform1i(uniform, 0)
uniform = glGetUniformLocation(program, "bgl_RenderedTextureWidth")
if uniform != -1: glUniform1f(uniform, width)
uniform = glGetUniformLocation(program, "bgl_RenderedTextureHeight")
if uniform != -1: glUniform1f(uniform, height)
uniform = glGetUniformLocation(program, "bgl_RenderedStereoEye")
if uniform != -1: glUniform1f(uniform, 0 if is_left else 1)
def bindcode(image):
"""load the image in the graphic card if necessary"""
image.gl_touch(GL_NEAREST)
return image.bindcode
# ##################
# Drawing Routines
# ##################
def view_setup():
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glMatrixMode(GL_TEXTURE)
glPushMatrix()
glLoadIdentity()
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
glOrtho(-1, 1, -1, 1, -20, 20)
gluLookAt(0.0, 0.0, 1.0, 0.0,0.0,0.0, 0.0,1.0,0.0)
def view_reset(viewport):
# Get texture info
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_TEXTURE)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
def draw_rectangle(zed=0.0):
texco = [(1, 1), (0, 1), (0, 0), (1,0)]
verco = [(1.0, 1.0), (-1.0, 1.0), (-1.0, -1.0), ( 1.0, -1.0)]
glPolygonMode(GL_FRONT_AND_BACK , GL_FILL)
glBegin(GL_QUADS)
for i in range(4):
glColor4f(1.0, 1.0, 1.0, 0.0)
glTexCoord3f(texco[i][0], texco[i][1], zed)
glVertex2f(verco[i][0], verco[i][1])
glEnd()
def draw_callback_px(self, context):
"""core function"""
if not self._enabled: return
is_left = self.is_stereo_left(context)
act_tex = Buffer(GL_INT, 1)
glGetIntegerv(GL_ACTIVE_TEXTURE, act_tex)
glGetIntegerv(GL_VIEWPORT, self.viewport)
# (1) dump buffer in texture
update_image(self.color_id, self.viewport, GL_RGBA, GL_TEXTURE0)
# (2) run screenshader
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
pjm = Buffer(GL_FLOAT, 16)
mvm = Buffer(GL_FLOAT, 16)
cam_pos = context.scene.camera.location.copy()
glMatrixMode(GL_MODELVIEW)
glTranslatef(cam_pos[0], cam_pos[1], cam_pos[2])
glGetFloatv(GL_PROJECTION_MATRIX, pjm)
glGetFloatv(GL_MODELVIEW_MATRIX, mvm)
# set identity matrices
view_setup()
# update shader
glUseProgram(self.program_shader)
setup_uniforms(self.program_shader, self.color_id, self.width, self.height, is_left)
draw_rectangle()
# (3) restore opengl defaults
glUseProgram(0)
glActiveTexture(act_tex[0])
glBindTexture(GL_TEXTURE_2D, 0)
view_reset(self.viewport)
glMatrixMode(GL_MODELVIEW)
glTranslatef(-cam_pos[0], -cam_pos[1], -cam_pos[2])
shaders/ 0000775 0000000 0000000 00000000000 12574032016 0033023 5 ustar 00root root 0000000 0000000 virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality oculus_dk1.glsl 0000664 0000000 0000000 00000004457 12574032016 0035771 0 ustar 00root root 0000000 0000000 virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality/shaders // Oculus DK1 lens distortion shader for multiple eyes
// shader is adapted from Oculus DK1 distortion shader by
// Lubosz Sarnecki(lubosz.wordpress.com/)
uniform sampler2D bgl_RenderedTexture;
uniform float bgl_RenderedTextureWidth;
uniform float bgl_RenderedTextureHeight;
const vec4 kappa = vec4(1.0,1.7,0.7,15.0);
float screen_width = bgl_RenderedTextureWidth;
float screen_height = bgl_RenderedTextureHeight;
const float scaleFactor = 0.8;
const vec2 leftCenter = vec2(0.25, 0.5);
const vec2 rightCenter = vec2(0.75, 0.5);
const float separation = 0.01;
// Scales input texture coordinates for distortion.
vec2 hmdWarp(vec2 LensCenter, vec2 texCoord, vec2 Scale, vec2 ScaleIn) {
vec2 theta = (texCoord - LensCenter) * ScaleIn;
float rSq = theta.x * theta.x + theta.y * theta.y;
vec2 rvector = theta * (kappa.x +
kappa.y * rSq +
kappa.z * rSq * rSq +
kappa.w * rSq * rSq * rSq);
vec2 tc = LensCenter + Scale * rvector;
return tc;
}
bool validate(vec2 tc, int left_eye) {
//keep within bounds of texture
if ((left_eye == 1 && (tc.x < 0.0 || tc.x > 0.5)) ||
(left_eye == 0 && (tc.x < 0.5 || tc.x > 1.0)) ||
tc.y < 0.0 || tc.y > 1.0) {
return false;
}
return true;
}
void main() {
vec2 screen = vec2(screen_width, screen_height);
float as = float(screen.x / 2.0) / float(screen.y);
vec2 Scale = vec2(0.5, as);
vec2 ScaleIn = vec2(2.0 * scaleFactor, 1.0 / as * scaleFactor);
vec2 texCoord = gl_TexCoord[0].st;
vec2 texCoordSeparated = texCoord;
vec2 tc = vec2(0);
vec4 color = vec4(0);
// ad hoc enhanced separation to allow proper viewing factor
float ad_hoc_enhance_stereo = 4.0;
if (texCoord.x < 0.5) {
texCoordSeparated.x -= ad_hoc_enhance_stereo *separation;
tc = hmdWarp(leftCenter, texCoordSeparated, Scale, ScaleIn );
color = texture2D(bgl_RenderedTexture, tc);
if (!validate(tc, 1))
color = vec4(0);
} else {
texCoordSeparated.x += ad_hoc_enhance_stereo *separation;
tc = hmdWarp(rightCenter, texCoordSeparated, Scale, ScaleIn);
color = texture2D(bgl_RenderedTexture, tc);
if (!validate(tc, 0))
color = vec4(0);
}
gl_FragColor = color;
}
oculus_dk2.glsl 0000664 0000000 0000000 00000003606 12574032016 0035765 0 ustar 00root root 0000000 0000000 virtual_reality_viewport-97af8d18cbf9b263c8a771909f5657b63908b8b6/space_view3d_virtual_reality/shaders // Oculus DK2 lens distortion shader for single eye
// shader is adapted from Oculus DK1 distortion shader by
// Lubosz Sarnecki(lubosz.wordpress.com/)
uniform sampler2D bgl_RenderedTexture;
uniform float bgl_RenderedTextureWidth;
uniform float bgl_RenderedTextureHeight;
const vec4 kappa = vec4(1.0,0.9,1.0,2.0);
float screen_width = bgl_RenderedTextureWidth;
float screen_height = bgl_RenderedTextureHeight;
const float scaleFactor = 0.83;
const vec2 lensCenter = vec2(0.5, 0.5);
// Scales input texture coordinates for distortion.
vec2 hmdWarp(vec2 texCoord, vec2 Scale, vec2 ScaleIn, float eta) {
vec2 theta = (texCoord - lensCenter) * ScaleIn;
float rSq = theta.x * theta.x + theta.y * theta.y;
vec2 rvector = theta * (kappa.x + kappa.y * rSq + kappa.z * rSq * rSq + kappa.w * rSq * rSq * rSq);
vec2 tc = lensCenter + Scale * eta * rvector;
return tc;
}
float edges(vec2 tc)
{
float vertL = smoothstep(0.0,0.05,tc.x);
float vertR = smoothstep(1.0,0.95,tc.x);
float horizL = smoothstep(0.0,0.05,tc.y);
float horizR = smoothstep(1.0,0.95,tc.y);
return vertL*vertR*horizL*horizR;
}
void main()
{
vec2 screen = vec2(screen_width, screen_height);
vec3 eta = vec3(1.00,1.018,1.042); //refraction indices
float as = float(screen.x) / float(screen.y);
vec2 Scale = vec2(1.0, 1.0);
vec2 ScaleIn = vec2(scaleFactor, scaleFactor);
vec2 texCoord = gl_TexCoord[0].st;
vec2 tcR = vec2(0.0);
vec2 tcG = vec2(0.0);
vec2 tcB = vec2(0.0);
vec4 color = vec4(0.0);
tcR = hmdWarp(texCoord, Scale, ScaleIn, eta.r );
tcG = hmdWarp(texCoord, Scale, ScaleIn, eta.g );
tcB = hmdWarp(texCoord, Scale, ScaleIn, eta.b );
color.r = texture2D(bgl_RenderedTexture, tcR*vec2(0.5,1.0)+vec2(0.25,0.0)).r;
color.g = texture2D(bgl_RenderedTexture, tcG*vec2(0.5,1.0)+vec2(0.25,0.0)).g;
color.b = texture2D(bgl_RenderedTexture, tcB*vec2(0.5,1.0)+vec2(0.25,0.0)).b;
color = color * edges(tcR);
gl_FragColor = color;
}