mittsu 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +3 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/Rakefile +7 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/examples/01_-_Default1noCulling.png +0 -0
- data/examples/01_scene_example.rb +14 -0
- data/examples/02_box_mesh_example.rb +30 -0
- data/examples/02_sphere_mesh_example.rb +30 -0
- data/examples/03_complex_object_example.rb +52 -0
- data/examples/04_ambient_light_example.rb +33 -0
- data/examples/04_dir_light_example.rb +36 -0
- data/examples/04_hemi_light_example.rb +30 -0
- data/examples/04_point_light_example.rb +50 -0
- data/examples/04_spot_light_example.rb +44 -0
- data/examples/05_earth_example.rb +42 -0
- data/examples/05_earth_moon_example.rb +46 -0
- data/examples/05_texture_example.rb +32 -0
- data/examples/06_cube_texture_example.rb +36 -0
- data/examples/06_skybox_example.rb +60 -0
- data/examples/07_earth_normal_example.rb +36 -0
- data/examples/08_shadow_example.rb +87 -0
- data/examples/09_line_example.rb +52 -0
- data/examples/10_obj_loader_example.rb +68 -0
- data/examples/11_character_input_example.rb +18 -0
- data/examples/11_continuous_keyboard_input_example.rb +35 -0
- data/examples/11_keyboard_input_example.rb +43 -0
- data/examples/12_mouse_click_example.rb +38 -0
- data/examples/12_mouse_motion_example.rb +35 -0
- data/examples/12_mouse_scroll_example.rb +36 -0
- data/examples/12_orbit_zoom_example.rb +68 -0
- data/examples/13_joystick_example.rb +80 -0
- data/examples/cubemap/tron_bk.png +0 -0
- data/examples/cubemap/tron_dn.png +0 -0
- data/examples/cubemap/tron_ft.png +0 -0
- data/examples/cubemap/tron_lf.png +0 -0
- data/examples/cubemap/tron_rt.png +0 -0
- data/examples/cubemap/tron_up.png +0 -0
- data/examples/earth.png +0 -0
- data/examples/earth_normal.png +0 -0
- data/examples/example_helper.rb +2 -0
- data/examples/male-02-1noCulling.png +0 -0
- data/examples/male02.mtl +54 -0
- data/examples/male02.obj +13888 -0
- data/examples/moon.png +0 -0
- data/examples/orig_02_-_Defaul1noCulling.png +0 -0
- data/examples/texture.png +0 -0
- data/lib/mittsu.rb +15 -0
- data/lib/mittsu/cameras.rb +4 -0
- data/lib/mittsu/cameras/camera.rb +34 -0
- data/lib/mittsu/cameras/cube_camera.rb +74 -0
- data/lib/mittsu/cameras/orthographic_camera.rb +53 -0
- data/lib/mittsu/cameras/perspective_camera.rb +115 -0
- data/lib/mittsu/constants.rb +160 -0
- data/lib/mittsu/core.rb +10 -0
- data/lib/mittsu/core/buffer_attribute.rb +87 -0
- data/lib/mittsu/core/buffer_geometry.rb +694 -0
- data/lib/mittsu/core/clock.rb +44 -0
- data/lib/mittsu/core/dynamic_buffer_attribute.rb +16 -0
- data/lib/mittsu/core/event_dispatcher.rb +39 -0
- data/lib/mittsu/core/face3.rb +30 -0
- data/lib/mittsu/core/geometry.rb +596 -0
- data/lib/mittsu/core/hash_array.rb +36 -0
- data/lib/mittsu/core/hash_object.rb +19 -0
- data/lib/mittsu/core/object_3d.rb +421 -0
- data/lib/mittsu/core/raycaster.rb +78 -0
- data/lib/mittsu/extras.rb +3 -0
- data/lib/mittsu/extras/geometries.rb +2 -0
- data/lib/mittsu/extras/geometries/box_geometry.rb +108 -0
- data/lib/mittsu/extras/geometries/sphere_geometry.rb +88 -0
- data/lib/mittsu/extras/helpers.rb +1 -0
- data/lib/mittsu/extras/helpers/camera_helper.rb +155 -0
- data/lib/mittsu/extras/image.rb +3 -0
- data/lib/mittsu/extras/image_utils.rb +80 -0
- data/lib/mittsu/lights.rb +7 -0
- data/lib/mittsu/lights/ambient_light.rb +16 -0
- data/lib/mittsu/lights/area_light.rb +24 -0
- data/lib/mittsu/lights/directional_light.rb +131 -0
- data/lib/mittsu/lights/hemisphere_light.rb +29 -0
- data/lib/mittsu/lights/light.rb +21 -0
- data/lib/mittsu/lights/point_light.rb +27 -0
- data/lib/mittsu/lights/spot_light.rb +104 -0
- data/lib/mittsu/loaders.rb +7 -0
- data/lib/mittsu/loaders/cache.rb +53 -0
- data/lib/mittsu/loaders/file_loader.rb +22 -0
- data/lib/mittsu/loaders/image_loader.rb +32 -0
- data/lib/mittsu/loaders/loader.rb +212 -0
- data/lib/mittsu/loaders/loading_manager.rb +17 -0
- data/lib/mittsu/loaders/mtl_loader.rb +242 -0
- data/lib/mittsu/loaders/obj_mtl_loader.rb +225 -0
- data/lib/mittsu/materials.rb +7 -0
- data/lib/mittsu/materials/line_basic_material.rb +39 -0
- data/lib/mittsu/materials/material.rb +156 -0
- data/lib/mittsu/materials/mesh_basic_material.rb +122 -0
- data/lib/mittsu/materials/mesh_face_material.rb +30 -0
- data/lib/mittsu/materials/mesh_lambert_material.rb +126 -0
- data/lib/mittsu/materials/mesh_phong_material.rb +152 -0
- data/lib/mittsu/materials/shader_material.rb +108 -0
- data/lib/mittsu/math.rb +105 -0
- data/lib/mittsu/math/box2.rb +135 -0
- data/lib/mittsu/math/box3.rb +194 -0
- data/lib/mittsu/math/color.rb +252 -0
- data/lib/mittsu/math/color_keywords.rb +151 -0
- data/lib/mittsu/math/euler.rb +182 -0
- data/lib/mittsu/math/frustum.rb +106 -0
- data/lib/mittsu/math/line3.rb +76 -0
- data/lib/mittsu/math/matrix3.rb +163 -0
- data/lib/mittsu/math/matrix4.rb +581 -0
- data/lib/mittsu/math/plane.rb +128 -0
- data/lib/mittsu/math/quaternion.rb +309 -0
- data/lib/mittsu/math/ray.rb +292 -0
- data/lib/mittsu/math/sphere.rb +91 -0
- data/lib/mittsu/math/spline.rb +128 -0
- data/lib/mittsu/math/triangle.rb +121 -0
- data/lib/mittsu/math/vector2.rb +238 -0
- data/lib/mittsu/math/vector3.rb +491 -0
- data/lib/mittsu/math/vector4.rb +414 -0
- data/lib/mittsu/objects.rb +3 -0
- data/lib/mittsu/objects/group.rb +8 -0
- data/lib/mittsu/objects/line.rb +143 -0
- data/lib/mittsu/objects/mesh.rb +243 -0
- data/lib/mittsu/renderers.rb +1 -0
- data/lib/mittsu/renderers/glfw_window.rb +216 -0
- data/lib/mittsu/renderers/opengl/opengl_debug.rb +38 -0
- data/lib/mittsu/renderers/opengl/opengl_program.rb +402 -0
- data/lib/mittsu/renderers/opengl/opengl_shader.rb +58 -0
- data/lib/mittsu/renderers/opengl/opengl_state.rb +207 -0
- data/lib/mittsu/renderers/opengl/plugins/shadow_map_plugin.rb +416 -0
- data/lib/mittsu/renderers/opengl_render_target.rb +87 -0
- data/lib/mittsu/renderers/opengl_renderer.rb +3376 -0
- data/lib/mittsu/renderers/shaders/shader_chunk.rb +12 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/alphamap_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/alphamap_pars_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/alphatest_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/bumpmap_pars_fragment.glsl +40 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/color_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/color_pars_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/color_pars_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/color_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/common.glsl +60 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/default_vertex.glsl +15 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/defaultnormal_vertex.glsl +21 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/envmap_fragment.glsl +62 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/envmap_pars_fragment.glsl +21 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/envmap_pars_vertex.glsl +7 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/envmap_vertex.glsl +17 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/fog_fragment.glsl +26 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/fog_pars_fragment.glsl +15 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_pars_fragment.glsl +6 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_pars_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lightmap_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_lambert_pars_vertex.glsl +43 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_lambert_vertex.glsl +196 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_fragment.glsl +243 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_pars_fragment.glsl +58 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_pars_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/lights_phong_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/linear_to_gamma_fragment.glsl +2 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl +12 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl +11 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/logdepthbuf_vertex.glsl +15 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_fragment.glsl +9 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_pars_fragment.glsl +11 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_pars_vertex.glsl +6 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_particle_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_particle_pars_fragment.glsl +6 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/map_vertex.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/morphnormal_vertex.glsl +12 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/morphtarget_pars_vertex.glsl +13 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/morphtarget_vertex.glsl +20 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/normalmap_pars_fragment.glsl +27 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_fragment.glsl +217 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_pars_fragment.glsl +19 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_pars_vertex.glsl +6 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/shadowmap_vertex.glsl +9 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/skinbase_vertex.glsl +8 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/skinning_pars_vertex.glsl +47 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/skinning_vertex.glsl +20 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/skinnormal_vertex.glsl +20 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/specularmap_fragment.glsl +12 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/specularmap_pars_fragment.glsl +5 -0
- data/lib/mittsu/renderers/shaders/shader_chunk/worldpos_vertex.glsl +17 -0
- data/lib/mittsu/renderers/shaders/shader_lib.rb +420 -0
- data/lib/mittsu/renderers/shaders/uniforms_lib.rb +107 -0
- data/lib/mittsu/renderers/shaders/uniforms_utils.rb +31 -0
- data/lib/mittsu/scenes.rb +1 -0
- data/lib/mittsu/scenes/scene.rb +27 -0
- data/lib/mittsu/textures.rb +5 -0
- data/lib/mittsu/textures/compressed_texture.rb +30 -0
- data/lib/mittsu/textures/cube_texture.rb +19 -0
- data/lib/mittsu/textures/data_texture.rb +17 -0
- data/lib/mittsu/textures/texture.rb +92 -0
- data/lib/mittsu/textures/video_texture.rb +17 -0
- data/lib/mittsu/version.rb +4 -0
- data/mittsu.gemspec +31 -0
- metadata +357 -0
@@ -0,0 +1,207 @@
|
|
1
|
+
module Mittsu
|
2
|
+
class OpenGLState
|
3
|
+
def initialize(param_mittsu_to_gl)
|
4
|
+
@param_mittsu_to_gl = param_mittsu_to_gl
|
5
|
+
|
6
|
+
@new_attributes = Array.new(16) # Uint8Array
|
7
|
+
@enabled_attributes = Array.new(16) # Uint8Array
|
8
|
+
|
9
|
+
@current_blending = nil
|
10
|
+
@current_blend_equation = nil
|
11
|
+
@current_blend_src = nil
|
12
|
+
@current_blend_dst = nil
|
13
|
+
@current_blend_equation_alpha = nil
|
14
|
+
@current_blend_src_alpha = nil
|
15
|
+
@current_blend_dst_alpha = nil
|
16
|
+
|
17
|
+
@current_depth_test = nil
|
18
|
+
@current_depth_write = nil
|
19
|
+
|
20
|
+
@current_color_write = nil
|
21
|
+
|
22
|
+
@current_double_sided = nil
|
23
|
+
@current_flip_sided = nil
|
24
|
+
|
25
|
+
@current_line_width = nil
|
26
|
+
|
27
|
+
@current_polygon_offset = nil
|
28
|
+
@current_polygon_offset_factor = nil
|
29
|
+
@current_polygon_offset_units = nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def init_attributes
|
33
|
+
@new_attributes.length.times do |i|
|
34
|
+
@new_attributes[i] = false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def enable_attribute(attribute)
|
39
|
+
glEnableVertexAttribArray(attribute)
|
40
|
+
@new_attributes[attribute] = true
|
41
|
+
|
42
|
+
if !@enabled_attributes[attribute]
|
43
|
+
# glEnableVertexAttribArray(attribute)
|
44
|
+
@enabled_attributes[attribute] = true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def disable_unused_attributes
|
49
|
+
@enabled_attributes.length.times do |i|
|
50
|
+
if @enabled_attributes[i] && !@new_attributes[i]
|
51
|
+
glDisableVertexAttribArray(i)
|
52
|
+
@enabled_attributes[i] = false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_blending(blending, blend_equation = nil, blend_src = nil, blend_dst = nil, blend_equation_alpha = nil, blend_src_alpha = nil, blend_dst_alpha = nil)
|
58
|
+
if blending != @current_blending
|
59
|
+
case blending
|
60
|
+
when NoBlending
|
61
|
+
glDisable(GL_BLEND)
|
62
|
+
when AdditiveBlending
|
63
|
+
glEnable(GL_BLEND)
|
64
|
+
glBlendEquation(GL_FUNC_ADD)
|
65
|
+
glBlendFunc(GL_SRC_ALPHA, GL_ONE)
|
66
|
+
when SubtractiveBlending
|
67
|
+
# TODO: Find blendFuncSeparate() combination ???
|
68
|
+
glEnable(GL_BLEND)
|
69
|
+
glBlendEquation(GL_FUNC_ADD)
|
70
|
+
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR)
|
71
|
+
when MultiplyBlending
|
72
|
+
# TODO: Find blendFuncSeparate() combination ???
|
73
|
+
glEnable(GL_BLEND)
|
74
|
+
glBlendEquation(GL_FUNC_ADD)
|
75
|
+
glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR)
|
76
|
+
when CustomBlending
|
77
|
+
glEnable(GL_BLEND)
|
78
|
+
else
|
79
|
+
glEnable(GL_BLEND)
|
80
|
+
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD)
|
81
|
+
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
|
82
|
+
end
|
83
|
+
|
84
|
+
@current_blending = blending
|
85
|
+
end
|
86
|
+
|
87
|
+
if blending == CustomBlending
|
88
|
+
blend_equation_alpha ||= blend_equation
|
89
|
+
blend_src_alpha ||= blend_src
|
90
|
+
blend_dst_alpha ||= blend_dst
|
91
|
+
|
92
|
+
if blend_equation != @current_blend_equation || blend_equation_alpha != @current_blend_equation_alpha
|
93
|
+
glBlendEquationSeparate(@param_mittsu_to_gl[blend_equation], @param_mittsu_to_gl[blend_equation_alpha])
|
94
|
+
|
95
|
+
@current_blend_equation = blend_equation
|
96
|
+
@current_blend_equation_alpha = blend_equation_alpha
|
97
|
+
end
|
98
|
+
|
99
|
+
if blend_src != @current_blend_src || blend_dst != @current_blend_dst || blend_src_alpha != @current_blend_src_alpha || blend_dst_alpha != @current_blend_dst_alpha
|
100
|
+
glBlendFuncSeparate(@param_mittsu_to_gl[blend_src], @param_mittsu_to_gl[blend_dst], @param_mittsu_to_gl[blend_src_alpha], @param_mittsu_to_gl[blend_dst_alpha])
|
101
|
+
|
102
|
+
@current_blend_src = nil
|
103
|
+
@current_blend_dst = nil
|
104
|
+
@current_blend_src_alpha = nil
|
105
|
+
@current_blend_dst_alpha = nil
|
106
|
+
end
|
107
|
+
else
|
108
|
+
@current_blend_equation = nil
|
109
|
+
@current_blend_src = nil
|
110
|
+
@current_blend_dst = nil
|
111
|
+
@current_blend_equation_alpha = nil
|
112
|
+
@current_blend_src_alpha = nil
|
113
|
+
@current_blend_dst_alpha = nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def set_depth_test(depth_test)
|
118
|
+
if @current_depth_test != depth_test
|
119
|
+
if depth_test
|
120
|
+
glEnable(GL_DEPTH_TEST)
|
121
|
+
else
|
122
|
+
glDisable(GL_DEPTH_TEST)
|
123
|
+
end
|
124
|
+
|
125
|
+
@current_depth_test = depth_test
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def set_depth_write(depth_write)
|
130
|
+
if @current_depth_write != depth_write
|
131
|
+
glDepthMask(depth_write ? GL_TRUE : GL_FALSE)
|
132
|
+
@current_depth_write = depth_write
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def set_color_write(color_write)
|
137
|
+
if @current_color_write != color_write
|
138
|
+
gl_color_write = color_write ? GL_TRUE : GL_FALSE
|
139
|
+
glColorMask(gl_color_write, gl_color_write, gl_color_write, gl_color_write)
|
140
|
+
@current_color_write = color_write
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def set_double_sided(double_sided)
|
145
|
+
if @current_double_sided != double_sided
|
146
|
+
if double_sided
|
147
|
+
glDisable(GL_CULL_FACE)
|
148
|
+
else
|
149
|
+
glEnable(GL_CULL_FACE)
|
150
|
+
end
|
151
|
+
|
152
|
+
@current_double_sided = double_sided
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def set_flip_sided(flip_sided)
|
157
|
+
if @current_flip_sided != flip_sided
|
158
|
+
if flip_sided
|
159
|
+
glFrontFace(GL_CW)
|
160
|
+
else
|
161
|
+
glFrontFace(GL_CCW)
|
162
|
+
end
|
163
|
+
|
164
|
+
@current_flip_sided = flip_sided
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def set_line_width(width)
|
169
|
+
if width != @current_line_width
|
170
|
+
glLineWidth(width)
|
171
|
+
@current_line_width = width
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def set_polygon_offset(polygon_offset, factor, units)
|
176
|
+
if @current_polygon_offset != polygon_offset
|
177
|
+
if polygon_offset
|
178
|
+
glEnable(GL_POLYGON_OFFSET_FILL)
|
179
|
+
else
|
180
|
+
glDisable(GL_POLYGON_OFFSET_FILL)
|
181
|
+
end
|
182
|
+
|
183
|
+
@current_polygon_offset = polygon_offset
|
184
|
+
end
|
185
|
+
|
186
|
+
if polygon_offset && (@current_polygon_offset_factor != factor || @current_polygon_offset_units != units)
|
187
|
+
glPolygonOffset(factor, units)
|
188
|
+
|
189
|
+
@current_polygon_offset_factor = factor
|
190
|
+
@current_polygon_offset_units = units
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def reset
|
195
|
+
@enabled_attributes.length.times do |i|
|
196
|
+
@enabled_attributes[i] = false
|
197
|
+
end
|
198
|
+
|
199
|
+
@current_blending = nil
|
200
|
+
@current_depth_test = nil
|
201
|
+
@current_depth_write = nil
|
202
|
+
@current_color_write = nil
|
203
|
+
@current_double_sided = nil
|
204
|
+
@current_flip_sided = nil
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,416 @@
|
|
1
|
+
require 'mittsu/math'
|
2
|
+
require 'mittsu/renderers/opengl_render_target'
|
3
|
+
|
4
|
+
module Mittsu
|
5
|
+
class ShadowMapPlugin
|
6
|
+
def initialize(renderer, lights, opengl_objects, opengl_objects_immediate)
|
7
|
+
@renderer, @lights = renderer, lights
|
8
|
+
@opengl_objects = opengl_objects
|
9
|
+
@opengl_objects_immediate = opengl_objects_immediate
|
10
|
+
|
11
|
+
@frustum = Frustum.new
|
12
|
+
@proj_screen_matrix = Matrix4.new
|
13
|
+
|
14
|
+
@min = Vector3.new
|
15
|
+
@max = Vector3.new
|
16
|
+
|
17
|
+
@matrix_position = Vector3.new
|
18
|
+
|
19
|
+
@render_list = []
|
20
|
+
|
21
|
+
depth_shader = ShaderLib[:depth_rgba]
|
22
|
+
depth_uniforms = UniformsUtils.clone(depth_shader.uniforms)
|
23
|
+
|
24
|
+
@depth_material = ShaderMaterial.new(
|
25
|
+
uniforms: depth_uniforms,
|
26
|
+
vertex_shader: depth_shader.vertex_shader,
|
27
|
+
fragment_shader: depth_shader.fragment_shader
|
28
|
+
)
|
29
|
+
|
30
|
+
@depth_material_morph = ShaderMaterial.new(
|
31
|
+
uniforms: depth_uniforms,
|
32
|
+
vertex_shader: depth_shader.vertex_shader,
|
33
|
+
fragment_shader: depth_shader.fragment_shader,
|
34
|
+
morph_targets: true
|
35
|
+
)
|
36
|
+
|
37
|
+
@depth_material_skin = ShaderMaterial.new(
|
38
|
+
uniforms: depth_uniforms,
|
39
|
+
vertex_shader: depth_shader.vertex_shader,
|
40
|
+
fragment_shader: depth_shader.fragment_shader,
|
41
|
+
skinning: true
|
42
|
+
)
|
43
|
+
|
44
|
+
@depth_material_morph_skin = ShaderMaterial.new(
|
45
|
+
uniforms: depth_uniforms,
|
46
|
+
vertex_shader: depth_shader.vertex_shader,
|
47
|
+
fragment_shader: depth_shader.fragment_shader,
|
48
|
+
morph_targets: true,
|
49
|
+
skinning: true
|
50
|
+
)
|
51
|
+
|
52
|
+
@depth_material[:_shadow_pass] = true
|
53
|
+
@depth_material_morph[:_shadow_pass] = true
|
54
|
+
@depth_material_skin[:_shadow_pass] = true
|
55
|
+
@depth_material_morph_skin[:_shadow_pass] = true
|
56
|
+
end
|
57
|
+
|
58
|
+
def render(scene, camera)
|
59
|
+
return unless @renderer.shadow_map_enabled
|
60
|
+
|
61
|
+
lights = []
|
62
|
+
fog = nil
|
63
|
+
|
64
|
+
# set GL state for depth map
|
65
|
+
|
66
|
+
glClearColor(1.0, 1.0, 1.0, 1.0)
|
67
|
+
glDisable(GL_BLEND)
|
68
|
+
|
69
|
+
glEnable(GL_CULL_FACE)
|
70
|
+
glFrontFace(GL_CCW)
|
71
|
+
|
72
|
+
if @renderer.shadow_map_cull_face = CullFaceFront
|
73
|
+
glCullFace(GL_FRONT)
|
74
|
+
else
|
75
|
+
glCullFace(GL_BACK)
|
76
|
+
end
|
77
|
+
|
78
|
+
@renderer.state.set_depth_test(true)
|
79
|
+
|
80
|
+
# process lights
|
81
|
+
# - skip lights that are not casting shadows
|
82
|
+
# - create virtual lights for cascaded shadow maps
|
83
|
+
|
84
|
+
@lights.select(&:cast_shadow).each do |light|
|
85
|
+
if light.is_a?(DirectionalLight) && light.shadow_cascade
|
86
|
+
light.shadow_cascade_count.times do |n|
|
87
|
+
if !light.shadow_cascade_array[n]
|
88
|
+
virtual_light = create_virtual_light(light, n)
|
89
|
+
virtual_light.original_camera = camera
|
90
|
+
|
91
|
+
gyro = Gyroscope.new
|
92
|
+
gyro.position.copy(light.shadow_cascade_offset)
|
93
|
+
|
94
|
+
gyro.add(virtual_light)
|
95
|
+
gyro.add(virtual_light.target)
|
96
|
+
|
97
|
+
camera.add(gyro)
|
98
|
+
|
99
|
+
light.shadow_cascade_array[n] = virtual_light
|
100
|
+
else
|
101
|
+
virtual_light = light.shadow_cascade_array[n]
|
102
|
+
end
|
103
|
+
|
104
|
+
update_virtual_light(light, n)
|
105
|
+
|
106
|
+
lights << virtual_light
|
107
|
+
end
|
108
|
+
else
|
109
|
+
lights << light
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# render depth map
|
114
|
+
|
115
|
+
lights.each do |light|
|
116
|
+
if !light.shadow_map
|
117
|
+
shadow_filter = LinearFilter
|
118
|
+
if @renderer.shadow_map_type == PCFSoftShadowMap
|
119
|
+
shadow_filter = NearestFilter
|
120
|
+
end
|
121
|
+
|
122
|
+
pars = { min_filter: shadow_filter, mag_filter: shadow_filter, format: RGBAFormat }
|
123
|
+
|
124
|
+
light.shadow_map = OpenGLRenderTarget.new(light.shadow_map_width, light.shadow_map_height, pars)
|
125
|
+
light.shadow_map_size = Vector2.new(light.shadow_map_width, light.shadow_map_height)
|
126
|
+
|
127
|
+
light.shadow_matrix = Matrix4.new
|
128
|
+
end
|
129
|
+
|
130
|
+
if !light.shadow_camera
|
131
|
+
case light
|
132
|
+
when SpotLight
|
133
|
+
light.shadow_camera = PerspectiveCamera.new(light.shadow_camera_fov, light.shadow_map_width / light.shadow_map_height, light.shadow_camera_near, light.shadow_camera_far)
|
134
|
+
when DirectionalLight
|
135
|
+
light.shadow_camera = OrthographicCamera.new(light.shadow_camera_left, light.shadow_camera_right, light.shadow_camera_top, light.shadow_camera_bottom, light.shadow_camera_near, light.shadow_camera_far)
|
136
|
+
else
|
137
|
+
puts "ERROR: Mittsu::ShadowMapPlugin: Unsupported light type for shadow #{light.inspect}"
|
138
|
+
next
|
139
|
+
end
|
140
|
+
|
141
|
+
scene.add(light.shadow_camera)
|
142
|
+
scene.update_matrix_world if scene.auto_update
|
143
|
+
end
|
144
|
+
|
145
|
+
if light.shadow_camera_visible && !light[:camera_helper]
|
146
|
+
light[:camera_helper] = CameraHelper.new(light.shadow_camera)
|
147
|
+
scene.add(light[:camera_helper])
|
148
|
+
end
|
149
|
+
|
150
|
+
if light.virtual? && virtual_light.original_camera == camera
|
151
|
+
update_shadow_camera(camera, light)
|
152
|
+
end
|
153
|
+
|
154
|
+
shadow_map = light.shadow_map
|
155
|
+
shadow_matrix = light.shadow_matrix
|
156
|
+
shadow_camera = light.shadow_camera
|
157
|
+
|
158
|
+
#
|
159
|
+
|
160
|
+
shadow_camera.position.set_from_matrix_position(light.matrix_world)
|
161
|
+
@matrix_position.set_from_matrix_position(light.target.matrix_world)
|
162
|
+
shadow_camera.look_at(@matrix_position)
|
163
|
+
shadow_camera.update_matrix_world
|
164
|
+
|
165
|
+
shadow_camera.matrix_world_inverse.inverse(shadow_camera.matrix_world)
|
166
|
+
|
167
|
+
#
|
168
|
+
|
169
|
+
|
170
|
+
light[:camera_helper].visible = light.shadow_camera_visible if light[:camera_helper]
|
171
|
+
light[:camera_helper].update if light.shadow_camera_visible
|
172
|
+
|
173
|
+
# compute shadow matrix
|
174
|
+
|
175
|
+
shadow_matrix.set(
|
176
|
+
0.5, 0.0, 0.0, 0.5,
|
177
|
+
0.0, 0.5, 0.0, 0.5,
|
178
|
+
0.0, 0.0, 0.5, 0.5,
|
179
|
+
0.0, 0.0, 0.0, 1.0
|
180
|
+
)
|
181
|
+
|
182
|
+
shadow_matrix.multiply(shadow_camera.projection_matrix)
|
183
|
+
shadow_matrix.multiply(shadow_camera.matrix_world_inverse)
|
184
|
+
|
185
|
+
# update camera matrices and frustum
|
186
|
+
|
187
|
+
@proj_screen_matrix.multiply_matrices(shadow_camera.projection_matrix, shadow_camera.matrix_world_inverse)
|
188
|
+
@frustum.set_from_matrix(@proj_screen_matrix)
|
189
|
+
|
190
|
+
# render shadow map
|
191
|
+
|
192
|
+
@renderer.set_render_target(shadow_map)
|
193
|
+
@renderer.clear
|
194
|
+
|
195
|
+
# set object matrices & frustum culling
|
196
|
+
|
197
|
+
@render_list.clear
|
198
|
+
|
199
|
+
project_object(scene, scene, shadow_camera)
|
200
|
+
|
201
|
+
# render regular obejcts
|
202
|
+
|
203
|
+
@render_list.each do |opengl_object|
|
204
|
+
object = opengl_object[:object]
|
205
|
+
buffer = opengl_object[:buffer]
|
206
|
+
|
207
|
+
# culling is overridden globally for all objects
|
208
|
+
# while rendering depth map
|
209
|
+
|
210
|
+
# need to deal with MeshFaceMaterial somehow
|
211
|
+
# in that case just use the first of material.materials for now
|
212
|
+
# (proper solution would require to break objects by materials
|
213
|
+
# similarly to regular rendering and then set corresponding
|
214
|
+
# depth materials per each chunk instead of just once per object)
|
215
|
+
|
216
|
+
object_material = get_object_material(object)
|
217
|
+
|
218
|
+
# TODO: SkinnedMesh/morph_targets
|
219
|
+
# use_morphing = !object.geometry.morph_targets.nil? && !object.geometry.morph_targets.empty?
|
220
|
+
# use_skinning = object.is_a?(SkinnedMesh) && object_material.skinning
|
221
|
+
|
222
|
+
# TODO: SkinnedMesh/morph_targets
|
223
|
+
# if object.custom_depth_material
|
224
|
+
# material = object.custom_depth_material
|
225
|
+
# elsif use_skinning
|
226
|
+
# material = use_morphing ? @depth_material_morph_skin : @depth_material_skin
|
227
|
+
# elsif use_morphing
|
228
|
+
# material = @deptth_material_morph
|
229
|
+
# else
|
230
|
+
material = @depth_material
|
231
|
+
# end
|
232
|
+
|
233
|
+
@renderer.set_material_faces(object_material)
|
234
|
+
|
235
|
+
if buffer.is_a?(BufferGeometry)
|
236
|
+
@renderer.render_buffer_direct(shadow_camera, @lights, fog, material, buffer, object)
|
237
|
+
else
|
238
|
+
@renderer.render_buffer(shadow_camera, @lights, fog, material, buffer, object)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# set materices and rendr immeidate objects
|
243
|
+
|
244
|
+
@opengl_objects_immediate.each do |opengl_object_immediate|
|
245
|
+
opengl_object = opengl_object_immediate
|
246
|
+
object = opengl_object[:object]
|
247
|
+
|
248
|
+
if object.visible && object.cast_shadow
|
249
|
+
object[:_model_view_matrix].multiply_matrices(shadow_camera.matrix_womatrix_world_inverse, object.matrix_world)
|
250
|
+
@renderer.render_immediate_object(shadow_camera, @lights, fog, @depth_material, object)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
# restore GL state
|
256
|
+
|
257
|
+
clear_color = @renderer.get_clear_color
|
258
|
+
clear_alpha = @renderer.get_clear_alpha
|
259
|
+
|
260
|
+
glClearColor(clear_color.r, clear_color.g, clear_color.b, clear_alpha)
|
261
|
+
glEnable(GL_BLEND)
|
262
|
+
|
263
|
+
if @renderer.shadow_map_cull_face == CullFaceFront
|
264
|
+
glCullFace(GL_BACK)
|
265
|
+
end
|
266
|
+
|
267
|
+
@renderer.reset_gl_state
|
268
|
+
end
|
269
|
+
|
270
|
+
def project_object(scene, object, shadow_camera)
|
271
|
+
if object.visible
|
272
|
+
opengl_objects = @opengl_objects[object.id]
|
273
|
+
|
274
|
+
if opengl_objects && object.cast_shadow && (object.frustum_culled == false || @frustum.intersects_object?(object) == true)
|
275
|
+
opengl_objects.each do |opengl_object|
|
276
|
+
object[:_model_view_matrix].multiply_matrices(shadow_camera.matrix_world_inverse, object.matrix_world)
|
277
|
+
@render_list << opengl_object
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
object.children.each do |child|
|
282
|
+
project_object(scene, child, shadow_camera)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
def create_virtual_light(light, cascade)
|
288
|
+
DirectionalLight.new.tap do |virtual_light|
|
289
|
+
virtual_light.is_virtual = true
|
290
|
+
|
291
|
+
virtual_light.only_shadow = true
|
292
|
+
virtual_light.cast_shadow = true
|
293
|
+
|
294
|
+
virtual_light.shadow_camera_near = light.shadow_camera_near
|
295
|
+
virtual_light.shadow_camera_far = light.shadow_camera_far
|
296
|
+
|
297
|
+
virtual_light.shadow_camera_left = light.shadow_camera_left
|
298
|
+
virtual_light.shadow_camera_right = light.shadow_camera_right
|
299
|
+
virtual_light.shadow_camera_bottom = light.shadow_camera_bottom
|
300
|
+
virtual_light.shadow_camera_top = light.shadow_camera_top
|
301
|
+
|
302
|
+
virtual_light.shadow_camera_visible = light.shadow_camera_visible
|
303
|
+
|
304
|
+
virtual_light.shadow_darkness = light.shadow_darkness
|
305
|
+
|
306
|
+
virtual_light.shadow_darkness = light.shadow_darkness
|
307
|
+
|
308
|
+
virtual_light.shadow_bias = light.shadow_cascade_bias[cascade]
|
309
|
+
virtual_light.shadow_map_width = light.shadow_cascade_width[cascade]
|
310
|
+
virtual_light.shadow_map_height = light.shadow_cascade_height[cascade]
|
311
|
+
|
312
|
+
points_world = virtual_light.points_world = []
|
313
|
+
points_frustum = virtual_light.points_frustum = []
|
314
|
+
|
315
|
+
8.times do
|
316
|
+
points_world << Vector3.new
|
317
|
+
points_frustum << Vector3.new
|
318
|
+
end
|
319
|
+
|
320
|
+
near_z = light.shadow_cascade_near_z[cascade]
|
321
|
+
far_z = light.shadow_cascade_far_z[cascade]
|
322
|
+
|
323
|
+
points_frustum[0].set(-1.0, -1.0, near_z)
|
324
|
+
points_frustum[1].set( 1.0, -1.0, near_z)
|
325
|
+
points_frustum[2].set(-1.0, 1.0, near_z)
|
326
|
+
points_frustum[3].set( 1.0, 1.0, near_z)
|
327
|
+
|
328
|
+
points_frustum[4].set(-1.0, -1.0, far_z)
|
329
|
+
points_frustum[5].set( 1.0, -1.0, far_z)
|
330
|
+
points_frustum[6].set(-1.0, 1.0, far_z)
|
331
|
+
points_frustum[7].set( 1.0, 1.0, far_z)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# synchronize virtual light with the original light
|
336
|
+
|
337
|
+
def update_virtual_light(light, cascade)
|
338
|
+
virtual_light = light.shadow_cascade_array[cascade]
|
339
|
+
|
340
|
+
virtual_light.position.copy(light.position)
|
341
|
+
virtual_light.target.position.copy(light.target.position)
|
342
|
+
virtual_light.look_at(virtual_light.target)
|
343
|
+
|
344
|
+
virtual_light.shadow_camera_visible = light.shadow_camera_visible
|
345
|
+
virtual_light.shadow_darkness = light.shadow_darkness
|
346
|
+
|
347
|
+
virtual_light.shadow_bias = light.shadow_cascade_bias[cascade]
|
348
|
+
|
349
|
+
near_z = light.shadow_cascade_near_z[cascade]
|
350
|
+
far_z = light.shadow_cascade_far_z[cascade]
|
351
|
+
|
352
|
+
points_frustum = virtual_light.points_frustum
|
353
|
+
|
354
|
+
points_frustum[0].z = near_z
|
355
|
+
points_frustum[1].z = near_z
|
356
|
+
points_frustum[2].z = near_z
|
357
|
+
points_frustum[3].z = near_z
|
358
|
+
|
359
|
+
points_frustum[4].z = far_z
|
360
|
+
points_frustum[5].z = far_z
|
361
|
+
points_frustum[6].z = far_z
|
362
|
+
points_frustum[7].z = far_z
|
363
|
+
end
|
364
|
+
|
365
|
+
# fit shadow camera's ortho frustum to camera frustum
|
366
|
+
|
367
|
+
def update_shadow_camera(camera, light)
|
368
|
+
shadow_camera = light.shadow_camera
|
369
|
+
points_frustum = light.pointa_frustum
|
370
|
+
points_world = light.points_world
|
371
|
+
|
372
|
+
@min.set(Float::INFINITY, Float::INFINITY, Float::INFINITY)
|
373
|
+
@max.set(-Float::INFINITY, -Float::INFINITY, -Float::INFINITY)
|
374
|
+
|
375
|
+
8.times do |i|
|
376
|
+
p = points_world[i]
|
377
|
+
|
378
|
+
p.copy(points_frustum[i])
|
379
|
+
p.unproject(camera)
|
380
|
+
|
381
|
+
p.apply_matrix4(shadow_camera.matrix_world_inverse)
|
382
|
+
|
383
|
+
@min.x = p.x if (p.x < @min.x)
|
384
|
+
@max.x = p.x if (p.x > @max.x)
|
385
|
+
|
386
|
+
@min.y = p.y if (p.y < @min.y)
|
387
|
+
@max.y = p.y if (p.y > @max.y)
|
388
|
+
|
389
|
+
@min.z = p.z if (p.z < @min.z)
|
390
|
+
@max.z = p.z if (p.z > @max.z)
|
391
|
+
end
|
392
|
+
|
393
|
+
shadow_camera.left = @min.x
|
394
|
+
shadow_camera.right = @max.x
|
395
|
+
shadow_camera.top = @max.y
|
396
|
+
shadow_camera.bottom = @min.y
|
397
|
+
|
398
|
+
# can't really fit near/far
|
399
|
+
# shadow_camera.near = @min.x
|
400
|
+
# shadow_camera.far = @max.z
|
401
|
+
|
402
|
+
shadow_camera.update_projection_matrix
|
403
|
+
end
|
404
|
+
|
405
|
+
# For the moment just ignore objects that have multiple materials with different animation methods
|
406
|
+
# Only the frst material will be taken into account for deciding which depth material to use for shadow maps
|
407
|
+
|
408
|
+
def get_object_material(object)
|
409
|
+
if object.material.is_a?(MeshFaceMaterial)
|
410
|
+
object.material.materials[0]
|
411
|
+
else
|
412
|
+
object.material
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
416
|
+
end
|