├── .nojekyll ├── resources ├── leaves.jpg ├── star.jpg ├── 8x8-font.png ├── eye-icon.png ├── keyboard.jpg ├── noodles.jpg ├── uv-grid.png ├── f-texture.png ├── mip-example.png ├── rotate-30.png ├── rotate-60.png ├── rotate-90.png ├── tdl │ ├── error.jpg │ ├── screenshot.js │ ├── log.js │ ├── fullscreen.js │ ├── fps.js │ ├── misc.js │ ├── buffers.js │ └── clock.js ├── images │ ├── frame.png │ └── computer-history-museum │ │ ├── neg-x.jpg │ │ ├── neg-y.jpg │ │ ├── neg-z.jpg │ │ ├── pos-x.jpg │ │ ├── pos-y.jpg │ │ └── pos-z.jpg ├── models │ ├── chair │ │ ├── chair.jpg │ │ ├── license.md │ │ └── chair.mtl │ ├── killer_whale │ │ ├── whale.png │ │ ├── thumbnail.jpg │ │ ├── whale.CYCLES.bin │ │ └── BLENDSWAP_LICENSE.txt │ ├── windmill │ │ ├── windmill-obj.jpg │ │ ├── windmill_001_base_COL.jpg │ │ ├── windmill_001_base_NOR.jpg │ │ ├── windmill_001_base_SPEC.jpg │ │ ├── windmill_001_lopatky_COL.jpg │ │ ├── windmill_001_lopatky_NOR.jpg │ │ ├── license.md │ │ └── windmill.mtl │ ├── book-vertex-chameleon-study │ │ ├── book.png │ │ └── LICENSE.md │ └── cube │ │ ├── cube.mtl │ │ ├── cube.obj │ │ └── offset-cube.obj ├── mip-low-res-example.png ├── f-texture-pixel-coords.png ├── css │ └── ui-lightness │ │ └── images │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_228ef1_256x240.png │ │ ├── ui-icons_ef8c08_256x240.png │ │ ├── ui-icons_ffd27a_256x240.png │ │ ├── ui-icons_ffffff_256x240.png │ │ ├── ui-bg_flat_10_000000_40x100.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_100_f6f6f6_1x400.png │ │ ├── ui-bg_glass_100_fdf5ce_1x400.png │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ ├── ui-bg_diagonals-thick_18_b81900_40x40.png │ │ ├── ui-bg_diagonals-thick_20_666666_40x40.png │ │ ├── ui-bg_highlight-soft_100_eeeeee_1x100.png │ │ └── ui-bg_highlight-soft_75_ffe45c_1x100.png ├── lesson-helper.css ├── glMatrix │ └── LICENSE.md ├── webgl-obj-loader │ ├── index.d.ts │ └── mesh.d.ts ├── stats.min.js ├── drag-and-drop.js ├── flattened-primitives.js ├── webgl-tutorials.css ├── polygon-f.svg ├── colResizable-1.3.min.js └── jquery.mousecapture.js ├── lessons ├── imgs │ ├── 23_pbr_result.png │ ├── 0_setup_devtool.JPG │ ├── 0_setup_result.JPG │ ├── 23_pbr_ctr_eqn.png │ ├── toc │ │ ├── 14_texture.JPG │ │ ├── 19_depth_map.JPG │ │ ├── 23_pbr_result.png │ │ ├── 10_using_matrix.JPG │ │ ├── 15_ambient_light.JPG │ │ ├── 16_diffuse_light.JPG │ │ ├── 17_specular_term.JPG │ │ ├── 02_shader_attribute.JPG │ │ ├── 03_draw_from_index.JPG │ │ ├── 04_shader_uniform.JPG │ │ ├── 07_buffer_abstraction.JPG │ │ ├── 13_model_abstraction.JPG │ │ ├── 18_light_abstraction.JPG │ │ ├── 22_shadow_mapping_pcf.JPG │ │ ├── 21_shadow_mapping_add_bias.JPG │ │ ├── 05_shader_uniform_interactive.JPG │ │ ├── 08_vertex_array_abstraction.JPG │ │ ├── 12_model_matrix_and_load_obj.JPG │ │ ├── 20_shadow_mapping_first_try.JPG │ │ ├── 06_drawing_multiple_objects_pt1.JPG │ │ ├── 06_drawing_multiple_objects_pt2.JPG │ │ ├── 09_shader_renderer_abstraction.JPG │ │ ├── 11_input_handling_color_change.JPG │ │ └── 11_input_handling_camera_control.JPG │ ├── 14_texture_result.jpg │ ├── 16_diffuse_light_dot.JPG │ ├── 19_depth_map_result.jpg │ ├── 15_ambient_light_result.JPG │ ├── 19_depth_map_far_plane.jpg │ ├── 19_depth_map_first_pass.jpg │ ├── 23_pbr_two_point_light.png │ ├── 5_shader_uniform_result.JPG │ ├── 16_diffuse_light_formula.JPG │ ├── 17_specular_light_result.JPG │ ├── 19_depth_map_created_FBO.jpg │ ├── 19_depth_map_default_FBO.jpg │ ├── 19_depth_map_second_pass.jpg │ ├── 23_pbr_single_point_light.png │ ├── 10_projection_matrix_devtool.jpg │ ├── 12_model_matrix_and_load_obj.JPG │ ├── 15_ambient_light_cull_only.JPG │ ├── 16_diffuse_light_ambient_0.0.JPG │ ├── 16_diffuse_light_ambient_0.2.JPG │ ├── 17_specular_light_unity_pbr.JPG │ ├── 17_specular_light_v_vector.JPG │ ├── 18_light_abstraction_result.JPG │ ├── 20_shadow_mapping_first_try.jpg │ ├── 21_shadow_mapping_add_bias.jpg │ ├── 22_shadow_mapping_pcf_result.jpg │ ├── 8_va_abstraction_rect_array.jpg │ ├── 11_input_handling_camera_space.jpg │ ├── 8_va_abstraction_rect_vertices.jpg │ ├── 11_input_handling_camera_setting.jpg │ ├── 11_input_handling_keyboardevent.jpg │ ├── 11_input_handling_window_object.jpg │ ├── 12_model_matrix_and_load_obj_raf1.JPG │ ├── 12_model_matrix_and_load_obj_raf2.JPG │ ├── 21_shadow_mapping_add_bias_result.jpg │ ├── 22_shadow_mapping_pcf_area_light.jpg │ ├── 22_shadow_mapping_pcf_hard_shadow.jpg │ ├── 22_shadow_mapping_pcf_point_light.jpg │ ├── 6_drawing_multiple_objects_result.JPG │ ├── 12_model_matrix_and_load_obj_teapot.JPG │ ├── 15_ambient_light_cull_only_problem.JPG │ ├── 20_shadow_mapping_first_try_result.jpg │ ├── 14_texture_texture_units_and_objects.png │ ├── 8_va_abstraction_rect_array_stride_offset.jpg │ └── 17_specular_light_result_dullmat_intensity_change.JPG ├── 24_toon_shading │ ├── TwoToneGradient.png │ ├── UtilToonGradient.png │ └── contents.html ├── _shaders │ ├── dirDepthmapFragment.js │ ├── simpleVertex.js │ ├── simpleFragment.js │ ├── basicProjectionFragment.js │ ├── basicViewProjectionFragment.js │ ├── textureFragment.js │ ├── dirDepthmapVertex.js │ ├── basicFragment.js │ ├── basicProjectionVertex.js │ ├── basicViewProjectionVertex.js │ ├── textureVertex.js │ ├── dirLightVertex.js │ ├── basicVertex.js │ ├── toonVertex.js │ ├── PBRShaderVertex.js │ ├── dirShadowBiasVertex.js │ ├── dirShadowPCFVertex.js │ ├── toonFragment.js │ ├── dirLightFragment.js │ ├── PBRShaderFragment.js │ ├── dirShadowBiasFragment.js │ └── dirShadowPCFFragment.js ├── _classes │ ├── Material.js │ ├── VertexBuffer.js │ ├── Renderer.js │ ├── IndexBuffer.js │ ├── BasicLight.js │ ├── VertexArray.js │ ├── Shader.js │ ├── OrbitCamera.js │ ├── Texture.js │ └── Model.js ├── 08_vertex_array_abstraction │ ├── contents.html │ └── main.js ├── 11_input_handling_pt1_color_change │ ├── contents.html │ └── main.js ├── 11_input_handling_pt2_camera_control │ ├── contents.html │ └── main.js ├── 09_shader_renderer_abstraction │ ├── contents.html │ └── main.js ├── 14_texture │ ├── contents.html │ └── main.js ├── 10_using_matrix │ ├── contents.html │ └── main.js ├── 15_ambient_light │ └── contents.html ├── 16_diffuse_light │ └── contents.html ├── 17_specular_term │ └── contents.html ├── 13_model_abstraction │ ├── contents.html │ └── main.js ├── 23_PBR │ └── contents.html ├── 12_model_matrix_and_load_obj │ ├── contents.html │ └── main.js ├── 18_light_abstraction │ └── contents.html ├── 19_depth_map │ └── contents.html ├── 22_shadow_mapping_pcf │ └── contents.html ├── 21_shadow_mapping_add_bias │ └── contents.html ├── 20_shadow_mapping_first_try │ └── contents.html ├── 00_Setup │ ├── contents.html │ └── README.md ├── 01_vertex_buffer │ └── contents.html ├── 04_shader_uniform │ ├── contents.html │ └── README.md ├── 02_shader_attribute │ └── contents.html ├── 05_shader_uniform_interactive │ └── contents.html └── 03_draw_from_index │ ├── README.md │ └── contents.html └── README.md /.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/leaves.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/leaves.jpg -------------------------------------------------------------------------------- /resources/star.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/star.jpg -------------------------------------------------------------------------------- /resources/8x8-font.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/8x8-font.png -------------------------------------------------------------------------------- /resources/eye-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/eye-icon.png -------------------------------------------------------------------------------- /resources/keyboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/keyboard.jpg -------------------------------------------------------------------------------- /resources/noodles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/noodles.jpg -------------------------------------------------------------------------------- /resources/uv-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/uv-grid.png -------------------------------------------------------------------------------- /resources/f-texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/f-texture.png -------------------------------------------------------------------------------- /resources/mip-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/mip-example.png -------------------------------------------------------------------------------- /resources/rotate-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/rotate-30.png -------------------------------------------------------------------------------- /resources/rotate-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/rotate-60.png -------------------------------------------------------------------------------- /resources/rotate-90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/rotate-90.png -------------------------------------------------------------------------------- /resources/tdl/error.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/tdl/error.jpg -------------------------------------------------------------------------------- /resources/images/frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/images/frame.png -------------------------------------------------------------------------------- /lessons/imgs/23_pbr_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/23_pbr_result.png -------------------------------------------------------------------------------- /lessons/imgs/0_setup_devtool.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/0_setup_devtool.JPG -------------------------------------------------------------------------------- /lessons/imgs/0_setup_result.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/0_setup_result.JPG -------------------------------------------------------------------------------- /lessons/imgs/23_pbr_ctr_eqn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/23_pbr_ctr_eqn.png -------------------------------------------------------------------------------- /lessons/imgs/toc/14_texture.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/14_texture.JPG -------------------------------------------------------------------------------- /resources/models/chair/chair.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/chair/chair.jpg -------------------------------------------------------------------------------- /lessons/imgs/14_texture_result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/14_texture_result.jpg -------------------------------------------------------------------------------- /lessons/imgs/toc/19_depth_map.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/19_depth_map.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/23_pbr_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/23_pbr_result.png -------------------------------------------------------------------------------- /resources/mip-low-res-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/mip-low-res-example.png -------------------------------------------------------------------------------- /lessons/imgs/16_diffuse_light_dot.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/16_diffuse_light_dot.JPG -------------------------------------------------------------------------------- /lessons/imgs/19_depth_map_result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/19_depth_map_result.jpg -------------------------------------------------------------------------------- /lessons/imgs/toc/10_using_matrix.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/10_using_matrix.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/15_ambient_light.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/15_ambient_light.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/16_diffuse_light.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/16_diffuse_light.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/17_specular_term.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/17_specular_term.JPG -------------------------------------------------------------------------------- /resources/f-texture-pixel-coords.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/f-texture-pixel-coords.png -------------------------------------------------------------------------------- /lessons/imgs/15_ambient_light_result.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/15_ambient_light_result.JPG -------------------------------------------------------------------------------- /lessons/imgs/19_depth_map_far_plane.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/19_depth_map_far_plane.jpg -------------------------------------------------------------------------------- /lessons/imgs/19_depth_map_first_pass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/19_depth_map_first_pass.jpg -------------------------------------------------------------------------------- /lessons/imgs/23_pbr_two_point_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/23_pbr_two_point_light.png -------------------------------------------------------------------------------- /lessons/imgs/5_shader_uniform_result.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/5_shader_uniform_result.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/02_shader_attribute.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/02_shader_attribute.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/03_draw_from_index.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/03_draw_from_index.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/04_shader_uniform.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/04_shader_uniform.JPG -------------------------------------------------------------------------------- /resources/models/killer_whale/whale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/killer_whale/whale.png -------------------------------------------------------------------------------- /lessons/imgs/16_diffuse_light_formula.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/16_diffuse_light_formula.JPG -------------------------------------------------------------------------------- /lessons/imgs/17_specular_light_result.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/17_specular_light_result.JPG -------------------------------------------------------------------------------- /lessons/imgs/19_depth_map_created_FBO.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/19_depth_map_created_FBO.jpg -------------------------------------------------------------------------------- /lessons/imgs/19_depth_map_default_FBO.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/19_depth_map_default_FBO.jpg -------------------------------------------------------------------------------- /lessons/imgs/19_depth_map_second_pass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/19_depth_map_second_pass.jpg -------------------------------------------------------------------------------- /lessons/imgs/23_pbr_single_point_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/23_pbr_single_point_light.png -------------------------------------------------------------------------------- /lessons/imgs/toc/07_buffer_abstraction.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/07_buffer_abstraction.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/13_model_abstraction.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/13_model_abstraction.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/18_light_abstraction.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/18_light_abstraction.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/22_shadow_mapping_pcf.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/22_shadow_mapping_pcf.JPG -------------------------------------------------------------------------------- /resources/models/windmill/windmill-obj.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/windmill/windmill-obj.jpg -------------------------------------------------------------------------------- /lessons/24_toon_shading/TwoToneGradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/24_toon_shading/TwoToneGradient.png -------------------------------------------------------------------------------- /lessons/24_toon_shading/UtilToonGradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/24_toon_shading/UtilToonGradient.png -------------------------------------------------------------------------------- /lessons/imgs/10_projection_matrix_devtool.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/10_projection_matrix_devtool.jpg -------------------------------------------------------------------------------- /lessons/imgs/12_model_matrix_and_load_obj.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/12_model_matrix_and_load_obj.JPG -------------------------------------------------------------------------------- /lessons/imgs/15_ambient_light_cull_only.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/15_ambient_light_cull_only.JPG -------------------------------------------------------------------------------- /lessons/imgs/16_diffuse_light_ambient_0.0.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/16_diffuse_light_ambient_0.0.JPG -------------------------------------------------------------------------------- /lessons/imgs/16_diffuse_light_ambient_0.2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/16_diffuse_light_ambient_0.2.JPG -------------------------------------------------------------------------------- /lessons/imgs/17_specular_light_unity_pbr.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/17_specular_light_unity_pbr.JPG -------------------------------------------------------------------------------- /lessons/imgs/17_specular_light_v_vector.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/17_specular_light_v_vector.JPG -------------------------------------------------------------------------------- /lessons/imgs/18_light_abstraction_result.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/18_light_abstraction_result.JPG -------------------------------------------------------------------------------- /lessons/imgs/20_shadow_mapping_first_try.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/20_shadow_mapping_first_try.jpg -------------------------------------------------------------------------------- /lessons/imgs/21_shadow_mapping_add_bias.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/21_shadow_mapping_add_bias.jpg -------------------------------------------------------------------------------- /lessons/imgs/22_shadow_mapping_pcf_result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/22_shadow_mapping_pcf_result.jpg -------------------------------------------------------------------------------- /lessons/imgs/8_va_abstraction_rect_array.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/8_va_abstraction_rect_array.jpg -------------------------------------------------------------------------------- /resources/models/killer_whale/thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/killer_whale/thumbnail.jpg -------------------------------------------------------------------------------- /lessons/imgs/11_input_handling_camera_space.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/11_input_handling_camera_space.jpg -------------------------------------------------------------------------------- /lessons/imgs/8_va_abstraction_rect_vertices.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/8_va_abstraction_rect_vertices.jpg -------------------------------------------------------------------------------- /lessons/imgs/toc/21_shadow_mapping_add_bias.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/21_shadow_mapping_add_bias.JPG -------------------------------------------------------------------------------- /resources/models/killer_whale/whale.CYCLES.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/killer_whale/whale.CYCLES.bin -------------------------------------------------------------------------------- /lessons/imgs/11_input_handling_camera_setting.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/11_input_handling_camera_setting.jpg -------------------------------------------------------------------------------- /lessons/imgs/11_input_handling_keyboardevent.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/11_input_handling_keyboardevent.jpg -------------------------------------------------------------------------------- /lessons/imgs/11_input_handling_window_object.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/11_input_handling_window_object.jpg -------------------------------------------------------------------------------- /lessons/imgs/12_model_matrix_and_load_obj_raf1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/12_model_matrix_and_load_obj_raf1.JPG -------------------------------------------------------------------------------- /lessons/imgs/12_model_matrix_and_load_obj_raf2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/12_model_matrix_and_load_obj_raf2.JPG -------------------------------------------------------------------------------- /lessons/imgs/21_shadow_mapping_add_bias_result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/21_shadow_mapping_add_bias_result.jpg -------------------------------------------------------------------------------- /lessons/imgs/22_shadow_mapping_pcf_area_light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/22_shadow_mapping_pcf_area_light.jpg -------------------------------------------------------------------------------- /lessons/imgs/22_shadow_mapping_pcf_hard_shadow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/22_shadow_mapping_pcf_hard_shadow.jpg -------------------------------------------------------------------------------- /lessons/imgs/22_shadow_mapping_pcf_point_light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/22_shadow_mapping_pcf_point_light.jpg -------------------------------------------------------------------------------- /lessons/imgs/6_drawing_multiple_objects_result.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/6_drawing_multiple_objects_result.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/05_shader_uniform_interactive.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/05_shader_uniform_interactive.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/08_vertex_array_abstraction.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/08_vertex_array_abstraction.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/12_model_matrix_and_load_obj.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/12_model_matrix_and_load_obj.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/20_shadow_mapping_first_try.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/20_shadow_mapping_first_try.JPG -------------------------------------------------------------------------------- /resources/images/computer-history-museum/neg-x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/images/computer-history-museum/neg-x.jpg -------------------------------------------------------------------------------- /resources/images/computer-history-museum/neg-y.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/images/computer-history-museum/neg-y.jpg -------------------------------------------------------------------------------- /resources/images/computer-history-museum/neg-z.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/images/computer-history-museum/neg-z.jpg -------------------------------------------------------------------------------- /resources/images/computer-history-museum/pos-x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/images/computer-history-museum/pos-x.jpg -------------------------------------------------------------------------------- /resources/images/computer-history-museum/pos-y.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/images/computer-history-museum/pos-y.jpg -------------------------------------------------------------------------------- /resources/images/computer-history-museum/pos-z.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/images/computer-history-museum/pos-z.jpg -------------------------------------------------------------------------------- /lessons/imgs/12_model_matrix_and_load_obj_teapot.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/12_model_matrix_and_load_obj_teapot.JPG -------------------------------------------------------------------------------- /lessons/imgs/15_ambient_light_cull_only_problem.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/15_ambient_light_cull_only_problem.JPG -------------------------------------------------------------------------------- /lessons/imgs/20_shadow_mapping_first_try_result.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/20_shadow_mapping_first_try_result.jpg -------------------------------------------------------------------------------- /lessons/imgs/toc/06_drawing_multiple_objects_pt1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/06_drawing_multiple_objects_pt1.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/06_drawing_multiple_objects_pt2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/06_drawing_multiple_objects_pt2.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/09_shader_renderer_abstraction.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/09_shader_renderer_abstraction.JPG -------------------------------------------------------------------------------- /lessons/imgs/toc/11_input_handling_color_change.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/11_input_handling_color_change.JPG -------------------------------------------------------------------------------- /resources/models/windmill/windmill_001_base_COL.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/windmill/windmill_001_base_COL.jpg -------------------------------------------------------------------------------- /resources/models/windmill/windmill_001_base_NOR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/windmill/windmill_001_base_NOR.jpg -------------------------------------------------------------------------------- /resources/models/windmill/windmill_001_base_SPEC.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/windmill/windmill_001_base_SPEC.jpg -------------------------------------------------------------------------------- /lessons/imgs/14_texture_texture_units_and_objects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/14_texture_texture_units_and_objects.png -------------------------------------------------------------------------------- /lessons/imgs/toc/11_input_handling_camera_control.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/toc/11_input_handling_camera_control.JPG -------------------------------------------------------------------------------- /resources/models/book-vertex-chameleon-study/book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/book-vertex-chameleon-study/book.png -------------------------------------------------------------------------------- /resources/models/windmill/windmill_001_lopatky_COL.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/windmill/windmill_001_lopatky_COL.jpg -------------------------------------------------------------------------------- /resources/models/windmill/windmill_001_lopatky_NOR.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/models/windmill/windmill_001_lopatky_NOR.jpg -------------------------------------------------------------------------------- /lessons/_shaders/dirDepthmapFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | //프래그먼트 셰이더는 아무것도 하지 않아도 됩니다. 4 | precision highp float; 5 | 6 | void main() 7 | { 8 | 9 | } 10 | `; -------------------------------------------------------------------------------- /lessons/imgs/8_va_abstraction_rect_array_stride_offset.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/8_va_abstraction_rect_array_stride_offset.jpg -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-icons_228ef1_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-icons_228ef1_256x240.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-icons_ef8c08_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-icons_ef8c08_256x240.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-icons_ffd27a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-icons_ffd27a_256x240.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /lessons/imgs/17_specular_light_result_dullmat_intensity_change.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/lessons/imgs/17_specular_light_result_dullmat_intensity_change.JPG -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png -------------------------------------------------------------------------------- /resources/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbnu-vclab/webgl-computer-graphics-lecture/HEAD/resources/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png -------------------------------------------------------------------------------- /lessons/_shaders/simpleVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | layout(location=0) in vec4 a_position; 5 | 6 | out vec4 v_color; 7 | 8 | void main() { 9 | gl_Position = a_position; 10 | } 11 | `; 12 | -------------------------------------------------------------------------------- /lessons/_shaders/simpleFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | precision highp float; 5 | 6 | layout(location=0) out vec4 outColor; 7 | 8 | uniform vec4 u_color; 9 | 10 | void main() { 11 | outColor = u_color; 12 | } 13 | ` -------------------------------------------------------------------------------- /resources/models/chair/license.md: -------------------------------------------------------------------------------- 1 | # Chair 2 | 3 | https://sketchfab.com/3d-models/chair-aa2acddb218646a59ece132bf95aa558 4 | 5 | # By haytonm 6 | 7 | https://sketchfab.com/haytonm 8 | 9 | # License: CC-BY 4.0 10 | 11 | http://creativecommons.org/licenses/by/4.0/ -------------------------------------------------------------------------------- /resources/models/cube/cube.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Material 5 | Ns 323.999994 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.800000 0.800000 0.800000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.0 0.0 0.0 10 | Ni 1.450000 11 | d 1.000000 12 | illum 2 13 | -------------------------------------------------------------------------------- /lessons/_shaders/basicProjectionFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | precision highp float; 5 | 6 | layout(location=0) out vec4 outColor; 7 | 8 | uniform vec4 u_color; 9 | 10 | void main() { 11 | outColor = u_color; //Shader 클래스의 동작 확인을 위해 uniform 색상으로 그리도록 수정 12 | } 13 | ` -------------------------------------------------------------------------------- /lessons/_shaders/basicViewProjectionFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | precision highp float; 5 | 6 | layout(location=0) out vec4 outColor; 7 | 8 | uniform vec4 u_color; 9 | 10 | void main() { 11 | outColor = u_color; //Shader 클래스의 동작 확인을 위해 uniform 색상으로 그리도록 수정 12 | } 13 | ` -------------------------------------------------------------------------------- /lessons/_shaders/textureFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | precision highp float; 5 | 6 | layout(location=0) out vec4 outColor; 7 | 8 | in vec2 v_texcoord; 9 | in vec3 v_normal; 10 | 11 | uniform sampler2D u_mainTexture; 12 | 13 | void main() { 14 | outColor = texture(u_mainTexture, v_texcoord); 15 | } 16 | ` -------------------------------------------------------------------------------- /resources/models/book-vertex-chameleon-study/LICENSE.md: -------------------------------------------------------------------------------- 1 | # Book - Vertex chameleon study 2 | 3 | From: https://sketchfab.com/3d-models/book-vertex-chameleon-study-51b0b3bdcd844a9e951a9ede6f192da8 4 | 5 | # Author: Oleaf 6 | 7 | https://sketchfab.com/homkahom0 8 | 9 | # License: CC-BY-NC 10 | 11 | http://creativecommons.org/licenses/by-nc/4.0/ 12 | -------------------------------------------------------------------------------- /lessons/_shaders/dirDepthmapVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | layout(location=0) in vec3 a_position; 4 | 5 | uniform mat4 u_model; //모델의 world공간 위치와 자세 6 | uniform mat4 u_directionalLightViewProjection; //카메라의 VP 행렬 7 | 8 | void main() { 9 | gl_Position = u_directionalLightViewProjection * u_model * vec4(a_position,1.0); 10 | } 11 | `; -------------------------------------------------------------------------------- /lessons/_shaders/basicFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | precision highp float; 5 | 6 | layout(location=0) out vec4 outColor; 7 | 8 | //정점 셰이더로부터 전달받은 varying 9 | //각 프래그먼트에 대해 보간된 값이 저장되어 있음 10 | in vec2 v_texcoord; 11 | in vec3 v_normal; 12 | 13 | uniform vec4 u_color; 14 | 15 | void main() { 16 | outColor = vec4(1.0,0.0,0.0,1.0); 17 | } 18 | ` -------------------------------------------------------------------------------- /lessons/_shaders/basicProjectionVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | layout(location=0) in vec4 a_position; 5 | layout(location=1) in vec4 a_color; 6 | 7 | uniform mat4 u_projection; // <-- 4x4 투영 행렬을 uniform으로 받을 겁니다. (즉, CPU로부터 전달받을 겁니다.) 8 | 9 | void main() { 10 | gl_Position = u_projection * a_position; //이제 position은 u_projection에 의해 변환됩니다. 11 | } 12 | `; 13 | -------------------------------------------------------------------------------- /lessons/_shaders/basicViewProjectionVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | layout(location=0) in vec4 a_position; 5 | layout(location=1) in vec4 a_color; 6 | 7 | uniform mat4 u_projection; 8 | uniform mat4 u_view; //Camera 클래스에서 반환된 view행렬 9 | 10 | void main() { 11 | gl_Position = u_projection * u_view * a_position; //proj * view * (model) * position 12 | } 13 | `; 14 | -------------------------------------------------------------------------------- /resources/models/windmill/license.md: -------------------------------------------------------------------------------- 1 | This model is licensed under the Creative Commons CC-BY-SA 3.0 license 2 | 3 | http://creativecommons.org/licenses/by-sa/3.0/ 4 | 5 | It can be used as long as attribution is given and any modifications 6 | are under the same license 7 | 8 | It was created by [ahedov](https://www.blendswap.com/user/ahedov) 9 | 10 | https://www.blendswap.com/blends/view/69174 11 | -------------------------------------------------------------------------------- /resources/lesson-helper.css: -------------------------------------------------------------------------------- 1 | .contextlost { 2 | position: absolute; 3 | left: 0; 4 | top: 0; 5 | width: 100vw; 6 | height: 100vh; 7 | background: red; 8 | color: white; 9 | font-family: monospace; 10 | font-weight: bold; 11 | display: flex; 12 | align-items: center; 13 | justify-content: center; 14 | } 15 | .contextlost>div { 16 | padding: 0.5em; 17 | background: darkred; 18 | cursor: pointer; 19 | } -------------------------------------------------------------------------------- /lessons/_classes/Material.js: -------------------------------------------------------------------------------- 1 | export default class Material{ 2 | specularIntensity; 3 | shininess; 4 | 5 | constructor(sIntensity, shininess) 6 | { 7 | this.specularIntensity = sIntensity; 8 | this.shininess = shininess; 9 | } 10 | 11 | UseMaterial(gl, shader) 12 | { 13 | shader.SetUniform1f(gl,"u_material.specularIntensity", this.specularIntensity); 14 | shader.SetUniform1f(gl,"u_material.shininess", this.shininess); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /lessons/_classes/VertexBuffer.js: -------------------------------------------------------------------------------- 1 | // VertexBuffer 관리를 위한 클래스 구현 2 | export default class VertexBuffer{ 3 | id; // 멤버 변수(필드) 4 | 5 | constructor(gl, data) //생성자 6 | { 7 | this.id = gl.createBuffer(); 8 | gl.bindBuffer(gl.ARRAY_BUFFER, this.id); 9 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW); 10 | } 11 | 12 | Bind(gl) 13 | { 14 | gl.bindBuffer(gl.ARRAY_BUFFER, this.id); 15 | } 16 | 17 | Unbind(gl) 18 | { 19 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 20 | } 21 | } -------------------------------------------------------------------------------- /lessons/_classes/Renderer.js: -------------------------------------------------------------------------------- 1 | // Renderer 클래스 구현 2 | export default class Renderer{ 3 | Clear(gl) 4 | { 5 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 6 | } 7 | 8 | Draw(gl, va, ib, shader) 9 | { 10 | //무언가를 그릴때, 3가지가 기본적으로 필요함. vao, ibo, shader program 11 | shader.Bind(gl); 12 | va.Bind(gl); 13 | 14 | var primitiveType = gl.TRIANGLES; 15 | var indexcount = ib.getCount(); 16 | var indexoffset = 0 17 | gl.drawElements(primitiveType, indexcount, gl.UNSIGNED_SHORT, 0); 18 | } 19 | } -------------------------------------------------------------------------------- /lessons/_shaders/textureVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | //--Attributes 5 | layout(location=0) in vec3 a_position; 6 | layout(location=1) in vec2 a_texcoord; 7 | layout(location=2) in vec3 a_normal; 8 | 9 | //--Uniforms 10 | uniform mat4 u_projection; 11 | uniform mat4 u_view; 12 | uniform mat4 u_model; 13 | 14 | //--Varyings 15 | out vec2 v_texcoord; 16 | out vec3 v_normal; 17 | 18 | void main() { 19 | gl_Position = u_projection * u_view * u_model * vec4(a_position, 1.0); //이제 a_position이 vec3이기 때문에 vec4로 만들어 곱해줘야 합니다. 20 | 21 | v_texcoord = a_texcoord; 22 | v_normal = a_normal; 23 | } 24 | `; 25 | -------------------------------------------------------------------------------- /resources/models/windmill/windmill.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'windmill_001.blend' 2 | # Material Count: 2 3 | 4 | newmtl Material 5 | Ns 0.000000 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.800000 0.800000 0.800000 8 | Ks 0.000000 0.000000 0.000000 9 | Ke 0.000000 0.000000 0.000000 10 | Ni 1.000000 11 | d 1.000000 12 | illum 1 13 | map_Kd windmill_001_lopatky_COL.jpg 14 | map_Bump windmill_001_lopatky_NOR.jpg 15 | 16 | newmtl windmill 17 | Ns 0.000000 18 | Ka 1.000000 1.000000 1.000000 19 | Kd 0.800000 0.800000 0.800000 20 | Ks 0.000000 0.000000 0.000000 21 | Ke 0.000000 0.000000 0.000000 22 | Ni 1.000000 23 | d 1.000000 24 | illum 1 25 | map_Kd windmill_001_base_COL.jpg 26 | map_Bump windmill_001_base_NOR.jpg 27 | map_Ns windmill_001_base_SPEC.jpg 28 | -------------------------------------------------------------------------------- /lessons/_shaders/dirLightVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | layout(location=0) in vec3 a_position; 4 | layout(location=1) in vec2 a_texcoord; 5 | layout(location=2) in vec3 a_normal; 6 | 7 | uniform mat4 u_projection; 8 | uniform mat4 u_view; //카메라를 통해 반환된 View행렬 9 | uniform mat4 u_model; //모델의 world공간 위치와 자세 10 | 11 | out vec2 v_texcoord; 12 | out vec3 v_normal; 13 | out vec3 v_worldPosition; 14 | 15 | void main() { 16 | gl_Position = u_projection * u_view * u_model * vec4(a_position,1.0); 17 | v_texcoord = a_texcoord; 18 | 19 | v_normal = mat3(transpose(inverse(u_model))) * a_normal; 20 | 21 | v_worldPosition = (u_model * vec4(a_position, 1.0)).xyz; //<-- 모델 행렬만 곱하면 월드공간 좌표가 얻어집니다. 22 | } 23 | `; -------------------------------------------------------------------------------- /lessons/_shaders/basicVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | //이제 일반적인 형태의 정점 셰이더를 구현합니다. 4 | //각 정점은 position(위치 좌표), texcoord(텍스처 좌표), normal(법선) 데이터를 가집니다. 5 | 6 | //--Attributes 7 | layout(location=0) in vec3 a_position; 8 | layout(location=1) in vec2 a_texcoord; 9 | layout(location=2) in vec3 a_normal; 10 | 11 | //--Uniforms 12 | uniform mat4 u_projection; 13 | uniform mat4 u_view; 14 | uniform mat4 u_model; 15 | 16 | //--Varyings 17 | out vec2 v_texcoord; 18 | out vec3 v_normal; 19 | 20 | void main() { 21 | gl_Position = u_projection * u_view * u_model * vec4(a_position, 1.0); //이제 a_position이 vec3이기 때문에 vec4로 만들어 곱해줘야 합니다. 22 | 23 | //프래그먼트 셰이더로 값을 넘김 24 | v_texcoord = a_texcoord; 25 | v_normal = a_normal; 26 | } 27 | `; 28 | -------------------------------------------------------------------------------- /lessons/_classes/IndexBuffer.js: -------------------------------------------------------------------------------- 1 | // IndexBuffer 관리를 위한 클래스 구현 2 | export default class IndexBuffer{ 3 | id; 4 | count; 5 | 6 | constructor(gl, data, count) 7 | { 8 | this.id = gl.createBuffer(); 9 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.id); 10 | gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), gl.STATIC_DRAW); 11 | 12 | this.count = count; //나중에 drawElement를 할 때 몇 개의 index를 그릴 것인지 명시해 주어야 하므로 따로 저장함 13 | } 14 | 15 | Bind(gl) 16 | { 17 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.id); 18 | } 19 | 20 | Unbind(gl) 21 | { 22 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); 23 | } 24 | 25 | getCount() 26 | { 27 | return this.count; 28 | } 29 | } -------------------------------------------------------------------------------- /lessons/_shaders/toonVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | //이제 일반적인 형태의 정점 셰이더를 구현합니다. 4 | //각 정점은 position(위치 좌표), texcoord(텍스처 좌표), normal(법선) 데이터를 가집니다. 5 | 6 | //--Attributes 7 | layout(location=0) in vec3 a_position; 8 | layout(location=1) in vec2 a_texcoord; 9 | layout(location=2) in vec3 a_normal; 10 | 11 | //--Uniforms 12 | uniform mat4 u_projection; 13 | uniform mat4 u_view; 14 | uniform mat4 u_model; 15 | 16 | //--Varyings 17 | out vec2 v_texcoord; 18 | out vec3 v_normal; 19 | 20 | void main() { 21 | gl_Position = u_projection * u_view * u_model * vec4(a_position, 1.0); //이제 a_position이 vec3이기 때문에 vec4로 만들어 곱해줘야 합니다. 22 | 23 | //프래그먼트 셰이더로 값을 넘김 24 | v_texcoord = a_texcoord; 25 | v_normal = mat3(transpose(inverse(u_model))) * a_normal; 26 | } 27 | `; 28 | -------------------------------------------------------------------------------- /lessons/_shaders/PBRShaderVertex.js: -------------------------------------------------------------------------------- 1 | // dirLightVertex와 동일한 Source 2 | 3 | export default 4 | `#version 300 es 5 | layout(location=0) in vec3 a_position; 6 | layout(location=1) in vec2 a_texcoord; 7 | layout(location=2) in vec3 a_normal; 8 | 9 | uniform mat4 u_projection; 10 | uniform mat4 u_view; //카메라를 통해 반환된 View행렬 11 | uniform mat4 u_model; //모델의 world공간 위치와 자세 12 | 13 | out vec2 v_texcoord; 14 | out vec3 v_normal; 15 | out vec3 v_worldPosition; 16 | 17 | void main() { 18 | gl_Position = u_projection * u_view * u_model * vec4(a_position,1.0); 19 | v_texcoord = a_texcoord; 20 | 21 | v_normal = mat3(transpose(inverse(u_model))) * a_normal; 22 | 23 | v_worldPosition = (u_model * vec4(a_position, 1.0)).xyz; //<-- 모델 행렬만 곱하면 월드공간 좌표가 얻어집니다. 24 | } 25 | `; -------------------------------------------------------------------------------- /lessons/08_vertex_array_abstraction/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 8.Vertex Array Abstraction 6 | 7 | 8 | 9 |
WebGL 8.Vertex Array Abstraction
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /lessons/11_input_handling_pt1_color_change/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 11. Input Handling - Color Change 6 | 7 | 8 | 9 |
WebGL 11. Input Handling - Color Change
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /lessons/11_input_handling_pt2_camera_control/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 11. Input Handling - Camera Control 6 | 7 | 8 | 9 |
WebGL 11. Input Handling - Camera Control
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /lessons/09_shader_renderer_abstraction/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 9.Shader and Renderer Abstraction 6 | 7 | 8 | 9 |
WebGL 9.Shader and Renderer Abstraction
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /lessons/14_texture/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 14. Texture 6 | 7 | 8 | 9 |
WebGL 14. Texture
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /lessons/10_using_matrix/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 10. Using Matrix 6 | 7 | 8 | 9 |
WebGL 10. Using Matrix
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /lessons/15_ambient_light/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 15. Ambient Light 6 | 7 | 8 | 9 |
WebGL 15. Ambient Light
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /lessons/16_diffuse_light/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 16. Diffuse Light 6 | 7 | 8 | 9 |
WebGL 16. Diffuse Light
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /lessons/17_specular_term/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 17. Specular Term 6 | 7 | 8 | 9 |
WebGL 17. Specular Term
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /lessons/13_model_abstraction/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 13. Model Abstraction 6 | 7 | 8 | 9 |
WebGL 13. Model Abstraction
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /lessons/23_PBR/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 23. PBR 6 | 7 | 8 | 9 |
WebGL 23. PBR
10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /lessons/_shaders/dirShadowBiasVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | layout(location=0) in vec3 a_position; 4 | layout(location=1) in vec2 a_texcoord; 5 | layout(location=2) in vec3 a_normal; 6 | 7 | uniform mat4 u_projection; 8 | uniform mat4 u_view; 9 | uniform mat4 u_model; 10 | uniform mat4 u_directionalLightViewProjection; //light space transform matrix 11 | 12 | out vec2 v_texcoord; 13 | out vec3 v_normal; 14 | out vec3 v_worldPosition; 15 | out vec4 v_lightSpacePos; //fragment의 light space 기준 좌표가 필요 16 | 17 | void main() { 18 | gl_Position = u_projection * u_view * u_model * vec4(a_position,1.0); 19 | 20 | v_texcoord = a_texcoord; 21 | v_normal = mat3(transpose(inverse(u_model))) * a_normal; 22 | 23 | //정점의 world공간 좌표. specular 계산에 사용 24 | v_worldPosition = (u_model * vec4(a_position,1.0)).xyz; 25 | 26 | //정점의 조명 공간 좌표. shadow 계산에 사용 27 | v_lightSpacePos = u_directionalLightViewProjection * u_model * vec4(a_position,1.0); 28 | } 29 | ` -------------------------------------------------------------------------------- /lessons/_shaders/dirShadowPCFVertex.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | layout(location=0) in vec3 a_position; 4 | layout(location=1) in vec2 a_texcoord; 5 | layout(location=2) in vec3 a_normal; 6 | 7 | uniform mat4 u_projection; 8 | uniform mat4 u_view; 9 | uniform mat4 u_model; 10 | uniform mat4 u_directionalLightViewProjection; //light space transform matrix 11 | 12 | out vec2 v_texcoord; 13 | out vec3 v_normal; 14 | out vec3 v_worldPosition; 15 | out vec4 v_lightSpacePos; //fragment의 light space 기준 좌표가 필요 16 | 17 | void main() { 18 | gl_Position = u_projection * u_view * u_model * vec4(a_position,1.0); 19 | 20 | v_texcoord = a_texcoord; 21 | v_normal = mat3(transpose(inverse(u_model))) * a_normal; 22 | 23 | //정점의 world공간 좌표. specular 계산에 사용 24 | v_worldPosition = (u_model * vec4(a_position,1.0)).xyz; 25 | 26 | //정점의 조명 공간 좌표. shadow 계산에 사용 27 | v_lightSpacePos = u_directionalLightViewProjection * u_model * vec4(a_position,1.0); 28 | } 29 | ` -------------------------------------------------------------------------------- /lessons/12_model_matrix_and_load_obj/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 12. Model Matrix and LoadOBJ 6 | 7 | 8 | 9 |
WebGL 12. Model Matrix and LoadOBJ
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /lessons/24_toon_shading/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 24. Toon Shading 6 | 7 | 8 | 9 |
WebGL 24. Toon Shading
10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lessons/18_light_abstraction/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 18. Light Abstraction 6 | 7 | 8 | 9 |
WebGL 18. Light Abstraction
10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lessons/_classes/BasicLight.js: -------------------------------------------------------------------------------- 1 | export class Light { 2 | lightColor; 3 | ambientIntensity; 4 | diffuseIntensity; 5 | 6 | constructor(lightColor, aIntensity, dIntensity) 7 | { 8 | this.lightColor = lightColor; 9 | this.ambientIntensity = aIntensity; 10 | this.diffuseIntensity = dIntensity; 11 | } 12 | } 13 | 14 | export class DirectionalLight extends Light { 15 | direction; 16 | 17 | constructor(lightColor, aIntensity, dir, dIntensity) 18 | { 19 | super(lightColor, aIntensity, dIntensity); 20 | this.direction = dir; 21 | } 22 | 23 | UseLight(gl,shader) 24 | { 25 | shader.SetUniform3f(gl,"u_directionalLight.base.lightColor", this.lightColor[0], this.lightColor[1], this.lightColor[2]); 26 | shader.SetUniform1f(gl,"u_directionalLight.base.ambientIntensity", this.ambientIntensity); 27 | shader.SetUniform1f(gl,"u_directionalLight.base.diffuseIntensity", this.diffuseIntensity); 28 | 29 | shader.SetUniform3f(gl,"u_directionalLight.direction", this.direction[0], this.direction[1], this.direction[2]); 30 | } 31 | } -------------------------------------------------------------------------------- /lessons/_classes/VertexArray.js: -------------------------------------------------------------------------------- 1 | export default class VertexArray{ 2 | id; 3 | 4 | constructor(gl) 5 | { 6 | this.id = gl.createVertexArray(); 7 | } 8 | 9 | Bind(gl) 10 | { 11 | gl.bindVertexArray(this.id); 12 | } 13 | 14 | Unbind(gl) 15 | { 16 | gl.bindVertexArray(null); 17 | } 18 | 19 | AddBuffer(gl, vb, countArray, normalizedArray) 20 | { 21 | console.assert(countArray.length == normalizedArray.length, 22 | "length of countArray and normalizedArray should match!"); 23 | this.Bind(gl); 24 | vb.Bind(gl); 25 | 26 | var stride = 0; 27 | for(var i=0;i 2 | 3 | 4 | 5 | WebGL 19. Depth Map 6 | 7 | 8 | 9 |
WebGL 19. Depth Map
10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /lessons/_shaders/toonFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | precision highp float; 4 | 5 | struct Light 6 | { 7 | vec3 lightColor; 8 | float ambientIntensity; 9 | float diffuseIntensity; 10 | }; 11 | 12 | struct DirectionalLight 13 | { 14 | Light base; 15 | vec3 direction; 16 | }; 17 | 18 | struct Material 19 | { 20 | float specularIntensity; 21 | float shininess; // == sh 22 | }; 23 | 24 | layout(location=0) out vec4 outColor; 25 | 26 | uniform sampler2D u_toonLut; // LUT == Look Up Table 27 | uniform sampler2D u_mainTexture; 28 | uniform DirectionalLight u_directionalLight; 29 | 30 | in vec2 v_texcoord; 31 | in vec3 v_normal; 32 | 33 | void main() 34 | { 35 | vec3 normal = normalize(v_normal); 36 | 37 | vec3 lightDir = normalize(-u_directionalLight.direction); 38 | float ndotl = dot(normal, lightDir); 39 | float diffuseFactor = max(ndotl, 0.0); 40 | 41 | vec4 lut = texture(u_toonLut, vec2(diffuseFactor, 0)); 42 | 43 | //outColor = vec4(0.8, 0.3, 0.2, 1.0) * lut; 44 | outColor = texture(u_mainTexture, v_texcoord) * lut; 45 | //outColor = lut; 46 | } 47 | ` -------------------------------------------------------------------------------- /resources/glMatrix/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2021, Brandon Jones, Colin MacKenzie IV. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /lessons/22_shadow_mapping_pcf/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 22. Shadow Mapping - PCF 6 | 7 | 8 | 9 |
WebGL 22. Shadow Mapping - PCF
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /resources/models/cube/cube.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.80 (sub 75) OBJ File: '' 2 | # www.blender.org 3 | mtllib cube.mtl 4 | o Cube 5 | v 1.000000 1.000000 -1.000000 6 | v 1.000000 -1.000000 -1.000000 7 | v 1.000000 1.000000 1.000000 8 | v 1.000000 -1.000000 1.000000 9 | v -1.000000 1.000000 -1.000000 10 | v -1.000000 -1.000000 -1.000000 11 | v -1.000000 1.000000 1.000000 12 | v -1.000000 -1.000000 1.000000 13 | vt 0.375000 0.000000 14 | vt 0.625000 0.000000 15 | vt 0.625000 0.250000 16 | vt 0.375000 0.250000 17 | vt 0.375000 0.250000 18 | vt 0.625000 0.250000 19 | vt 0.625000 0.500000 20 | vt 0.375000 0.500000 21 | vt 0.625000 0.750000 22 | vt 0.375000 0.750000 23 | vt 0.625000 0.750000 24 | vt 0.625000 1.000000 25 | vt 0.375000 1.000000 26 | vt 0.125000 0.500000 27 | vt 0.375000 0.500000 28 | vt 0.375000 0.750000 29 | vt 0.125000 0.750000 30 | vt 0.625000 0.500000 31 | vt 0.875000 0.500000 32 | vt 0.875000 0.750000 33 | vn 0.0000 1.0000 0.0000 34 | vn 0.0000 0.0000 1.0000 35 | vn -1.0000 0.0000 0.0000 36 | vn 0.0000 -1.0000 0.0000 37 | vn 1.0000 0.0000 0.0000 38 | vn 0.0000 0.0000 -1.0000 39 | usemtl Material 40 | s off 41 | f 1/1/1 5/2/1 7/3/1 3/4/1 42 | f 4/5/2 3/6/2 7/7/2 8/8/2 43 | f 8/8/3 7/7/3 5/9/3 6/10/3 44 | f 6/10/4 2/11/4 4/12/4 8/13/4 45 | f 2/14/5 1/15/5 3/16/5 4/17/5 46 | f 6/18/6 5/19/6 1/20/6 2/11/6 47 | -------------------------------------------------------------------------------- /resources/models/cube/offset-cube.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.80 (sub 75) OBJ File: '' 2 | # www.blender.org 3 | mtllib cube.mtl 4 | o Cube 5 | v 10.000000 1.000000 -1.000000 6 | v 10.000000 -1.000000 -1.000000 7 | v 10.000000 1.000000 1.000000 8 | v 10.000000 -1.000000 1.000000 9 | v 8.000000 1.000000 -1.000000 10 | v 8.000000 -1.000000 -1.000000 11 | v 8.000000 1.000000 1.000000 12 | v 8.000000 -1.000000 1.000000 13 | vt 0.375000 0.000000 14 | vt 0.625000 0.000000 15 | vt 0.625000 0.250000 16 | vt 0.375000 0.250000 17 | vt 0.375000 0.250000 18 | vt 0.625000 0.250000 19 | vt 0.625000 0.500000 20 | vt 0.375000 0.500000 21 | vt 0.625000 0.750000 22 | vt 0.375000 0.750000 23 | vt 0.625000 0.750000 24 | vt 0.625000 1.000000 25 | vt 0.375000 1.000000 26 | vt 0.125000 0.500000 27 | vt 0.375000 0.500000 28 | vt 0.375000 0.750000 29 | vt 0.125000 0.750000 30 | vt 0.625000 0.500000 31 | vt 0.875000 0.500000 32 | vt 0.875000 0.750000 33 | vn 0.0000 1.0000 0.0000 34 | vn 0.0000 0.0000 1.0000 35 | vn -1.0000 0.0000 0.0000 36 | vn 0.0000 -1.0000 0.0000 37 | vn 1.0000 0.0000 0.0000 38 | vn 0.0000 0.0000 -1.0000 39 | usemtl Material 40 | s off 41 | f 1/1/1 5/2/1 7/3/1 3/4/1 42 | f 4/5/2 3/6/2 7/7/2 8/8/2 43 | f 8/8/3 7/7/3 5/9/3 6/10/3 44 | f 6/10/4 2/11/4 4/12/4 8/13/4 45 | f 2/14/5 1/15/5 3/16/5 4/17/5 46 | f 6/18/6 5/19/6 1/20/6 2/11/6 47 | -------------------------------------------------------------------------------- /lessons/21_shadow_mapping_add_bias/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 21. Shadow Mapping - Add bias 6 | 7 | 8 | 9 |
WebGL 21. Shadow Mapping - Add bias
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /lessons/20_shadow_mapping_first_try/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 20. Shadow Mapping - First Try 6 | 7 | 8 | 9 |
WebGL 20. Shadow Mapping - First Try
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /resources/webgl-obj-loader/index.d.ts: -------------------------------------------------------------------------------- 1 | import Mesh, { MeshOptions, MaterialNameToIndex, IndexToMaterial, ArrayBufferWithItemSize, Uint16ArrayWithItemSize } from "./mesh"; 2 | import { Material, MaterialLibrary, Vec3, UVW, TextureMapData } from "./material"; 3 | import { Layout, TYPES, AttributeInfo, DuplicateAttributeException, Attribute } from "./layout"; 4 | import { downloadModels, downloadMeshes, initMeshBuffers, deleteMeshBuffers, DownloadModelsOptions, MeshMap, NameAndUrls, ExtendedGLBuffer, MeshWithBuffers } from "./utils"; 5 | declare const version = "2.0.3"; 6 | export declare const OBJ: { 7 | Attribute: typeof Attribute; 8 | DuplicateAttributeException: typeof DuplicateAttributeException; 9 | Layout: typeof Layout; 10 | Material: typeof Material; 11 | MaterialLibrary: typeof MaterialLibrary; 12 | Mesh: typeof Mesh; 13 | TYPES: typeof TYPES; 14 | downloadModels: typeof downloadModels; 15 | downloadMeshes: typeof downloadMeshes; 16 | initMeshBuffers: typeof initMeshBuffers; 17 | deleteMeshBuffers: typeof deleteMeshBuffers; 18 | version: string; 19 | }; 20 | /** 21 | * @namespace 22 | */ 23 | export { ArrayBufferWithItemSize, Attribute, AttributeInfo, DownloadModelsOptions, DuplicateAttributeException, ExtendedGLBuffer, IndexToMaterial, Layout, Material, MaterialLibrary, MaterialNameToIndex, Mesh, MeshMap, MeshOptions, MeshWithBuffers, NameAndUrls, TextureMapData, TYPES, Uint16ArrayWithItemSize, UVW, Vec3, downloadModels, downloadMeshes, initMeshBuffers, deleteMeshBuffers, version, }; 24 | -------------------------------------------------------------------------------- /lessons/_classes/Shader.js: -------------------------------------------------------------------------------- 1 | // Shader 클래스 구현 2 | export default class Shader{ 3 | id; 4 | locations = {}; 5 | 6 | constructor(gl, vsource, fsource) 7 | { 8 | this.id = webglUtils.createProgramFromSources(gl,[vsource, fsource]); 9 | } 10 | 11 | //Shader는 useProgram을 호출하지만 통일성을 위해 수정 12 | Bind(gl) 13 | { 14 | gl.useProgram(this.id); 15 | } 16 | 17 | Unbind(gl) 18 | { 19 | gl.useProgram(null); 20 | } 21 | 22 | GetUniformLocation(gl, name) 23 | { 24 | let location = 0; 25 | if(name in this.locations) 26 | { 27 | location = this.locations[name]; 28 | } 29 | else 30 | { 31 | location = gl.getUniformLocation(this.id, name); 32 | this.locations[name] = location; 33 | } 34 | return location; 35 | } 36 | 37 | //SetUniform 메소드들 38 | SetUniform1f(gl,name, val) 39 | { 40 | let location = this.GetUniformLocation(gl,name); 41 | gl.uniform1f(location, val); 42 | } 43 | 44 | SetUniform3f(gl,name, v0,v1,v2) 45 | { 46 | let location = this.GetUniformLocation(gl,name); 47 | gl.uniform3f(location, v0, v1, v2); 48 | } 49 | 50 | SetUniform4f(gl,name, v0,v1,v2,v3) 51 | { 52 | let location = this.GetUniformLocation(gl,name); 53 | gl.uniform4f(location, v0, v1, v2, v3); 54 | } 55 | 56 | SetUniformMat4f(gl, name, mat) 57 | { 58 | let location = this.GetUniformLocation(gl,name); 59 | gl.uniformMatrix4fv(location, false, mat); 60 | } 61 | 62 | SetUniform1i(gl, name, val) 63 | { 64 | let location = this.GetUniformLocation(gl,name); 65 | gl.uniform1i(location, val); 66 | } 67 | } -------------------------------------------------------------------------------- /lessons/00_Setup/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 0.Setup 6 | 7 | 8 | 9 |
WebGL Setup Result
10 | 11 | 12 | 13 | 14 | 70 | -------------------------------------------------------------------------------- /lessons/_classes/OrbitCamera.js: -------------------------------------------------------------------------------- 1 | const {mat2, mat3, mat4, vec2, vec3, vec4} = glMatrix; 2 | 3 | // Orbit Camera class 4 | export default class OrbitCamera { 5 | constructor(eye, at, up, yaw, pitch, distance, turnspeed) 6 | { 7 | this.eye = eye; this.worldup = up; this.yaw = yaw; this.pitch = pitch; 8 | this.turnspeed = turnspeed; 9 | this.worldAt = at; 10 | this.distance = distance; 11 | this.front = [0.0, 0.0, -1.0]; 12 | 13 | this.right = vec3.create(); 14 | this.up = vec3.create(); 15 | 16 | this.Update(); 17 | } 18 | 19 | CalculateViewMatrix() 20 | { 21 | //mat4의 lookAt은 camera matrix를 반환합니다. 22 | let cameramat = mat4.create(); 23 | let at = vec3.create(); 24 | vec3.add(at, this.eye,this.front) 25 | mat4.lookAt(cameramat, this.eye, at, this.up); 26 | return cameramat; 27 | } 28 | 29 | Update() 30 | { 31 | //yaw,pitch 각도를 사용해 eye 위치를 변경합니다. 32 | //구면 좌표계 -> 카르테시안 좌표계 변경식을 사용합니다. 33 | this.front[0] = Math.cos(this.yaw * Math.PI / 180) * Math.cos(this.pitch * Math.PI / 180); 34 | this.front[1] = Math.sin(this.pitch * Math.PI / 180); 35 | this.front[2] = Math.sin(this.yaw * Math.PI / 180) * Math.cos(this.pitch * Math.PI / 180) 36 | vec3.normalize(this.front,this.front); 37 | 38 | //기존 front 계산 결과의 방향을 뒤집고 길이가 distant인 벡터 back을 계산합니다. 39 | let back = vec3.create(); 40 | vec3.scale(back, this.front, -this.distance); 41 | 42 | //at에서 back만큼 떨어진 위치를 카메라 위치로 설정합니다. 43 | vec3.add(this.eye, this.worldAt, back); 44 | 45 | //front 방향과 up 방향을 외적해 right 방향을 계산합니다. 46 | vec3.cross(this.right, this.front, this.worldup) 47 | vec3.normalize(this.right,this.right); 48 | //마지막으로 front 방향과 right 방향을 외적해 up 방향을 계산합니다. 49 | vec3.cross(this.up, this.right, this.front) 50 | vec3.normalize(this.up,this.up); 51 | } 52 | } -------------------------------------------------------------------------------- /lessons/_classes/Texture.js: -------------------------------------------------------------------------------- 1 | //Texture class 2 | export default class Texture { 3 | id; 4 | image; 5 | 6 | constructor(gl) 7 | { 8 | this.id = gl.createTexture(); 9 | gl.bindTexture(gl.TEXTURE_2D, this.id); 10 | 11 | //텍스처 맵핑 및 필터링 옵션 설정 12 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 13 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 14 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 15 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 16 | 17 | //1x1 크기의 임시 텍스처를 생성합니다. 18 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, 19 | new Uint8Array([0, 0, 255, 255])); 20 | gl.bindTexture(gl.TEXTURE_2D, null); 21 | 22 | } 23 | 24 | LoadTextureFromImage(gl, path) 25 | { 26 | this.image = new Image(); 27 | 28 | //아래 익명함수 대신 콜백을 별도로 구현해 사용해도 됩니다. 29 | //다만 이벤트 리스너 설정을 src 설정 이전에 해주어야 합니다. 30 | //this.image.addEventListener("load", this.ChangeTexture(gl)); 31 | 32 | this.image.src = path; 33 | this.image.crossOrigin = ""; // CORS 권한 요청 34 | // 텍스처를 로딩할 때 시간이 소요됩니다. 로드가 완료되면 그 이미지로 임시 텍스처를 대체합니다. 35 | this.image.onload = () => { 36 | gl.bindTexture(gl.TEXTURE_2D, this.id); 37 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA,gl.UNSIGNED_BYTE, this.image); 38 | gl.generateMipmap(gl.TEXTURE_2D); 39 | gl.bindTexture(gl.TEXTURE_2D, null); 40 | }; 41 | } 42 | 43 | //slot은 texture unit을 명시합니다. 44 | //자세한 내용은 강의 자료를 참고하세요. 45 | Bind(gl,slot) 46 | { 47 | gl.activeTexture(gl.TEXTURE0 + slot); 48 | gl.bindTexture(gl.TEXTURE_2D, this.id); 49 | } 50 | 51 | Unbind(gl) 52 | { 53 | gl.bindTexture(gl.TEXTURE_2D, null); 54 | } 55 | } -------------------------------------------------------------------------------- /lessons/_classes/Model.js: -------------------------------------------------------------------------------- 1 | import VertexBuffer from '../_classes/VertexBuffer.js'; 2 | import IndexBuffer from '../_classes/IndexBuffer.js'; 3 | import VertexArray from '../_classes/VertexArray.js'; 4 | import Renderer from '../_classes/Renderer.js'; 5 | 6 | //Model class 7 | export default class Model { 8 | //각 모델은 고유의 VAO, VBO, IBO를 갖습니다. 9 | VAO; 10 | VBO; 11 | IBO; 12 | 13 | //경로의 모델을 읽어오고, VAO, IBO에 저장 14 | async LoadModel(gl, path) 15 | { 16 | var response = await fetch(path); 17 | var text = await response.text(); 18 | this.mesh = new OBJ.Mesh(text); //라이브러리의 Mesh 메소드로 obj를 파싱합니다. 19 | 20 | var meshVertexData = [] 21 | 22 | var vertexCount = this.mesh.vertices.length/3; 23 | for(var i=0; ic.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div"); 4 | k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display= 5 | "block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:11,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height= 6 | a+"px",m=b,r=0);return b},update:function(){l=this.end()}}}; 7 | -------------------------------------------------------------------------------- /resources/drag-and-drop.js: -------------------------------------------------------------------------------- 1 | const handlers = { 2 | onDropFile: () => {}, 3 | }; 4 | 5 | export function setup(options) { 6 | const html = ` 7 | 31 | 36 | `; 37 | 38 | const elem = document.createElement('div'); 39 | elem.innerHTML = html; 40 | document.body.appendChild(elem); 41 | 42 | const dragInfo = document.querySelector('.dragInfo'); 43 | function showDragInfo(show) { 44 | dragInfo.style.display = show ? '' : 'none'; 45 | } 46 | 47 | document.body.addEventListener('dragenter', () => { 48 | showDragInfo(true); 49 | }); 50 | 51 | const dragElem = dragInfo; 52 | 53 | dragElem.addEventListener('dragover', (e) => { 54 | e.preventDefault(); 55 | return false; 56 | }); 57 | 58 | dragElem.addEventListener('dragleave', () => { 59 | showDragInfo(false); 60 | return false; 61 | }); 62 | 63 | dragElem.addEventListener('dragend', () => { 64 | showDragInfo(false); 65 | return false; 66 | }); 67 | 68 | dragElem.addEventListener('drop', (e) => { 69 | e.preventDefault(); 70 | showDragInfo(false); 71 | if (e.dataTransfer.items && e.dataTransfer.items) { 72 | let fileNdx = 0; 73 | for (let i = 0; i < e.dataTransfer.items.length; ++i) { 74 | const item = e.dataTransfer.items[i]; 75 | if (item.kind === 'file') { 76 | handlers.onDropFile(item.getAsFile(), fileNdx++); 77 | } 78 | } 79 | } 80 | 81 | return false; 82 | }); 83 | 84 | } 85 | 86 | export function onDropFile(fn) { 87 | handlers.onDropFile = fn; 88 | } 89 | 90 | -------------------------------------------------------------------------------- /lessons/01_vertex_buffer/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 1.VertexBuffer 6 | 7 | 8 | 9 |
WebGL Vertex Buffer
10 | 11 | 12 | 13 | 14 | 72 | -------------------------------------------------------------------------------- /resources/flattened-primitives.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | "use strict"; 3 | 4 | // this function takes a set of indexed vertices 5 | // It deindexed them. It then adds random vertex 6 | // colors to each triangle. Finally it passes 7 | // the result to createBufferInfoFromArrays and 8 | // returns a twgl.BufferInfo 9 | function createFlattenedVertices(gl, vertices, vertsPerColor) { 10 | let last; 11 | return twgl.createBufferInfoFromArrays( 12 | gl, 13 | twgl.primitives.makeRandomVertexColors( 14 | twgl.primitives.deindexVertices(vertices), 15 | { 16 | vertsPerColor: vertsPerColor || 1, 17 | rand: function(ndx, channel) { 18 | if (channel === 0) { 19 | last = 128 + Math.random() * 128 | 0; 20 | } 21 | return channel < 3 ? last : 255; 22 | }, 23 | }) 24 | ); 25 | } 26 | 27 | function createFlattenedFunc(createVerticesFunc, vertsPerColor) { 28 | return function(gl) { 29 | const arrays = createVerticesFunc.apply(null, Array.prototype.slice.call(arguments, 1)); 30 | return createFlattenedVertices(gl, arrays, vertsPerColor); 31 | }; 32 | } 33 | 34 | // These functions make primitives with semi-random vertex colors. 35 | // This means the primitives can be displayed without needing lighting 36 | // which is important to keep the samples simple. 37 | 38 | window.flattenedPrimitives = { 39 | "create3DFBufferInfo": createFlattenedFunc(twgl.primitives.create3DFVertices, 6), 40 | "createCubeBufferInfo": createFlattenedFunc(twgl.primitives.createCubeVertices, 6), 41 | "createPlaneBufferInfo": createFlattenedFunc(twgl.primitives.createPlaneVertices, 6), 42 | "createSphereBufferInfo": createFlattenedFunc(twgl.primitives.createSphereVertices, 6), 43 | "createTruncatedConeBufferInfo": createFlattenedFunc(twgl.primitives.createTruncatedConeVertices, 6), 44 | "createXYQuadBufferInfo": createFlattenedFunc(twgl.primitives.createXYQuadVertices, 6), 45 | "createCresentBufferInfo": createFlattenedFunc(twgl.primitives.createCresentVertices, 6), 46 | "createCylinderBufferInfo": createFlattenedFunc(twgl.primitives.createCylinderVertices, 6), 47 | "createTorusBufferInfo": createFlattenedFunc(twgl.primitives.createTorusVertices, 6), 48 | "createDiscBufferInfo": createFlattenedFunc(twgl.primitives.createDiscVertices, 4), 49 | }; 50 | 51 | }()); 52 | 53 | -------------------------------------------------------------------------------- /resources/models/chair/chair.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 11 3 | 4 | newmtl D1blinn1SG 5 | Ns 323.999994 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.500000 0.500000 0.500000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.0 0.0 0.0 10 | Ni 1.000000 11 | d 1.000000 12 | illum 2 13 | 14 | newmtl D1lambert2SG 15 | Ns 323.999994 16 | Ka 1.000000 1.000000 1.000000 17 | Kd 0.020000 0.020000 0.020000 18 | Ks 0.500000 0.500000 0.500000 19 | Ke 0.0 0.0 0.0 20 | Ni 1.000000 21 | d 1.000000 22 | illum 2 23 | 24 | newmtl D1lambert3SG 25 | Ns 323.999994 26 | Ka 1.000000 1.000000 1.000000 27 | Kd 1.000000 1.000000 1.000000 28 | Ks 0.500000 0.500000 0.500000 29 | Ke 0.0 0.0 0.0 30 | Ni 1.000000 31 | d 1.000000 32 | illum 2 33 | 34 | newmtl D1lambert4SG 35 | Ns 323.999994 36 | Ka 1.000000 1.000000 1.000000 37 | Kd 1.000000 0.260000 0.560000 38 | Ks 0.500000 0.500000 0.500000 39 | Ke 0.0 0.0 0.0 40 | Ni 1.000000 41 | d 1.000000 42 | illum 2 43 | 44 | newmtl Dblinn1SG 45 | Ns 323.999994 46 | Ka 1.000000 1.000000 1.000000 47 | Kd 0.500000 0.500000 0.500000 48 | Ks 0.500000 0.500000 0.500000 49 | Ke 0.0 0.0 0.0 50 | Ni 1.000000 51 | d 1.000000 52 | illum 2 53 | 54 | newmtl Dblinn2SG 55 | Ns 323.999994 56 | Ka 1.000000 1.000000 1.000000 57 | Kd 0.500000 0.500000 0.500000 58 | Ks 0.500000 0.500000 0.500000 59 | Ke 0.0 0.0 0.0 60 | Ni 1.000000 61 | d 1.000000 62 | illum 2 63 | 64 | newmtl Dlambert2SG 65 | Ns 323.999994 66 | Ka 1.000000 1.000000 1.000000 67 | Kd 0.020000 0.020000 0.020000 68 | Ks 0.500000 0.500000 0.500000 69 | Ke 0.0 0.0 0.0 70 | Ni 1.000000 71 | d 1.000000 72 | illum 2 73 | 74 | newmtl Dlambert3SG 75 | Ns 323.999994 76 | Ka 1.000000 1.000000 1.000000 77 | Kd 1.000000 1.000000 1.000000 78 | Ks 0.500000 0.500000 0.500000 79 | Ke 0.0 0.0 0.0 80 | Ni 1.000000 81 | d 1.000000 82 | illum 2 83 | 84 | newmtl Dlambert4SG 85 | Ns 323.999994 86 | Ka 1.000000 1.000000 1.000000 87 | Kd 1.000000 0.260000 0.560000 88 | Ks 0.500000 0.500000 0.500000 89 | Ke 0.0 0.0 0.0 90 | Ni 1.000000 91 | d 1.000000 92 | illum 2 93 | 94 | newmtl initialShadingGroup 95 | Ns 323.999994 96 | Ka 1.000000 1.000000 1.000000 97 | Kd 0.070000 0.580000 0.640000 98 | Ks 0.500000 0.500000 0.500000 99 | Ke 0.0 0.0 0.0 100 | Ni 1.000000 101 | d 1.000000 102 | illum 2 103 | 104 | newmtl lambert18SG 105 | Ns 323.999994 106 | Ka 1.000000 1.000000 1.000000 107 | Kd 0.050000 0.460000 0.510000 108 | Ks 0.500000 0.500000 0.500000 109 | Ke 0.0 0.0 0.0 110 | Ni 1.000000 111 | d 1.000000 112 | illum 2 113 | -------------------------------------------------------------------------------- /lessons/10_using_matrix/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //Classes 4 | import VertexBuffer from '../_classes/VertexBuffer.js'; 5 | import IndexBuffer from '../_classes/IndexBuffer.js'; 6 | import VertexArray from '../_classes/VertexArray.js'; 7 | import Shader from '../_classes/Shader.js'; 8 | import Renderer from '../_classes/Renderer.js'; 9 | 10 | //Shaders 11 | import basicProjectionFragmentShader from '../_shaders/basicProjectionFragment.js'; 12 | import basicProjectionVertexShader from '../_shaders/basicProjectionVertex.js'; 13 | 14 | const {mat2, mat3, mat4, vec2, vec3, vec4} = glMatrix; 15 | 16 | function main() { 17 | // Get A WebGL context 18 | var canvas = document.querySelector("#c"); 19 | var gl = canvas.getContext("webgl2"); 20 | if (!gl) { 21 | return; 22 | } 23 | 24 | //--사각형 데이터 25 | var rectangleVertices = [ 26 | //x y r g b a 27 | -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, //0번 vertex 28 | 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, //1번 vertex 29 | 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, //2번 vertex 30 | -0.5, 0.5, 0.8, 0.2, 0.3, 1.0, //3번 vertex 31 | ]; 32 | 33 | var rectangleIndices = [ 34 | 0, 1, 2, //0,1,2번 vertex로 이루어진 삼각형 35 | 2, 3, 0, //2,3,0번 vertex로 이루어진 삼각형 36 | ]; 37 | 38 | let rectVA = new VertexArray(gl); 39 | let rectangleVB = new VertexBuffer(gl,rectangleVertices); 40 | rectVA.AddBuffer(gl, rectangleVB, [2, 4], [false, false]); 41 | let rectangleIB = new IndexBuffer(gl, rectangleIndices, 6); 42 | 43 | //glMatrix의 함수를 사용해 orthographic projection matrix를 생성합니다. 44 | let proj = mat4.create(); 45 | mat4.ortho(proj,-2.0, 2.0, -1.5, 1.5, -1.0, 1.0); 46 | 47 | let shader = new Shader(gl,basicProjectionVertexShader,basicProjectionFragmentShader); 48 | 49 | rectVA.Unbind(gl); 50 | rectangleVB.Unbind(gl); 51 | rectangleIB.Unbind(gl); 52 | 53 | let renderer = new Renderer(); 54 | gl.clearColor(1.0, 1.0, 1.0, 1.0); 55 | 56 | drawScene(); 57 | 58 | //화면을 새로 그리기 위한 명령어들을 모아 함수로 구현하였음 59 | function drawScene() 60 | { 61 | //정확한 사이즈를 보기 위해서는 아래 두 줄 코드를 추가해야 합니다. 62 | //Viewport의 경우 이후 강의의 viewport transform에서 살펴볼 것입니다. 63 | webglUtils.resizeCanvasToDisplaySize(gl.canvas); 64 | gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); 65 | 66 | renderer.Clear(gl); 67 | 68 | shader.Bind(gl); //Uniform 설정에 필요하기 때문에 바인딩 69 | 70 | let blueColor = vec4.fromValues(0.0, 0.0, 1.0, 1.0); 71 | shader.SetUniform4f(gl,"u_color", blueColor[0], blueColor[1], blueColor[2], blueColor[3]); 72 | shader.SetUniformMat4f(gl, "u_projection", proj); //proj 행렬을 shader로 넘깁니다. SetUniformMat4f 함수가 shader 클래스에 추가되어야 합니다. 73 | 74 | renderer.Draw(gl, rectVA, rectangleIB, shader); 75 | 76 | rectVA.Unbind(gl); 77 | shader.Unbind(gl); 78 | } 79 | } 80 | 81 | main(); -------------------------------------------------------------------------------- /resources/tdl/log.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | /** 34 | * @fileoverview This file contains objects to deal with logging. 35 | */ 36 | 37 | tdl.provide('tdl.log'); 38 | 39 | tdl.require('tdl.string'); 40 | 41 | /** 42 | * A module for log. 43 | * @namespace 44 | */ 45 | tdl.log = tdl.log || {}; 46 | 47 | 48 | /** 49 | * Wrapped logging function. 50 | * @param {*} msg The message to log. 51 | */ 52 | tdl.log = function() { 53 | var str = tdl.string.argsToString(arguments); 54 | if (window.console && window.console.log) { 55 | window.console.log(str); 56 | } else if (window.dump) { 57 | window.dump(str + "\n"); 58 | } 59 | }; 60 | 61 | /** 62 | * Wrapped logging function. 63 | * @param {*} msg The message to log. 64 | */ 65 | tdl.error = function() { 66 | var str = tdl.string.argsToString(arguments); 67 | if (window.console) { 68 | if (window.console.error) { 69 | window.console.error(str); 70 | } else if (window.console.log) { 71 | window.console.log(str); 72 | } else if (window.dump) { 73 | window.dump(str + "\n"); 74 | } 75 | } 76 | }; 77 | 78 | /** 79 | * Dumps an object to the console. 80 | * 81 | * @param {!Object} obj Object to dump. 82 | * @param {string} opt_prefix string to prefix each value with. 83 | */ 84 | tdl.dumpObj = function(obj, opt_prefix) { 85 | tdl.log(tdl.string.objToString(obj, opt_prefix)); 86 | }; 87 | 88 | 89 | -------------------------------------------------------------------------------- /lessons/_shaders/PBRShaderFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | 4 | precision highp float; 5 | 6 | layout(location=0) out vec4 outColor; 7 | 8 | in vec2 v_texCoords; 9 | in vec3 v_worldPosition; 10 | in vec3 v_normal; 11 | 12 | // material parameters 13 | uniform vec3 u_albedo; 14 | uniform float u_metallic; 15 | uniform float u_roughness; 16 | uniform float u_ao; 17 | 18 | // lights 19 | uniform vec3 u_lightPositions[4]; 20 | uniform vec3 u_lightColors[4]; 21 | 22 | uniform vec3 u_eyePosition; 23 | 24 | const float PI = 3.14159265359; 25 | 26 | float DistributionGGX (vec3 N, vec3 H, float roughness){ 27 | float a2 = roughness * roughness * roughness * roughness; 28 | float NdotH = max (dot (N, H), 0.0); 29 | float denom = (NdotH * NdotH * (a2 - 1.0) + 1.0); 30 | return a2 / (PI * denom * denom); 31 | } 32 | 33 | float GeometrySchlickGGX (float NdotV, float roughness){ 34 | float r = (roughness + 1.0); 35 | float k = (r * r) / 8.0; 36 | return NdotV / (NdotV * (1.0 - k) + k); 37 | } 38 | 39 | float GeometrySmith (vec3 N, vec3 V, vec3 L, float roughness){ 40 | return GeometrySchlickGGX (max (dot (N, L), 0.0), roughness) * 41 | GeometrySchlickGGX (max (dot (N, V), 0.0), roughness); 42 | } 43 | 44 | vec3 FresnelSchlick (float cosTheta, vec3 F0){ 45 | return F0 + (1.0 - F0) * pow (1.0 - cosTheta, 5.0); 46 | } 47 | 48 | void main() 49 | { 50 | vec3 N = normalize(v_normal); 51 | vec3 V = normalize(u_eyePosition - v_worldPosition); 52 | 53 | vec3 F0 = vec3(0.04); 54 | F0 = mix(F0, u_albedo, u_metallic); 55 | 56 | // reflectance equation 57 | vec3 Lo = vec3(0.0); 58 | for(int i = 0; i < 4; ++i) 59 | { 60 | // calculate per-light radiance 61 | vec3 L = normalize(u_lightPositions[i] - v_worldPosition); 62 | vec3 H = normalize(V + L); 63 | float distance = length(u_lightPositions[i] - v_worldPosition); 64 | float attenuation = 1.0 / (distance * distance); 65 | vec3 radiance = u_lightColors[i] * attenuation; 66 | 67 | // cook-torrance brdf 68 | float NDF = DistributionGGX(N, H, u_roughness); 69 | float G = GeometrySmith(N, V, L, u_roughness); 70 | vec3 F = FresnelSchlick(max(dot(H, V), 0.0), F0); 71 | 72 | vec3 kS = F; 73 | vec3 kD = vec3(1.0) - kS; 74 | kD *= 1.0 - u_metallic; 75 | 76 | vec3 numerator = NDF * G * F; 77 | float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001; 78 | vec3 specular = numerator / denominator; 79 | 80 | // add to outgoing radiance Lo 81 | float NdotL = max(dot(N, L), 0.0); 82 | Lo += (kD * u_albedo / PI + specular) * radiance * NdotL; 83 | } 84 | 85 | vec3 ambient = vec3(0.03) * u_albedo * u_ao; 86 | vec3 color = ambient + Lo; 87 | 88 | color = color / (color + vec3(1.0)); 89 | color = pow(color, vec3(1.0/2.2)); 90 | 91 | outColor = vec4(color, 1.0); 92 | }` -------------------------------------------------------------------------------- /lessons/04_shader_uniform/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 4.Shader Uniform 6 | 7 | 8 | 9 |
WebGL 4.Shader Uniform
10 | 11 | 12 | 13 | 14 | 98 | -------------------------------------------------------------------------------- /lessons/_shaders/dirShadowBiasFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | precision highp float; 4 | 5 | struct Light 6 | { 7 | vec3 lightColor; 8 | float ambientIntensity; 9 | float diffuseIntensity; 10 | }; 11 | 12 | struct DirectionalLight 13 | { 14 | Light base; 15 | vec3 direction; 16 | }; 17 | 18 | struct Material 19 | { 20 | float specularIntensity; 21 | float shininess; //sh 22 | }; 23 | 24 | layout(location=0) out vec4 outColor; 25 | 26 | uniform sampler2D u_mainTexture; 27 | uniform DirectionalLight u_directionalLight; 28 | uniform vec3 u_eyePosition; 29 | uniform Material u_material; 30 | uniform sampler2D u_depthMap; //depth map 31 | 32 | in vec2 v_texcoord; 33 | in vec3 v_normal; 34 | in vec3 v_worldPosition; 35 | in vec4 v_lightSpacePos; //light 공간 좌표 36 | 37 | 38 | float CalculateShadowFactor(DirectionalLight light) 39 | { 40 | //varying은 perspective division을 자동으로 해주지 않기 때문에 직접 해주어야 함 41 | vec3 projCoords = v_lightSpacePos.xyz / v_lightSpacePos.w; 42 | 43 | //위에서 계산한 projCoord는 NDC상 좌표. 이를 [0,1]로 변환 (xy는 texture 좌표, z는 depth로 사용) 44 | projCoords = (projCoords * 0.5) + 0.5; 45 | 46 | //z는 현재 그리려는 픽셀 위치의 depth map에 저장된 깊이값 47 | float z = texture(u_depthMap, projCoords.xy).r; 48 | //d는 light로부터 현재 그리려는 픽셀까지의 깊이값 49 | float d = projCoords.z; 50 | 51 | //Shadow acne를 해결하기 위해 bias를 추가해 보겠습니다. 52 | //강의 자료에서보다 발전한 알고리즘을 사용합니다. 53 | vec3 normal = normalize(v_normal); 54 | vec3 lightDir = normalize(-light.direction); 55 | float bias = max(0.05*(1.0 - dot(normal,lightDir)), 0.0005); 56 | 57 | float shadowFactor = d - bias > z ? 1.0 : 0.0; 58 | 59 | if(d > 1.0) 60 | { 61 | shadowFactor = 0.0; 62 | } 63 | 64 | if(projCoords.x > 1.0 || projCoords.y > 1.0 || projCoords.x < 0.0 || projCoords.y < 0.0) 65 | { 66 | shadowFactor = 0.0; 67 | } 68 | 69 | return shadowFactor; 70 | } 71 | 72 | vec3 CalculateLight(Light light, vec3 direction, float shadowFactor) //shadow Factor가 추가됨 73 | { 74 | vec3 normal = normalize(v_normal); 75 | 76 | //ambient 77 | vec3 lightAmbient = light.lightColor * light.ambientIntensity; 78 | 79 | //diffuse 80 | vec3 lightDir = normalize(-direction); 81 | float diffuseFactor = max(dot(normal, lightDir), 0.0); 82 | vec3 lightDiffuse = light.lightColor * light.diffuseIntensity * diffuseFactor; 83 | 84 | //specular 85 | vec3 vVec = normalize(u_eyePosition - v_worldPosition); 86 | vec3 rVec = 2.0 * normal * dot(normal, lightDir) - lightDir; 87 | vec3 lightSpecular = pow(max(dot(rVec,vVec),0.0),u_material.shininess) * light.lightColor * u_material.specularIntensity; 88 | 89 | //ambient는 그림자에 영향을 받지 않지만 diffuse와 specular는 그림자 여부에 영향을 받음 90 | return (lightAmbient + (1.0-shadowFactor) * (lightDiffuse + lightSpecular)); 91 | 92 | } 93 | 94 | vec3 CalculateDirectionalLight() 95 | { 96 | float shadowFactor = CalculateShadowFactor(u_directionalLight); 97 | return CalculateLight(u_directionalLight.base, u_directionalLight.direction, shadowFactor); 98 | 99 | } 100 | 101 | void main() { 102 | vec3 lightColor = CalculateDirectionalLight(); 103 | outColor = texture(u_mainTexture, v_texcoord) * vec4(lightColor,1.0); 104 | } 105 | `; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WebGL Computer Graphics Lecture Material 2 | 3 | "컴퓨터 그래픽스"강의를 위한 Repository입니다. WebGL을 기반으로 합니다. 4 | 5 | WebGL 구현을 위해 JS(자바스크립트)와 GLSL을 사용합니다. HTML과 CSS도 밀접하게 관련되어 있으나 이 강의에서는 단순 사용만 할 뿐, 내용을 다루지 않습니다. 6 | 7 | ## Why WebGL? 8 | 9 | 이전 강의에서는 C++과 OpenGL을 사용하여 컴퓨터 그래픽스 강의에 대한 실습을 진행하였습니다. 물론 큰 문제는 없었지만 아래와 같은 이유로 인해 WebGL을 사용하는 것으로 실습 환경을 바꾸는 것이 좋겠다고 생각하여 이 Repository를 만들었습니다. 10 | 11 | 1. OpenGL은 플랫폼 독립적이지만, 함께 사용하는 GLFW, GLEW의 경우 Windows/Mac에서 사용 방법에 차이가 있어서 Mac을 사용하는 학생이 어려움을 겪는 경우가 있습니다. 12 | 13 | 2. 향후 여러분이 직접 OpenGL 프로그래밍을 할 일은 거의 없으실겁니다. (Direct3D라면 조금 가능성이 있겠지만요.) 따라서 굳이 OpenGL Specific한 내용을 배운다고 미래에 도움이 되지는 않을겁니다. 오히려 WebGL은 실무에서 약간 사용할 수도 있을 것 같습니다. 14 | 15 | 3. 이 수업은 WebGL(또는 OpenGL) 프로그래밍을 가르치는 수업이 아니고 컴퓨터 그래픽스 동작 방식을 배우는 수업이며, WebGL은 직접 이를 눈으로 확인하기 위한 수단일 뿐입니다. 따라서 이 수업의 목적을 위해서는 둘 중 어느 환경에서 실습해도 우열은 없습니다. 16 | 17 | 4. WebGL이든 OpenGL이든 여러분이 API를 통해 해야 할 일은 동일합니다. **WebGL을 사용할 줄 알면, OpenGL은 손쉽게 사용 가능**하고 그 반대도 마찬가지입니다. 18 | 19 | 그래도 여전히 OpenGL로 내용을 보고 싶으신 분들은 이 Repository와 거의 동일한 구성으로 만들어진 [OpenGL 강의 코드](https://github.com/diskhkme/OpenGL_Lecture_Material)를 보시면 됩니다. 20 | 21 | ## How to use 22 | - 이 Repository를 학습을 위해 사용하려면, `/lessons/` 하위 각 챕터의 README.md 파일을 차례대로 읽으며 해당하는 파일을 보시면 됩니다. 23 | 24 | - 강의의 중후반부부터는 추가 또는 수정한 모든 내역을 설명하고 있지는 않습니다. 직접 코드를 살펴보시거나, 해당하는 커밋 히스토리를 직접 참고 하시길 바랍니다. 25 | 26 | - 실제 이 사이트 코드를 사용해 웹브라우저로 WebGL 화면을 보는 방법은 `/lessons/0_Setup/`을 참고하세요. 27 | 28 | ## Folder Structure 29 | - 주요 폴더들과 그 설명은 아래와 같습니다. 30 | * `/resources/`: HTML 페이지에 사용할 CSS, 렌더링에 사용할 모델(*.obj) 및 텍스처 이미지, 외부 라이브러리 코드가 포함되어 있습니다. (출처: [WebGL2 Fundamental Repository](https://github.com/gfxfundamentals/webgl2-fundamentals)) 31 | * `/lessons/_classes/`: 진행 도중 작성할 클래스 구현 코드들이 들어있는 폴더입니다. (*주의: 이 사이트의 코드는 제가 이전에 [OpenGL 강의에 사용한 코드](https://github.com/diskhkme/OpenGL_Lecture_Material)와 통일성을 주기 위해 JS 스타일이 아닌 C++ 스타일을 모사하여 작성되었습니다. 실제 WebGL App을 작성하기 위해서는 JS 스타일에 맞게 구현하시는 것이 좋습니다.*) 32 | * `/lessons/_shaders/`: 진행 도중 작성할 GLSL 셰이더 코드들이 있는 폴더입니다. 33 | * `/lessons/_current/`: **현재 커밋의 가장 최신 HTML을 담고있는 코드입니다. "How to use"의 2번 방법을 따라가시는 분들은 이 폴더내 HTML코드의 변화에 주목하시면 됩니다.** 34 | * `lessons/#_XXX/`: 각 강의내용의 완성된 HTML을 개별적으로 분리하여 저장해 둔 폴더입니다. 35 | 36 | ## Important Links for Starting 37 | - [Mozilla의 WebGL Reference](https://developer.mozilla.org/ko/docs/Web/API/WebGL_API): WebGL 코드의 정의를 찾아볼 때는 이 링크를 사용하세요. 38 | - [WebGL2 Fundamental](https://webgl2fundamentals.org/webgl/lessons/ko/): 추가적인 설명이 보고싶거나, WebGL 관련한 보다 상세한 내용이 궁금할 때는 이 링크를 참고하세요. 39 | - [OpenGL Lecture Series](https://www.youtube.com/watch?v=W3gAzLwfIP0&list=PLlrATfBNZ98foTJPJ_Ev03o2oq3-GGOS2): "The Cherno"라는 개발자의 C++ OpenGL 강의 영상입니다. 제 [OpenGL 강의 코드](https://github.com/diskhkme/OpenGL_Lecture_Material)가 이 스타일을 따랐고, 이 Reposiroty의 코드도 이 스타일을 따르고 있습니다. 40 | - [Serves](https://greggman.github.io/servez/): 이 Repository의 결과물을 정상적으로 보려면 웹서버가 필요합니다. 간단하게 설치할 수 있는 웹서버입니다. (`/lessons/0_Setup/`에서 설치, 사용 방법 설명) 41 | 42 | ## Ray Tracing 43 | - 다른 카테고리의 렌더링 방법으로 광선 추적(Ray Tracing)이 있습니다. 광선 추적 또한 이번 학기 강의 후반부에 다룰 예정입니다. 44 | - 가장 좋은 공부 방법은 [TinyRaytracer](https://github.com/ssloy/tinyraytracer) 또는 [Ray Tracing in one weekend](https://raytracing.github.io/books/RayTracingInOneWeekend.html)와 같은 자료를 참고하여 직접 구현해 보는 것입니다. 45 | - 해당 자료들을 기반으로 제가 구현한 코드는 [링크](https://github.com/diskhkme/TinyRaytracer_SFML)에 있으니 참고 하시기 바랍니다. 46 | -------------------------------------------------------------------------------- /resources/webgl-tutorials.css: -------------------------------------------------------------------------------- 1 | /* Licensed under a BSD license. See ../license.html for license */ 2 | 3 | html { 4 | box-sizing: border-box; 5 | } 6 | *, *:before, *:after { 7 | box-sizing: inherit; 8 | user-select: none; 9 | } 10 | 11 | body { 12 | background-color: #aaa; 13 | font-family: Sans-Serif; 14 | } 15 | 16 | canvas { 17 | background-color: #fff; 18 | border: 1px solid black; 19 | /* NOTE: This size is changed if in iframe - see below '.iframe canvas' */ 20 | width: 800px; 21 | height: 600px; 22 | display: block; 23 | } 24 | 25 | #uiContainer { 26 | position: absolute; 27 | top: 10px; 28 | right: 10px; 29 | z-index: 3; 30 | font-family: monospace; 31 | pointer-events: none; 32 | 33 | text-shadow: 34 | -1px -1px 0 #FFF, 35 | 1px -1px 0 #FFF, 36 | -1px 1px 0 #FFF, 37 | 1px 1px 0 #FFF; 38 | } 39 | #ui { 40 | opacity: 0.8; 41 | } 42 | #ui>div { 43 | pointer-events: none; 44 | } 45 | #ui input, #ui select, #ui option, #ui canvas { 46 | pointer-events: auto; 47 | } 48 | 49 | .gman-slider-label, .gman-widget-label, .gman-checkbox-label { 50 | font-size: small; 51 | min-width: 10em; 52 | text-align: right; 53 | } 54 | .gman-checkbox-label { 55 | pointer-events: auto; 56 | } 57 | .gman-widget-value { 58 | float: right; 59 | font-size: small; 60 | order: 1; 61 | min-width: 3em; 62 | } 63 | 64 | .gman-slider-upper { 65 | height: 1.5em; 66 | } 67 | .gman-slider-outer, .gman-widget-outer { 68 | float: right; 69 | display: flex; 70 | align-items: center; 71 | height: 1.7em; 72 | } 73 | .gman-widget-slider, .gman-widget-checkbox, .gman-widget-select { 74 | opacity: 0.5; 75 | font-size: large; 76 | margin-left: .3em; 77 | margin-right: .3em; 78 | } 79 | .gman-widget-select { 80 | font-size: small; 81 | } 82 | .gman-widget-slider { 83 | min-width: 120px; 84 | } 85 | 86 | 87 | /* styles to apply if in an iframe */ 88 | 89 | html.iframe { 90 | height: 100vh; 91 | } 92 | body.iframe { 93 | width: 100vw; 94 | height: 100vh; 95 | margin: 0; 96 | } 97 | 98 | .iframe>.description { 99 | display: none; 100 | } 101 | .iframe .divcanvas { 102 | width: 100vw; 103 | height: 100vh; 104 | } 105 | .iframe canvas { 106 | width: 100vw; 107 | height: 100vh; 108 | max-width: 100vw; 109 | border: none; 110 | } 111 | 112 | .iframe>#example { 113 | width: 100%; 114 | height: 100%; 115 | } 116 | #ui #rotation>canvas { 117 | background-color: rgba(255, 255, 255, 0.6); 118 | } 119 | #ui { 120 | width: 200px; 121 | } 122 | 123 | @media (max-width: 390px) { 124 | pre { 125 | font-size: xx-small !important; 126 | max-width: 300px !important; 127 | } 128 | canvas { 129 | width: 100vw; 130 | } 131 | .iframe canvas { 132 | width: 100vw; 133 | height: 100vh; 134 | border: none; 135 | } 136 | #uiContainer { 137 | top: 120px; 138 | } 139 | .iframe #uiContainer { 140 | top: 10px; 141 | } 142 | } 143 | 144 | @media (prefers-color-scheme: dark) { 145 | #ui .ui-dark-support { 146 | color: white; 147 | text-shadow: 148 | -1px -1px 0 #000, 149 | 1px -1px 0 #000, 150 | -1px 1px 0 #000, 151 | 1px 1px 0 #000; 152 | } 153 | } 154 | 155 | -------------------------------------------------------------------------------- /resources/tdl/fullscreen.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | /** 34 | * @fileoverview This file contains misc functions to deal with 35 | * fullscreen. 36 | */ 37 | 38 | tdl.provide('tdl.fullscreen'); 39 | 40 | /** 41 | * A module for misc. 42 | * @namespace 43 | */ 44 | tdl.fullscreen = tdl.fullscreen || {}; 45 | 46 | tdl.fullscreen.requestFullScreen = function(element) { 47 | if (element.webkitRequestFullScreen) { 48 | element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT); 49 | } else if (element.mozRequestFullScreen) { 50 | element.mozRequestFullScreen(); 51 | } 52 | }; 53 | 54 | tdl.fullscreen.cancelFullScreen = function(element) { 55 | if (document.webkitCancelFullScreen) { 56 | document.webkitCancelFullScreen(); 57 | } else if (document.mozCancelFullScreen) { 58 | document.mozCancelFullScreen(); 59 | } 60 | }; 61 | 62 | tdl.fullscreen.onFullScreenChange = function(element, callback) { 63 | element.addEventListener('fullscreenchange', function(event) { 64 | callback(document.fullscreenEnabled); 65 | }); 66 | element.addEventListener('webkitfullscreenchange', function(event) { 67 | var fullscreenEnabled = document.webkitFullscreenEnabled; 68 | if (fullscreenEnabled === undefined) { 69 | fullscreenEnabled = document.webkitIsFullScreen; 70 | } 71 | callback(fullscreenEnabled); 72 | }); 73 | element.addEventListener('mozfullscreenchange', function(event) { 74 | var fullscreenEnabled = document.mozFullscreenEnabled; 75 | if (fullscreenEnabled === undefined) { 76 | fullscreenEnabled = document.mozFullScreen; 77 | } 78 | callback(fullscreenEnabled); 79 | }); 80 | }; 81 | 82 | 83 | -------------------------------------------------------------------------------- /lessons/13_model_abstraction/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //Classes 4 | import Shader from '../_classes/Shader.js'; 5 | import Renderer from '../_classes/Renderer.js'; 6 | import Camera from '../_classes/Camera.js'; 7 | import Model from '../_classes/Model.js'; 8 | 9 | //Shaders 10 | import basicVertexShader from '../_shaders/basicVertex.js'; 11 | import basicFragmentShader from '../_shaders/basicFragment.js'; 12 | 13 | const {mat2, mat3, mat4, vec2, vec3, vec4} = glMatrix; 14 | 15 | async function main() { 16 | // Get A WebGL context 17 | let canvas = document.querySelector("#c"); 18 | let gl = canvas.getContext("webgl2"); 19 | if (!gl) { 20 | return; 21 | } 22 | 23 | //---Model Loading 24 | let cube = new Model(); 25 | cube.LoadModel(gl, '../../resources/models/cube/cube.obj') 26 | 27 | let teapot = new Model(); 28 | teapot.LoadModel(gl, '../../resources/models/teapot/teapot.obj') 29 | 30 | //---Camera(view) Initialize 31 | let eye = [0.0, 0.0, 5.0]; 32 | let up = [0.0, 1.0, 0.0]; 33 | let yaw = -90.0; 34 | let pitch = 0.0; 35 | let movespeed = 0.05; 36 | let turnspeed = 0.5; 37 | let mainCamera = new Camera(eye,up,yaw,pitch,movespeed,turnspeed); 38 | 39 | //---Projection Initialize 40 | let fovRadian = 90.0 * Math.PI / 180; 41 | let aspect = gl.canvas.clientWidth/gl.canvas.clientHeight; 42 | let proj = mat4.create(); 43 | mat4.perspective(proj, fovRadian, aspect, 0.1, 100.0); 44 | 45 | //---Shader Initialize 46 | let shader = new Shader(gl,basicVertexShader,basicFragmentShader); 47 | shader.Bind(gl); 48 | shader.SetUniformMat4f(gl, "u_projection", proj); //<-- 특별한 경우가 아니면 proj는 실행도중 변경되지 않으므로 이곳으로 이동 49 | shader.Unbind(gl); 50 | 51 | //---Renderer Initialize 52 | let renderer = new Renderer(); 53 | gl.clearColor(1.0, 1.0, 1.0, 1.0); 54 | 55 | let rotationAngle = 0; 56 | 57 | requestAnimationFrame(drawScene); 58 | 59 | function drawScene() 60 | { 61 | //화면 크기 재조정 62 | webglUtils.resizeCanvasToDisplaySize(gl.canvas); 63 | gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); 64 | 65 | renderer.Clear(gl); 66 | 67 | shader.Bind(gl); //Uniform 설정에 필요하기 때문에 바인딩 68 | { 69 | //---카메라 설정(현재는 모든 모델에 대해 동일한 뷰행렬 사용) 70 | let view = mainCamera.CalculateViewMatrix(); 71 | shader.SetUniformMat4f(gl, "u_view", view); 72 | 73 | //---육면체 그리기 74 | rotationAngle += Math.PI * 1 / 180; 75 | 76 | let model = mat4.create(); 77 | mat4.fromXRotation(model, rotationAngle); 78 | shader.SetUniformMat4f(gl, "u_model", model); 79 | 80 | cube.RenderModel(gl, shader); 81 | 82 | //---주전자 그리기 83 | model = mat4.create(); 84 | mat4.translate(model, model, [3, 0, 0]); 85 | mat4.scale(model, model, [0.1, 0.1, 0.1]); 86 | shader.SetUniformMat4f(gl, "u_model", model); 87 | 88 | teapot.RenderModel(gl, shader); 89 | } 90 | 91 | shader.Unbind(gl); 92 | 93 | requestAnimationFrame(drawScene); 94 | } 95 | 96 | window.addEventListener('keydown', KeyboardEventHandler); 97 | window.addEventListener('mousemove', MouseMoveEventHandler); 98 | 99 | //키보드 이벤트 핸들러 함수 100 | function KeyboardEventHandler(e) 101 | { 102 | mainCamera.KeyControl(e); 103 | } 104 | 105 | //마우스 이벤트 핸들러 함수 106 | function MouseMoveEventHandler(e) 107 | { 108 | mainCamera.MouseControl(e); 109 | } 110 | } 111 | 112 | main(); -------------------------------------------------------------------------------- /resources/models/killer_whale/BLENDSWAP_LICENSE.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | Thank you for downloading "Office Interior design" by pasilan 3 | Released under 4 | Creative Commons Attribution 3.0 5 | Downloaded from http://www.blendswap.com/blends/view/65255 6 | 7 | The following is important licensing information, please keep this file for 8 | archival and future reference when working with the file. It's important that 9 | you know, understand and follow any requirements stated in this file regarding 10 | the usage of the materials included. 11 | 12 | Some parts of this file are marked with [#], the corresponding numbered note is 13 | at the end of the file. 14 | 15 | -------------------------------------------------------------------------------- 16 | ################################################################################ 17 | 18 | VERY IMPORTANT LICENSE INFORMATION: 19 | 20 | This blend has been released under 21 | Creative Commons Attribution 3.0 22 | 23 | This means that you can use it for any purpose you see fit, even commercially, 24 | as long as you respect these requirements: 25 | 26 | --You MUST give credit to pasilan. 27 | 28 | 29 | ################################################################################ 30 | -------------------------------------------------------------------------------- 31 | 32 | ABOUT THE BLEND: 33 | 34 | Ready for Blender 2.65 35 | Published on: 2013-01-17 06:26:31 36 | 37 | -------------------------------------------------------------------------------- 38 | 39 | HELP US MODERATE THIS BLEND: 40 | If you find anomalies in this blend or any of the contained files such as: 41 | 42 | - Missing, unneeded or corrupted files. 43 | - Inaccurate/mismatching preview image on the site. 44 | - Illegal distribution of third party files. 45 | - Ripping from a game or other 3D repository. 46 | - Uncredited or incorrect use of other CC licensed works. 47 | - Some other troubling issues[1]. 48 | 49 | Please submit a report from http://www.blendswap.com/blends/view/65255 50 | by pressing the red button with the flag, including links and details that serve 51 | as evidence and can help us to solve any conflicts or issues derived from the 52 | contents of this file. 53 | 54 | -------------------------------------------------------------------------------- 55 | 56 | Thank you for using Blend Swap! 57 | 58 | Register to get tons of more blends! http://www.blendswap.com/register 59 | Share your own blends with the world from http://www.blendswap.com/blends/add 60 | 61 | Get answers to your questions and doubts: http://www.blendswap.com/page/faq 62 | If the site doesn't work for you try here: http://www.blendswap.com/page/issues 63 | For questions please contact us: http://www.blendswap.com/contact 64 | Check out our Terms Of Use: http://www.blendswap.com/tou 65 | Report website bugs: http://www.blendswap.com/bugs 66 | 67 | Consider getting an associate Membership to get some neat features and 68 | enhancements. 69 | 70 | -------------------------------------------------------------------------------- 71 | 72 | NOTES: 73 | 74 | [1] Please make sure your problem is not derived from a setting in Blender (like 75 | hidden layers or objects) before submitting a report under the "Other" category. 76 | Issues arising from this type of problem will be ignored. 77 | 78 | -------------------------------------------------------------------------------- 79 | ###################### END OF BLEND SWAP LICENSE.txt ##################### -------------------------------------------------------------------------------- /lessons/02_shader_attribute/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 2.Shader_Attribute 6 | 7 | 8 | 9 |
WebGL Shader and Vertex Attribute
10 | 11 | 12 | 13 | 14 | 96 | -------------------------------------------------------------------------------- /resources/polygon-f.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 28 | 30 | 54 | 55 | 60 | Layer 1 62 | 64 | 71 | 78 | 79 | 81 | 88 | 95 | 96 | 98 | 105 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /resources/tdl/fps.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | /** 34 | * @fileoverview This file contains objects to measure frames 35 | * per second. 36 | */ 37 | 38 | tdl.provide('tdl.fps'); 39 | 40 | /** 41 | * A module for fps. 42 | * @namespace 43 | */ 44 | tdl.fps = tdl.fps || {}; 45 | 46 | /** 47 | * Number of frames to average over for computing FPS. 48 | * @type {number} 49 | */ 50 | tdl.fps.NUM_FRAMES_TO_AVERAGE = 16; 51 | 52 | /** 53 | * Measures frames per second. 54 | * @constructor 55 | */ 56 | tdl.fps.FPSTimer = function() { 57 | // total time spent for last N frames. 58 | this.totalTime_ = tdl.fps.NUM_FRAMES_TO_AVERAGE; 59 | 60 | // elapsed time for last N frames. 61 | this.timeTable_ = []; 62 | 63 | // where to record next elapsed time. 64 | this.timeTableCursor_ = 0; 65 | 66 | // Initialize the FPS elapsed time history table. 67 | for (var tt = 0; tt < tdl.fps.NUM_FRAMES_TO_AVERAGE; ++tt) { 68 | this.timeTable_[tt] = 1.0; 69 | } 70 | }; 71 | 72 | /** 73 | * Updates the fps measurement. You must call this in your 74 | * render loop. 75 | * 76 | * @param {number} elapsedTime The elasped time in seconds 77 | * since the last frame. 78 | */ 79 | tdl.fps.FPSTimer.prototype.update = function(elapsedTime) { 80 | // Keep the total time and total active time for the last N frames. 81 | this.totalTime_ += elapsedTime - this.timeTable_[this.timeTableCursor_]; 82 | 83 | // Save off the elapsed time for this frame so we can subtract it later. 84 | this.timeTable_[this.timeTableCursor_] = elapsedTime; 85 | 86 | // Wrap the place to store the next time sample. 87 | ++this.timeTableCursor_; 88 | if (this.timeTableCursor_ == tdl.fps.NUM_FRAMES_TO_AVERAGE) { 89 | this.timeTableCursor_ = 0; 90 | } 91 | 92 | this.instantaneousFPS = Math.floor(1.0 / elapsedTime + 0.5); 93 | this.averageFPS = Math.floor( 94 | (1.0 / (this.totalTime_ / tdl.fps.NUM_FRAMES_TO_AVERAGE)) + 0.5); 95 | }; 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /lessons/09_shader_renderer_abstraction/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import VertexBuffer from '../_classes/VertexBuffer.js'; 4 | import IndexBuffer from '../_classes/IndexBuffer.js'; 5 | import VertexArray from '../_classes/VertexArray.js'; 6 | import simpleFragmentShader from '../_shaders/simpleFragment.js'; 7 | import simpleVertexShader from '../_shaders/simpleVertex.js'; 8 | 9 | // Shader 클래스 구현 10 | class Shader{ 11 | id; 12 | locations = {}; 13 | 14 | constructor(gl, vsource, fsource) 15 | { 16 | this.id = webglUtils.createProgramFromSources(gl,[vsource, fsource]); 17 | } 18 | 19 | //Shader는 useProgram을 호출하지만 통일성을 위해 수정 20 | Bind(gl) 21 | { 22 | gl.useProgram(this.id); 23 | } 24 | 25 | Unbind(gl) 26 | { 27 | gl.useProgram(null); 28 | } 29 | 30 | GetUniformLocation(gl, name) 31 | { 32 | let location = 0; 33 | if(name in this.locations) 34 | { 35 | location = this.locations[name]; 36 | } 37 | else 38 | { 39 | location = gl.getUniformLocation(this.id, name); 40 | this.locations[name] = location; 41 | } 42 | return location; 43 | } 44 | 45 | //SetUniform 메소드들 46 | SetUniform4f(gl,name, v0,v1,v2,v3) 47 | { 48 | let location = this.GetUniformLocation(gl,name); 49 | gl.uniform4f(location, v0, v1, v2, v3); 50 | } 51 | } 52 | 53 | // Renderer 클래스 구현 54 | class Renderer{ 55 | Clear(gl) 56 | { 57 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 58 | } 59 | 60 | Draw(gl, va, ib, shader) 61 | { 62 | //무언가를 그릴때, 3가지가 기본적으로 필요함. vao, ibo, shader program 63 | shader.Bind(gl); 64 | va.Bind(gl); 65 | 66 | var primitiveType = gl.TRIANGLES; 67 | var indexcount = ib.getCount(); 68 | var indexoffset = 0; 69 | gl.drawElements(primitiveType, indexcount, gl.UNSIGNED_SHORT, indexoffset); 70 | } 71 | } 72 | 73 | function main() { 74 | // Get A WebGL context 75 | var canvas = document.querySelector("#c"); 76 | var gl = canvas.getContext("webgl2"); 77 | if (!gl) { 78 | return; 79 | } 80 | 81 | //--사각형 데이터 82 | var rectangleVertices = [ 83 | //x y r g b a 84 | -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, //0번 vertex 85 | 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, //1번 vertex 86 | 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, //2번 vertex 87 | -0.5, 0.5, 0.8, 0.2, 0.3, 1.0, //3번 vertex 88 | ]; 89 | 90 | var rectangleIndices = [ 91 | 0, 1, 2, //0,1,2번 vertex로 이루어진 삼각형 92 | 2, 3, 0, //2,3,0번 vertex로 이루어진 삼각형 93 | ]; 94 | 95 | let rectVA = new VertexArray(gl); 96 | let rectangleVB = new VertexBuffer(gl,rectangleVertices); 97 | rectVA.AddBuffer(gl, rectangleVB, [2, 4], [false, false]); 98 | let rectangleIB = new IndexBuffer(gl, rectangleIndices, 6); 99 | 100 | let shader = new Shader(gl,simpleVertexShader,simpleFragmentShader); 101 | 102 | rectVA.Unbind(gl); // <-- 지난번 커밋에서 바꾸는건 깜박했습니다! 103 | rectangleVB.Unbind(gl); 104 | rectangleIB.Unbind(gl); 105 | 106 | let renderer = new Renderer(); 107 | gl.clearColor(1.0, 1.0, 1.0, 1.0); 108 | 109 | drawScene(); 110 | 111 | //화면을 새로 그리기 위한 명령어들을 모아 함수로 구현하였음 112 | function drawScene() 113 | { 114 | renderer.Clear(gl); 115 | 116 | shader.Bind(gl); //Uniform 설정에 필요하기 때문에 바인딩 117 | shader.SetUniform4f(gl,"u_color", 0.0, 0.0, 1.0, 1.0); 118 | 119 | renderer.Draw(gl, rectVA, rectangleIB, shader); 120 | 121 | rectVA.Unbind(gl); 122 | shader.Unbind(gl); 123 | } 124 | } 125 | 126 | main(); -------------------------------------------------------------------------------- /lessons/_shaders/dirShadowPCFFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `#version 300 es 3 | precision highp float; 4 | 5 | struct Light 6 | { 7 | vec3 lightColor; 8 | float ambientIntensity; 9 | float diffuseIntensity; 10 | }; 11 | 12 | struct DirectionalLight 13 | { 14 | Light base; 15 | vec3 direction; 16 | }; 17 | 18 | struct Material 19 | { 20 | float specularIntensity; 21 | float shininess; //sh 22 | }; 23 | 24 | layout(location=0) out vec4 outColor; 25 | 26 | uniform sampler2D u_mainTexture; 27 | uniform DirectionalLight u_directionalLight; 28 | uniform vec3 u_eyePosition; 29 | uniform Material u_material; 30 | uniform sampler2D u_depthMap; //depth map 31 | 32 | in vec2 v_texcoord; 33 | in vec3 v_normal; 34 | in vec3 v_worldPosition; 35 | in vec4 v_lightSpacePos; //light 공간 좌표 36 | 37 | 38 | float CalculateShadowFactor(DirectionalLight light) 39 | { 40 | //varying은 perspective division을 자동으로 해주지 않기 때문에 직접 해주어야 함 41 | vec3 projCoords = v_lightSpacePos.xyz / v_lightSpacePos.w; 42 | 43 | //위에서 계산한 projCoord는 NDC상 좌표. 이를 [0,1]로 변환 (xy는 texture 좌표, z는 depth로 사용) 44 | projCoords = (projCoords * 0.5) + 0.5; 45 | 46 | //d는 light로부터 현재 그리려는 픽셀까지의 깊이값 47 | float d = projCoords.z; 48 | 49 | //Shadow acne를 해결하기 위해 bias를 추가해 보겠습니다. 50 | //강의 자료에서보다 발전한 알고리즘을 사용합니다. 51 | vec3 normal = normalize(v_normal); 52 | vec3 lightDir = normalize(-light.direction); 53 | float bias = max(0.05*(1.0 - dot(normal,lightDir)), 0.0005); 54 | 55 | //Percentage Close Filtering(PCF) 56 | //이제 shadowFactor 0 또는 1이 아닌, 중간값을 가질 수 있습니다. 57 | //주변 9개의 그림자 영역 여부를 계산하여 평균냅니다. 58 | float shadowFactor = 0.0; 59 | float texelSizeX = 1.0 / float(textureSize(u_depthMap,0).x); 60 | float texelSizeY = 1.0 / float(textureSize(u_depthMap,0).y); 61 | vec2 texelSize = vec2(texelSizeX, texelSizeY); 62 | for(int x=-1;x<=1;x++) 63 | { 64 | for(int y=-1;y<=1;y++) 65 | { 66 | float z = texture(u_depthMap, projCoords.xy + vec2(x,y) * texelSize).r; 67 | shadowFactor += d - bias > z ? 1.0 : 0.0; 68 | } 69 | } 70 | shadowFactor /= 9.0; 71 | 72 | if(d > 1.0) 73 | { 74 | shadowFactor = 0.0; 75 | } 76 | 77 | if(projCoords.x > 1.0 || projCoords.y > 1.0 || projCoords.x < 0.0 || projCoords.y < 0.0) 78 | { 79 | shadowFactor = 0.0; 80 | } 81 | 82 | return shadowFactor; 83 | } 84 | 85 | vec3 CalculateLight(Light light, vec3 direction, float shadowFactor) //shadow Factor가 추가됨 86 | { 87 | vec3 normal = normalize(v_normal); 88 | 89 | //ambient 90 | vec3 lightAmbient = light.lightColor * light.ambientIntensity; 91 | 92 | //diffuse 93 | vec3 lightDir = normalize(-direction); 94 | float diffuseFactor = max(dot(normal, lightDir), 0.0); 95 | vec3 lightDiffuse = light.lightColor * light.diffuseIntensity * diffuseFactor; 96 | 97 | //specular 98 | vec3 vVec = normalize(u_eyePosition - v_worldPosition); 99 | vec3 rVec = 2.0 * normal * dot(normal, lightDir) - lightDir; 100 | vec3 lightSpecular = pow(max(dot(rVec,vVec),0.0),u_material.shininess) * light.lightColor * u_material.specularIntensity; 101 | 102 | //ambient는 그림자에 영향을 받지 않지만 diffuse와 specular는 그림자 여부에 영향을 받음 103 | return (lightAmbient + (1.0-shadowFactor) * (lightDiffuse + lightSpecular)); 104 | 105 | } 106 | 107 | vec3 CalculateDirectionalLight() 108 | { 109 | float shadowFactor = CalculateShadowFactor(u_directionalLight); 110 | return CalculateLight(u_directionalLight.base, u_directionalLight.direction, shadowFactor); 111 | 112 | } 113 | 114 | void main() { 115 | vec3 lightColor = CalculateDirectionalLight(); 116 | outColor = texture(u_mainTexture, v_texcoord) * vec4(lightColor,1.0); 117 | } 118 | `; -------------------------------------------------------------------------------- /resources/colResizable-1.3.min.js: -------------------------------------------------------------------------------- 1 | //colResizable - by Alvaro Prieto Lauroba - MIT & GPL 2 | (function(a){function h(b){var c=a(this).data(q),d=m[c.t],e=d.g[c.i];e.ox=b.pageX;e.l=e[I]()[H];i[D](E+q,f)[D](F+q,g);P[z](x+"*{cursor:"+d.opt.dragCursor+K+J);e[B](d.opt.draggingClass);l=e;if(d.c[c.i].l)for(b=0;b",y="push",z="append",A="removeClass",B="addClass",C="removeAttr",D="bind",E="mousemove.",F="mouseup.",G="currentTarget",H="left",I="position",J="}",K="!important;",L=":0px"+K,M="resize",N="table",O,P=a("head")[z](x+".CRZ{table-layout:fixed;}.CRZ td,.CRZ th{padding-"+H+L+"padding-right"+L+"overflow:hidden}.CRC{height:0px;"+I+":relative;}.CRG{margin-left:-5px;"+I+":absolute;z-index:5;}.CRG .CRZ{"+I+":absolute;background-color:red;filter:alpha(opacity=1);opacity:0;width:10px;height:100%;top:0px}.CRL{"+I+":absolute;width:1px}.CRD{ border-left:1px dotted black"+J);try{O=sessionStorage}catch(Q){}a(window)[D](M+"."+q,function(){for(a in m){var a=m[a],b,c=0;a[A](q);if(a.w!=a[u]()){a.w=a[u]();for(b=0;b'),e.opt=d,e.g=[],e.c=[],e.w=e[u](),e.gc=e.prev(),d.marginLeft&&e.gc.css("marginLeft",d.marginLeft),d.marginRight&&e.gc.css("marginRight",d.marginRight),e.cs=r(t?this.cellSpacing||this.currentStyle.borderSpacing:e.css("border-spacing"))||2,e.b=r(t?this.border||this.currentStyle.borderLeftWidth:e.css("border-"+H+"-"+u))||1,m[f]=e,b(e)}})}})})(jQuery) -------------------------------------------------------------------------------- /lessons/11_input_handling_pt2_camera_control/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //Classes 4 | import VertexBuffer from '../_classes/VertexBuffer.js'; 5 | import IndexBuffer from '../_classes/IndexBuffer.js'; 6 | import VertexArray from '../_classes/VertexArray.js'; 7 | import Shader from '../_classes/Shader.js'; 8 | import Renderer from '../_classes/Renderer.js'; 9 | import Camera from '../_classes/Camera.js'; 10 | 11 | //Shaders 12 | import basicViewProjectionFragmentShader from '../_shaders/basicViewProjectionFragment.js'; 13 | import basicViewProjectionVertexShader from '../_shaders/basicViewProjectionVertex.js'; 14 | 15 | const {mat2, mat3, mat4, vec2, vec3, vec4} = glMatrix; 16 | 17 | function main() { 18 | // Get A WebGL context 19 | let canvas = document.querySelector("#c"); 20 | let gl = canvas.getContext("webgl2"); 21 | if (!gl) { 22 | return; 23 | } 24 | 25 | //--사각형 데이터 26 | let rectangleVertices = [ 27 | //x y r g b a 28 | -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, //0번 vertex 29 | 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, //1번 vertex 30 | 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, //2번 vertex 31 | -0.5, 0.5, 0.8, 0.2, 0.3, 1.0, //3번 vertex 32 | ]; 33 | 34 | let rectangleIndices = [ 35 | 0, 1, 2, //0,1,2번 vertex로 이루어진 삼각형 36 | 2, 3, 0, //2,3,0번 vertex로 이루어진 삼각형 37 | ]; 38 | 39 | let rectVA = new VertexArray(gl); 40 | let rectangleVB = new VertexBuffer(gl,rectangleVertices); 41 | rectVA.AddBuffer(gl, rectangleVB, [2, 4], [false, false]); 42 | let rectangleIB = new IndexBuffer(gl, rectangleIndices, 6); 43 | 44 | //이제는 키보드/마우스 입력에 따라 view matrix를 반환하는 Camera를 생성합니다. 45 | //WASD로 카메라의 eye 위치를 바꾸고, 마우스로 yaw-pitch 각 변경을 통해 46 | //forward 벡터 방향을 변경한 뒤, at 위치를 계산하는데 사용합니다. 47 | let eye = [0.0, 0.0, 5.0]; 48 | let up = [0.0, 1.0, 0.0]; 49 | let yaw = -90.0; 50 | let pitch = 0.0; 51 | let movespeed = 0.05; 52 | let turnspeed = 0.5; 53 | let mainCamera = new Camera(eye,up,yaw,pitch,movespeed,turnspeed); 54 | 55 | //orthographc 대신 perspective projection matrix 사용 56 | let fovRadian = 90.0 * Math.PI / 180; 57 | let aspect = gl.canvas.clientWidth/gl.canvas.clientHeight; 58 | let proj = mat4.create(); 59 | mat4.perspective(proj, fovRadian, aspect, 0.1, 100.0); 60 | 61 | let shader = new Shader(gl,basicViewProjectionVertexShader,basicViewProjectionFragmentShader); 62 | 63 | rectVA.Unbind(gl); 64 | rectangleVB.Unbind(gl); 65 | rectangleIB.Unbind(gl); 66 | shader.Unbind(gl); 67 | 68 | let renderer = new Renderer(); 69 | gl.clearColor(1.0, 1.0, 1.0, 1.0); 70 | 71 | drawScene(); 72 | 73 | function drawScene() 74 | { 75 | webglUtils.resizeCanvasToDisplaySize(gl.canvas); 76 | gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); 77 | 78 | renderer.Clear(gl); 79 | 80 | shader.Bind(gl); //Uniform 설정에 필요하기 때문에 바인딩 81 | 82 | shader.SetUniform4f(gl,"u_color", 1.0, 0.0, 0.0, 1.0); 83 | 84 | let view = mainCamera.CalculateViewMatrix(); 85 | shader.SetUniformMat4f(gl, "u_view", view); 86 | shader.SetUniformMat4f(gl, "u_projection", proj); 87 | 88 | renderer.Draw(gl, rectVA, rectangleIB, shader); 89 | 90 | rectVA.Unbind(gl); 91 | shader.Unbind(gl); 92 | } 93 | 94 | window.addEventListener('keydown', KeyboardEventHandler); 95 | window.addEventListener('mousemove', MouseMoveEventHandler); 96 | 97 | //키보드 이벤트 핸들러 함수 98 | function KeyboardEventHandler(e) 99 | { 100 | mainCamera.KeyControl(e); // 카메라 클래스의 KeyControl로 이벤트 정보 전달 101 | drawScene(); // 값이 바뀔때마다 drawScene()으로 화면을 다시 그려야 한다는 것을 잊지 마세요. 102 | } 103 | 104 | //마우스 이벤트 핸들러 함수 105 | function MouseMoveEventHandler(e) 106 | { 107 | mainCamera.MouseControl(e); // 카메라 클래스의 MouseControl로 이벤트 정보 전달 108 | drawScene(); 109 | } 110 | } 111 | 112 | main(); -------------------------------------------------------------------------------- /resources/webgl-obj-loader/mesh.d.ts: -------------------------------------------------------------------------------- 1 | import { Layout } from "./layout"; 2 | import { Material, MaterialLibrary } from "./material"; 3 | export interface MeshOptions { 4 | enableWTextureCoord?: boolean; 5 | calcTangentsAndBitangents?: boolean; 6 | materials?: { 7 | [key: string]: Material; 8 | }; 9 | } 10 | export interface MaterialNameToIndex { 11 | [k: string]: number; 12 | } 13 | export interface IndexToMaterial { 14 | [k: number]: Material; 15 | } 16 | export interface ArrayBufferWithItemSize extends ArrayBuffer { 17 | numItems?: number; 18 | } 19 | export interface Uint16ArrayWithItemSize extends Uint16Array { 20 | numItems?: number; 21 | } 22 | /** 23 | * The main Mesh class. The constructor will parse through the OBJ file data 24 | * and collect the vertex, vertex normal, texture, and face information. This 25 | * information can then be used later on when creating your VBOs. See 26 | * OBJ.initMeshBuffers for an example of how to use the newly created Mesh 27 | */ 28 | export default class Mesh { 29 | vertices: number[]; 30 | vertexNormals: number[]; 31 | textures: number[]; 32 | indices: number[]; 33 | name: string; 34 | vertexMaterialIndices: number[]; 35 | indicesPerMaterial: number[][]; 36 | materialNames: string[]; 37 | materialIndices: MaterialNameToIndex; 38 | materialsByIndex: IndexToMaterial; 39 | tangents: number[]; 40 | bitangents: number[]; 41 | textureStride: number; 42 | /** 43 | * Create a Mesh 44 | * @param {String} objectData - a string representation of an OBJ file with 45 | * newlines preserved. 46 | * @param {Object} options - a JS object containing valid options. See class 47 | * documentation for options. 48 | * @param {bool} options.enableWTextureCoord - Texture coordinates can have 49 | * an optional "w" coordinate after the u and v coordinates. This extra 50 | * value can be used in order to perform fancy transformations on the 51 | * textures themselves. Default is to truncate to only the u an v 52 | * coordinates. Passing true will provide a default value of 0 in the 53 | * event that any or all texture coordinates don't provide a w value. 54 | * Always use the textureStride attribute in order to determine the 55 | * stride length of the texture coordinates when rendering the element 56 | * array. 57 | * @param {bool} options.calcTangentsAndBitangents - Calculate the tangents 58 | * and bitangents when loading of the OBJ is completed. This adds two new 59 | * attributes to the Mesh instance: `tangents` and `bitangents`. 60 | */ 61 | constructor(objectData: string, options?: MeshOptions); 62 | /** 63 | * Calculates the tangents and bitangents of the mesh that forms an orthogonal basis together with the 64 | * normal in the direction of the texture coordinates. These are useful for setting up the TBN matrix 65 | * when distorting the normals through normal maps. 66 | * Method derived from: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/ 67 | * 68 | * This method requires the normals and texture coordinates to be parsed and set up correctly. 69 | * Adds the tangents and bitangents as members of the class instance. 70 | */ 71 | calculateTangentsAndBitangents(): void; 72 | /** 73 | * @param layout - A {@link Layout} object that describes the 74 | * desired memory layout of the generated buffer 75 | * @return The packed array in the ... TODO 76 | */ 77 | makeBufferData(layout: Layout): ArrayBufferWithItemSize; 78 | makeIndexBufferData(): Uint16ArrayWithItemSize; 79 | makeIndexBufferDataForMaterials(...materialIndices: Array): Uint16ArrayWithItemSize; 80 | addMaterialLibrary(mtl: MaterialLibrary): void; 81 | } 82 | -------------------------------------------------------------------------------- /lessons/05_shader_uniform_interactive/contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WebGL 5.Shader Uniform - Interactive 6 | 7 | 8 | 9 |
WebGL 5.Shader Uniform - Interactive
10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 | 20 | 120 | -------------------------------------------------------------------------------- /lessons/00_Setup/README.md: -------------------------------------------------------------------------------- 1 | # 0. SETUP 2 | 3 | 첫 번째 내용으로, 웹 서버를 설치하고 문제가 없는지 부터 살펴봅니다. 4 | 5 | ## How to 6 | 7 | ### Install and Run Web Server 8 | 1. 우선 이 Repository(또는 현재 커밋)을 Clone하여 여러분의 PC에 사본을 만듭니다. 9 | * `D:/Lecture/CG/`에 Clone했다고 가정하겠습니다. 즉 `D:/Lecture/CG/resources/` 폴더와 `D:/Lecture/CG/lessons/` 폴더가 있는 상태입니다. 10 | 2. [Serves](https://greggman.github.io/servez/)를 다운로드하고 설치합니다. 11 | 3. 설치된 Serves를 실행하고 "Folder to Serve" 경로를 Clone한 폴더로 지정합니다. 12 | * 위 예시에 따르면 `D:/Lecture/CG/` 폴더를 선택합니다. 13 | 4. Start를 누릅니다. 14 | 15 | ### Connect and Check 16 | 5. `lessons` 폴더 하위에 `practice` 폴더를 만들고 그 안에 `contents.html` 파일을 만듭니다. (`D:/Lecture/CG/lessons/practice/contents.html`) 17 | 6. `contents.html` 파일을 편집기로 열어서 아래 코드를 복사해서 붙여넣어 줍니다. 18 | 19 | ```html 20 | 21 | 22 | 23 | 24 | WebGL 0.Setup 25 | 26 | 27 | 28 |
WebGL Setup Result
29 | 30 | 31 | 32 | 33 | 89 | ``` 90 | 91 | 7. 웹 브라우저(Chrome 또는 FireFox)를 실행하고 `http://localhost:8080/lessons/practice/contents.html` 주소로 접속합니다. 92 | 8. 아래와 같이 WebGL Setup Result 글자와 파란색 삼각형이 나오는지 확인합니다. 93 | 94 | ![](../imgs/0_setup_result.JPG) 95 | 96 | ### Modify 97 | 7. 이제 `D:/Lecture/CG/lessons/practice/contents.html` 파일을 다시 편집기로 열어서 아래 `
`태그 내의 문자열을 다른 문자로 바꿔 보세요. 98 | 99 | ```html 100 |
WebGL Setup Result
101 | ``` 102 | 103 | 8. 페이지를 새로고침해서 바뀐 문자열이 적용되어 표시되는지 확인해 보세요. 104 | 105 | 9. F12를 눌러 아래와 같은 개발자 도구를 띄우고 "Source"를 누른 뒤 왼쪽의 contents.html을 더블클릭해서 코드가 표시되는 것을 확인해 보세요. 106 | * 표시되지 않으면 F5를 눌러서 화면을 새로고침하여 확인해 보세요. 107 | 108 | ![](../imgs/0_setup_devtool.JPG) 109 | 110 | 위 과정들이 모두 제대로 동작한다면 이제 WebGL 코드를 작성할 준비가 된 것입니다! 111 | 112 | ## FAQ 113 | 114 | - 화면에 아무것도 나오지 않는다면 우선 본인 브라우저가 WebGL을 지원하는지 [링크](https://get.webgl.org/webgl2/)에 접속해서 확인해 보세요. 지원하지 않는다면 다른 웹 브라우저를 설치해서 사용하셔야 합니다. 115 | - `http://localhost:8080`이 3번에서 설정한 경로를 가리킵니다. 따라서 `http://localhost:8080/lessons/practice/contents.html`이라 하면 `D:/Lecture/CG/lessons/practice/contents.html`파일을 가리키게 됩니다. 제대로 설정되었는지 확인해 보세요. 116 | 117 | ## Useful Links 118 | 119 | - [WebGL2 설정 및 설치(WebGL2 Fundamentals)](https://webgl2fundamentals.org/webgl/lessons/ko/webgl-setup-and-installation.html) 120 | 121 | --- 122 | 123 | [다음 강의](../01_vertex_buffer/) 124 | 125 | [목록으로](../) 126 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /lessons/11_input_handling_pt1_color_change/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //Classes 4 | import VertexBuffer from '../_classes/VertexBuffer.js'; 5 | import IndexBuffer from '../_classes/IndexBuffer.js'; 6 | import VertexArray from '../_classes/VertexArray.js'; 7 | import Shader from '../_classes/Shader.js'; 8 | import Renderer from '../_classes/Renderer.js'; 9 | 10 | //Shaders 11 | import basicProjectionFragmentShader from '../_shaders/basicProjectionFragment.js'; 12 | import basicProjectionVertexShader from '../_shaders/basicProjectionVertex.js'; 13 | 14 | const {mat2, mat3, mat4, vec2, vec3, vec4} = glMatrix; 15 | 16 | function main() { 17 | // Get A WebGL context 18 | let canvas = document.querySelector("#c"); 19 | let gl = canvas.getContext("webgl2"); 20 | if (!gl) { 21 | return; 22 | } 23 | 24 | //--사각형 데이터 25 | let rectangleVertices = [ 26 | //x y r g b a 27 | -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, //0번 vertex 28 | 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, //1번 vertex 29 | 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, //2번 vertex 30 | -0.5, 0.5, 0.8, 0.2, 0.3, 1.0, //3번 vertex 31 | ]; 32 | 33 | let rectangleIndices = [ 34 | 0, 1, 2, //0,1,2번 vertex로 이루어진 삼각형 35 | 2, 3, 0, //2,3,0번 vertex로 이루어진 삼각형 36 | ]; 37 | 38 | let rectVA = new VertexArray(gl); 39 | let rectangleVB = new VertexBuffer(gl,rectangleVertices); 40 | rectVA.AddBuffer(gl, rectangleVB, [2, 4], [false, false]); 41 | let rectangleIB = new IndexBuffer(gl, rectangleIndices, 6); 42 | 43 | //glMatrix의 함수를 사용해 orthographic projection matrix를 생성합니다. 44 | let proj = mat4.create(); 45 | mat4.ortho(proj,-2.0, 2.0, -1.5, 1.5, -1.0, 1.0); 46 | 47 | let shader = new Shader(gl,basicProjectionVertexShader,basicProjectionFragmentShader); 48 | 49 | rectVA.Unbind(gl); 50 | rectangleVB.Unbind(gl); 51 | rectangleIB.Unbind(gl); 52 | 53 | let renderer = new Renderer(); 54 | gl.clearColor(1.0, 1.0, 1.0, 1.0); 55 | 56 | //--Variables--// 57 | let red = 0.0; 58 | let green = 0.0; 59 | let mouseX = 0.0; 60 | let mouseY = 0.0; 61 | 62 | drawScene(); 63 | 64 | function drawScene() 65 | { 66 | webglUtils.resizeCanvasToDisplaySize(gl.canvas); 67 | gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); 68 | 69 | renderer.Clear(gl); 70 | 71 | shader.Bind(gl); //Uniform 설정에 필요하기 때문에 바인딩 72 | 73 | shader.SetUniform4f(gl,"u_color", red, green, 0.0, 1.0); 74 | shader.SetUniformMat4f(gl, "u_projection", proj); //proj 행렬을 shader로 넘깁니다. SetUniformMat4f 함수가 shader 클래스에 추가되어야 합니다. 75 | 76 | renderer.Draw(gl, rectVA, rectangleIB, shader); 77 | 78 | rectVA.Unbind(gl); 79 | shader.Unbind(gl); 80 | } 81 | 82 | // window.addEventListener()를 통해 어떤 윈도우 내에서 어떤 이벤트가 발생할 때 호출되는 함수를 구현합니다. 83 | // 'keydown'은 키보드가 눌렸을때 두번째 인자의 함수를 호출합니다. 84 | // Javascript KeyCode list 확인 85 | // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode 86 | window.addEventListener('keydown', KeyboardEventHandler); 87 | 88 | // 'mousemove'는 윈도우 내에서 마우스가 움직이면 두번째 인자의 함수를 호출합니다. 89 | window.addEventListener('mousemove', MouseMoveEventHandler); 90 | 91 | //키보드 이벤트 핸들러 함수 92 | function KeyboardEventHandler(e) 93 | { 94 | if(e.code == "KeyA") // 'A' key down 95 | { 96 | //console.log("A key down"); 97 | red -= 0.1; 98 | } 99 | if(e.code == "KeyD") // 'D' key down 100 | { 101 | //console.log("D key down"); 102 | red += 0.1; 103 | } 104 | if(e.code == "KeyW") // 'W' key down 105 | { 106 | //console.log("W key down"); 107 | green += 0.1; 108 | } 109 | if(e.code == "KeyS") // 'S' key down 110 | { 111 | //console.log("S key down"); 112 | green -= 0.1; 113 | } 114 | drawScene(); // 값이 바뀔때마다 drawScene()으로 화면을 다시 그려야 한다는 것을 잊지 마세요. 115 | } 116 | 117 | //마우스 이벤트 핸들러 함수 118 | function MouseMoveEventHandler(e) 119 | { 120 | mouseX = e.clientX; 121 | mouseY = e.clientY; 122 | console.log("Mouse position : (" + mouseX + "," + mouseY + ")"); 123 | } 124 | } 125 | 126 | main(); -------------------------------------------------------------------------------- /resources/tdl/misc.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | /** 34 | * @fileoverview This file contains misc functions that don't fit elsewhere. 35 | */ 36 | 37 | tdl.provide('tdl.misc'); 38 | 39 | tdl.require('tdl.log'); 40 | 41 | /** 42 | * A module for misc. 43 | * @namespace 44 | */ 45 | tdl.misc = tdl.misc || {}; 46 | 47 | tdl.misc.applyUrlSettings = function(obj, opt_argumentName) { 48 | var argumentName = opt_argumentName || 'settings'; 49 | try { 50 | var s = window.location.href; 51 | var q = s.indexOf("?"); 52 | var e = s.indexOf("#"); 53 | if (e < 0) { 54 | e = s.length; 55 | } 56 | var query = s.substring(q + 1, e); 57 | //tdl.log("query:", query); 58 | var pairs = query.split("&"); 59 | //tdl.log("pairs:", pairs.length); 60 | for (var ii = 0; ii < pairs.length; ++ii) { 61 | var keyValue = pairs[ii].split("="); 62 | var key = keyValue[0]; 63 | var value = decodeURIComponent(keyValue[1]); 64 | //tdl.log(ii, ":", key, "=", value); 65 | switch (key) { 66 | case argumentName: 67 | //tdl.log(value); 68 | var settings = eval("(" + value + ")"); 69 | //tdl.log("settings:", settings); 70 | tdl.misc.copyProperties(settings, obj); 71 | break; 72 | } 73 | } 74 | } catch (e) { 75 | tdl.error(e); 76 | tdl.error("settings:", settings); 77 | return; 78 | } 79 | }; 80 | 81 | /** 82 | * Copies properties from obj to dst recursively. 83 | * @private 84 | * @param {!Object} obj Object with new settings. 85 | * @param {!Object} dst Object to receive new settings. 86 | */ 87 | tdl.misc.copyProperties = function(obj, dst) { 88 | for (var name in obj) { 89 | var value = obj[name]; 90 | if (value instanceof Array) { 91 | //tdl.log("apply->: ", name, "[]"); 92 | var newDst = dst[name]; 93 | if (!newDst) { 94 | newDst = []; 95 | dst[name] = newDst; 96 | } 97 | tdl.misc.copyProperties(value, newDst); 98 | } else if (typeof value == 'object') { 99 | //tdl.log("apply->: ", name); 100 | var newDst = dst[name]; 101 | if (!newDst) { 102 | newDst = {}; 103 | dst[name] = newDst; 104 | } 105 | tdl.misc.copyProperties(value, newDst); 106 | } else { 107 | //tdl.log("apply: ", name, "=", value); 108 | dst[name] = value; 109 | } 110 | } 111 | }; 112 | 113 | 114 | -------------------------------------------------------------------------------- /lessons/04_shader_uniform/README.md: -------------------------------------------------------------------------------- 1 | # 4. Shader Uniform 2 | 3 | 이번에는 사각형의 색상을 바꿔 보겠습니다. 이전에 퀴즈로 내 드렸던 내용을 직접 해보신 분들은 아시겠지만, 프래그먼트 셰이더의 outColor에 대입한 색상이 바뀌면 화면에 표시되는 삼각형의 색상이 바뀌는 것을 볼 수 있었습니다. 4 | 5 | 그러면 꼭 이렇게 출력되는 색상을 셰이더에 하드코딩해서 넣는 방법만 존재할까요? 당연히 아닙니다! 6 | 7 | JS 쪽으로부터 셰이더 프로그램으로 원하는 값을 그때그때 전달해 줄 수 있는 방법이 있는데, 바로 Uniform 타입의 변수를 사용하는 것입니다. 8 | 9 | 두 번째 강의였던 Shader Attribute에서 말씀드렸는데요, (GPU에 있는)셰이더 프로그램에 (RAM으로부터) 데이터를 전달하는 방법은 두 가지가 있습니다. 10 | 11 | 1. Attribute: 정점의 위치 등 각 정점별로 다른 값을 갖는(per-vertex) 데이터 전달 12 | 2. Uniform: 변환 행렬 등 물체별로 다른 값을 갖는(per-object) 데이터 전달 13 | 14 | > Texture라는, 물체의 색상이나 기타 속성들을 정의하는 이미지 형태의 데이터 또한 uniform 변수로써 접근하게 됩니다. 동작 방식은 여기서 보는 일반적인 uniform과는 약간 다른데 이 부분은 나중에 Texture 관련 챕터에서 다시 설명하도록 하겠습니다. 15 | 16 | 이번 자료에서는 Uniform에 대해 코드를 작성해 볼 것입니다. 우선 위에서 물체라는 것은 삼각형의 집합을 의미한다고 생각하시면 됩니다. `positions`는 각 정점의 위치값을 가지고 있습니다. 따라서 모든 정점이 다른 값을 가지므로, 이는 attribute로 전달했습니다. 17 | 18 | 한편, 내가 사각형을 빨간색으로 칠하고 싶다면 물체(=사각형, 삼각형의 집합) 전체에 적용할 빨간색 데이터를 전달해 주어야 합니다. 이렇게 정점별로 다르지 않고 물체에 공통적으로 적용할 데이터를 우리는 Uniform이라는 변수를 사용해서 전달해 줄 수 있습니다. 19 | 20 | 잘 설명이 되었는지 모르겠는데요, 예제를 보시면 명확해 질 겁니다. 21 | 22 | ## How to 23 | 24 | 이번 코드를 시작하기에 앞서 이전에 설명을 위해 달아두었던 주석들을 정리하였으니 참고 하시기 바랍니다. 25 | 26 | 이전 코드에서 변화된 내용들을 보자면 아래와 같습니다. 27 | 28 | --- 29 | 1. 셰이더에 Uniform 변수 정의 30 | 31 | ```glsl 32 | var fragmentShaderSource = `#version 300 es 33 | precision highp float; 34 | layout(location=0) out vec4 outColor; 35 | 36 | uniform vec4 u_color; //CPU로부터 데이터를 받는 또다른 방법인 uniform 변수 37 | 38 | void main() { 39 | outColor = u_color; //uniform 변수에 저장된 색상으로 출력 40 | } 41 | `; 42 | ``` 43 | 44 | 프래그먼트 셰이더에 `u_color`라는 `vec4`타입의 변수를 선언하고, 그 앞에 `uniform`이라는 키워드를 붙여 두었습니다. 이렇게 하면 셰이더 프로그램에 uniform을 생성한 겁니다. 45 | 46 | 그리고 `main()`함수에서는 하드코딩한 색상값을 넣는 대신에, `u_color`에 저장된 값을 출력하도록 해 두었습니다. 이제 `u_color`에 저장된 값으로 사각형이 표시될 것이라는 것을 예상할 수 있습니다. 47 | 48 | 2. Uniform에 데이터 전달 49 | 50 | ```js 51 | var location = gl.getUniformLocation(program, "u_color"); //u_color 변수 위치를 참조 52 | gl.uniform4f(location, 0.8, 0.3, 0.8, 1.0); //해당 위치에 0.8, 0.3, 0.8, 1.0 데이터를 전달 53 | ``` 54 | 55 | 이렇게 두 줄로 셰이더의 `u_color`변수에 RAM으로부터 데이터가 전달됩니다. 참 쉽죠? 56 | 57 | 의미를 좀 뜯어서 보겠습니다. 먼저 `getUniformLocation()`함수에 첫 번째 인자로는 우리가 컴파일하여 준비해둔 셰이더 프로그램의 ID를 전달하고 있습니다. 셰이더 프로그램도 여러개가 있을 수 있기 때문에 어느 셰이더 안에 있는 uniform에 데이터를 전달할 것인지를 정확하려 얻어오려면 당연히 필요할겁니다. 두 번째 인자로는 그 셰이더 프로그램 내의 uniform 변수의 이름을 문자열로 전달합니다. 위에서 우리가 선언한 uniform변수 이름인 `u_color`를 전달하면 됩니다. 그 반환값으로 `u_color`의 위치가 반환됩니다. 앞으로 uniform 변수의 위치는 location이라고 영문 그대로 적겠습니다. 58 | 59 | 이제 남은 것은 그 location에 데이터를 집어넣는 것입니다. `u_color`가 `vec4` 타입이기 때문에 `gl.uniform4f()`라는 API를 사용하고 있습니다. [링크](https://webgl2fundamentals.org/webgl/lessons/ko/webgl-shaders-and-glsl.html#uniforms)의 글 중간에 보시면 셰이더 내의 데이터 타입별로 다른 함수를 사용해 데이터를 전달해야 한다는 것을 아실 수 있습니다. 60 | 61 | 예를들어 우리가 `uniform float a;`를 셰이더에 정의해 두었다면 여기에는 `gl.uniform1f()` API를 사용해 데이터를 전달해야 합니다. 이후 강의에서는 uniform을 전체적으로 관리하고, 데이터를 전달하는 인터페이스를 갖는 클래스를 만들 것입니다. 62 | 63 | 어쨋든, `gl.uniform4f()`의 첫번째 인자로 우리가 데이터를 넣은 location을 알려주고, 2~5번째 인자에 `vec4`에 필요한 float 4개를 개별적으로 전달해 줍니다. 이 명령문이 실행되면, `u_color`에는 (0.8, 0.3, 0.8, 1.0) 네 개의 값이 저장됩니다. (`vec4`는 x,y,z,w 네 멤버를 갖는 구조체라고 말씀드린 바 있습니다.) 64 | 65 | --- 66 | 67 | `http://localhost:8080/lessons/practice/contents.html`(또는 `http://localhost:8080/lessons/04_shader_uniform/contents.html`)에 접속해 보시면 화면에 보라색 사각형이 나오는 것을 보실 수 있습니다. 68 | 69 | "그냥 이쪽(셰이더)에 작성하던 코드를 저쪽(CPU 사이드)으로 옮겼구나"라고 생각하실 수도 있지만 사실 Uniform이라는 것은 향후 우리가 작성해 볼 코드에서 굉장히 중요한 역할을 수행합니다. 특히 3차원 표현을 위한 Model/View/Projection 행렬을 전달하는데 사용되기 때문에 더 그러한데요, 지금 코드만 가지고는 감이 잘 안오실테니 얼른 uniform을 좀더 재미있게 활용하는 코드로 넘어가 보도록 합시다. 70 | 71 | ## Quiz 72 | 73 | 1. 정점 셰이더에도 `uniform vec4 offset;`을 선언하고, 셰이더 코드의 `main()`함수 내부를 아래와 같이 바꿔 보세요. 74 | 75 | ``` 76 | gl_Position = a_position + offset; 77 | ``` 78 | 그리고 나서 JS쪽에서 offset uniform으로 값을 전달해서 결과가 어떻게 달라지는지 살펴보세요. 79 | 80 | 2. Uniform에 값을 전달하기 위해서는 셰이더 프로그램이 활성화(바인딩)되어 있어야 합니다. 코드의 주석을 따라서 프로그램을 비활성화(언바인딩)하고 제대로 동작하는지 그렇지 않은지 확인해 보세요. 81 | 82 | ## Useful Links 83 | 84 | - [WebGL Shader와 GLSL](https://webgl2fundamentals.org/webgl/lessons/ko/webgl-shaders-and-glsl.html#uniforms) 85 | 86 | --- 87 | 88 | [다음 강의](../05_shader_uniform_interactive/) 89 | 90 | [목록으로](../) 91 | -------------------------------------------------------------------------------- /lessons/14_texture/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //Classes 4 | import Shader from '../_classes/Shader.js'; 5 | import Renderer from '../_classes/Renderer.js'; 6 | import Camera from '../_classes/Camera.js'; 7 | import Model from '../_classes/Model.js'; 8 | import Texture from '../_classes/Texture.js'; 9 | 10 | //Shaders 11 | import textureVertexShader from '../_shaders/textureVertex.js'; 12 | import textureFragmentShader from '../_shaders/textureFragment.js'; 13 | 14 | const {mat2, mat3, mat4, vec2, vec3, vec4} = glMatrix; 15 | 16 | async function main() { 17 | // Get A WebGL context 18 | let canvas = document.querySelector("#c"); 19 | let gl = canvas.getContext("webgl2"); 20 | if (!gl) { 21 | return; 22 | } 23 | 24 | //---Model Loading 25 | let cube = new Model(); 26 | cube.LoadModel(gl, '../../resources/models/cube/cube.obj') 27 | 28 | let teapot = new Model(); 29 | teapot.LoadModel(gl, '../../resources/models/teapot/teapot.obj') 30 | 31 | //--Texture loading 32 | let checkerTexture = new Texture(gl); 33 | checkerTexture.LoadTextureFromImage(gl,'../../resources/uv-grid.png'); 34 | 35 | let internetTexture = new Texture(gl); 36 | internetTexture.LoadTextureFromImage(gl, 'https://c1.staticflickr.com/9/8873/18598400202_3af67ef38f_q.jpg') 37 | 38 | //---Camera(view) Initialize 39 | let eye = [0.0, 0.0, 5.0]; 40 | let up = [0.0, 1.0, 0.0]; 41 | let yaw = -90.0; 42 | let pitch = 0.0; 43 | let movespeed = 0.05; 44 | let turnspeed = 0.5; 45 | let mainCamera = new Camera(eye,up,yaw,pitch,movespeed,turnspeed); 46 | 47 | //---Projection Initialize 48 | let fovRadian = 90.0 * Math.PI / 180; 49 | let aspect = gl.canvas.clientWidth/gl.canvas.clientHeight; 50 | let proj = mat4.create(); 51 | mat4.perspective(proj, fovRadian, aspect, 0.1, 100.0); 52 | 53 | //---Shader Initialize 54 | let shader = new Shader(gl,textureVertexShader,textureFragmentShader); 55 | shader.Bind(gl); 56 | shader.SetUniformMat4f(gl, "u_projection", proj); 57 | shader.Unbind(gl); 58 | 59 | //---Renderer Initialize 60 | let renderer = new Renderer(); 61 | gl.clearColor(1.0, 1.0, 1.0, 1.0); 62 | 63 | let rotationAngle = 0; 64 | 65 | requestAnimationFrame(drawScene); 66 | 67 | function drawScene() 68 | { 69 | //화면 크기 재조정 70 | webglUtils.resizeCanvasToDisplaySize(gl.canvas); 71 | gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); 72 | 73 | renderer.Clear(gl); 74 | 75 | shader.Bind(gl); //Uniform 설정에 필요하기 때문에 바인딩 76 | { 77 | //---카메라 설정(현재는 모든 모델에 대해 동일한 뷰행렬 사용) 78 | let view = mainCamera.CalculateViewMatrix(); 79 | shader.SetUniformMat4f(gl, "u_view", view); 80 | 81 | //---육면체 그리기 82 | rotationAngle += Math.PI * 1 / 180; 83 | 84 | let model = mat4.create(); 85 | mat4.fromXRotation(model, rotationAngle); 86 | shader.SetUniformMat4f(gl, "u_model", model); 87 | 88 | //텍스처를 바인딩하고, 셰이더의 sampler2D u_texture에 해당 텍스처를 사용합니다. 89 | //0번 텍스처 유닛에 텍스처를 바인딩하고, 셰이더에는 0번 유닛으로부터 텍스처 값을 얻어오게 합니다. 90 | internetTexture.Bind(gl,0); 91 | shader.SetUniform1i(gl, "u_mainTexture", 0); 92 | 93 | cube.RenderModel(gl, shader); 94 | 95 | //---주전자 그리기 96 | model = mat4.create(); 97 | mat4.translate(model, model, [3, 0, 0]); 98 | mat4.scale(model, model, [0.1, 0.1, 0.1]); 99 | shader.SetUniformMat4f(gl, "u_model", model); 100 | 101 | //주전자에는 checker texture를 사용해 보겠습니다. 102 | //이번에는 1번 텍스처 유닛에 바인딩하고 셰이더에는 1번 유닛을 사용하도록 알려줍니다. 103 | checkerTexture.Bind(gl,1); 104 | shader.SetUniform1i(gl, "u_mainTexture", 1); 105 | 106 | teapot.RenderModel(gl, shader); 107 | } 108 | 109 | shader.Unbind(gl); 110 | 111 | requestAnimationFrame(drawScene); 112 | } 113 | 114 | window.addEventListener('keydown', KeyboardEventHandler); 115 | window.addEventListener('mousemove', MouseMoveEventHandler); 116 | 117 | //키보드 이벤트 핸들러 함수 118 | function KeyboardEventHandler(e) 119 | { 120 | mainCamera.KeyControl(e); 121 | } 122 | 123 | //마우스 이벤트 핸들러 함수 124 | function MouseMoveEventHandler(e) 125 | { 126 | mainCamera.MouseControl(e); 127 | } 128 | } 129 | 130 | main(); -------------------------------------------------------------------------------- /lessons/03_draw_from_index/README.md: -------------------------------------------------------------------------------- 1 | # 3. Draw from Index 2 | 3 | 이번에는 삼각형이 아닌 사각형을 그리면서 정점 인덱스를 사용하는 방법에 대해 알아보겠습니다. 4 | 5 | 사각형을 화면에 표시하기 위해서는 삼각형이 두 개가 필요합니다. 삼각형이 두개이니 정점은 6개가 필요하지만 실제로 6개 중 두 개의 정점은 동일한 좌표값을 가지므로 Unique한 좌표 값만을 생각해보면 4개의 정점만 있으면 됩니다. 6 | 7 | 이렇게 중복되는 정점을 여러 삼각형에서 공유하여 사용하려면 인덱스를 활용해서 삼각형을 정의해야 합니다. 코드로 직접 보시죠. 8 | 9 | ## How to 10 | 11 | 이전 코드에서 변화된 내용들을 보자면 아래와 같습니다. 12 | 13 | --- 14 | 1. 정점 4개 정의 15 | 16 | ```js 17 | var positions = [ //사각형의 4개 점들을 우선 정의 18 | -0.5, -0.5, //0번 vertex 19 | 0.5, -0.5, //1번 vertex 20 | 0.5, 0.5, //2번 vertex 21 | -0.5, 0.5, //3번 vertex 22 | ]; 23 | ``` 24 | 25 | 2. 인덱스 정의 26 | 27 | ```js 28 | var indices = [ 29 | 0, 1, 2, //0,1,2번 vertex로 이루어진 삼각형 30 | 2, 3, 0, //2,3,0번 vertex로 이루어진 삼각형 31 | ]; 32 | ``` 33 | 34 | 이제 사각형을 이루는 두 개의 삼각형이 어떤 정점들로 이루어져 있는지를 `indices`라는 배열에 정의합니다. 이전과 마찬가지로 6개의 숫자 데이터일 뿐이지만 우리는 삼각형을 그리도록 데이터를 정의한 것이기 때문에 알아보시기 쉽도록 3개씩 끊어서 주석을 적어 두었습니다. 35 | 36 | 위의 네 개 정점의 위치를 노트에 그려보고, (0, 1, 2 / 2, 3, 0) 인덱스로 어떻게 두 개의 삼각형을 만들 수 있는지를 먼저 확인해 보세요. 37 | 38 | 3. 인덱스 데이터 GPU로 전달 39 | 40 | ```js 41 | var indexBuffer = gl.createBuffer(); //1. 버퍼 만들기 42 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); //2. 버퍼 바인딩 43 | var uintIndices = new Uint16Array(indices); 44 | gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, //3. 데이터 복사해 넣기 45 | uintIndices, 46 | gl.STATIC_DRAW); 47 | ``` 48 | 49 | `positions` 데이터를 GPU로 전달한 것과 동일한 과정을 거칩니다. 50 | 51 | 1. 인덱스 정보를 저장할 버퍼를 GPU에 만들어 두고, 52 | 2. `gl.ELEMENT_ARRAY_BUFFER`로 해당 버퍼를 바인딩해서, 이후 데이터를 집어넣을 때 우리가 만든 버퍼에 데이터가 들어가도록 준비해 둡니다. 53 | 3. 마지막으로 `gl.ELEMENT_ARRAY_BUFFER`에 `bufferData()`를 사용해 데이터를 집어넣으면 1에서 우리가 만들어둔 버퍼가 `gl.ELEMENT_ARRAY_BUFFER`에 바인딩되어 있으므로 그 곳에 데이터가 들어가게 됩니다. 54 | 55 | `positions`처럼, JS 배열을 `Uint16` 타입으로 명시된 배열로 바꾸기 위해 먼저 생성해 둔 것도 잊지 마세요. 56 | 57 | 4. 인덱스를 사용하는 드로우콜 58 | 59 | ```js 60 | gl.drawElements(gl.TRIANGLES, // 삼각형을 그려라 61 | 6, //6개의 index를 그려라 62 | gl.UNSIGNED_SHORT, //index는 unsigned short 타입으로 정의되어 있다 63 | 0); //0번 위치부터 데이터를 읽어라 64 | ``` 65 | 66 | 인덱스를 사용해 그릴 때에는 `drawArrays()` 대신 `drawElements()` 함수를 호출해야 합니다. `drawArrays()`와 비교해 보면 인자를 하나 더 전달해 주어야 하는 것을 볼 수 있습니다. 67 | 68 | 연습 겸 해서 [레퍼런스 문서](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements)를 한번 읽어 보시고, 아래 설명을 보시면 좋을 것 같네요. 69 | 70 | * `gl.TRIANGLES`: (mode) 현재 그리려고 하는 것이 무엇인지를 명시합니다. 우리는 삼각형을 그리려는 것이고, 문서를 보면 아시겠지만 다른 것들도 그릴 수 있습니다. 71 | * `6`: (count) 몇 개의 데이터를 그릴 것인지를 명시합니다. 삼각형 두 개에 해당하는 인덱스 6개가 있으므로 6을 인자로 넘겨줍니다. 72 | * `gl.UNSIGNED_SHORT`: (type) 인덱스가 어떠한 데이터 타입으로 버퍼에 들어가 있는지를 알려줍니다. 73 | * `0`: (offset) 첫 데이터를 어디부터 읽을지를 명시합니다. 0~5까지 6개의 인덱스를 모두 사용할 것이므로 0부터 시작하도록 합니다. 74 | --- 75 | 76 | `http://localhost:8080/lessons/practice/contents.html`(또는 `http://localhost:8080/lessons/03_draw_from_index/contents.html`)에 접속해 보시면 화면에 파란색 사각형이 나오는 것을 보실 수 있습니다. 77 | 78 | 짝짝짝~ 하고 끝내지 마시고, 한번 생각해 봅시다. 앞서 우리가 정점 좌표 (`positions`)를 전달할 때에는 `vertexAttribPointer()`를 사용해 데이터를 어떻게 끊어서 읽을지를 따로 명시해 주었습니다. 인덱스와 관련해서는 왜 그런 API의 호출이 명시적으로 필요하지 않은걸까요? 스스로 생각해 보신 후에 아래 글을 펼쳐서 읽어보세요. 79 | 80 |
81 | 생각해 보셨나요? 82 | 83 | `drawElements()`의 인자로 데이터를 읽는 방법이 모두 설명되어 있습니다. `gl.TRIANGLES`이니 당연히 인덱스 3개씩이 필요하고, `gl.UNSIGNED_SHORT`를 통해 각 인덱스가 `UInt16`으로 표현되어 있다는 것을 알려주었습니다. 따라서 GPU는 버퍼에 쓰여진 데이터를 2바이트씩 끊어서 읽을 수 있습니다. 84 |
85 | 86 | ## Quiz 87 | 88 | 1. `gl.TRIANGLES` 대신 `gl.LINES`나 `gl.LINE_STRIP`으로 바꾸어서 그려지는 결과를 보고, 왜 그런 결과가 나왔는지 생각해 보세요. 각각이 무엇을 의미하는지는 아래 "Useful Links"의 글을 한 번 읽어보세요. 89 | 90 | 2. `drawElements()`의 두 번째 인자로 3을 넣으면 우측 하단의 삼각형 하나만 그려지게 됩니다. 왜 그럴까요? 91 | 92 | 3. 반대로, `drawElements()`의 인자를 바꾸어서 좌측 상단의 삼각형 하나만 그려지도록 바꾸어 보세요. (*힌트: 레퍼런스 문서에 써있다시피 `offset`은 바이트 단위의 크기를 인자로 받습니다!*) 93 | 94 | ## Useful Links 95 | 96 | - [WebGL2 점, 선, 삼각형](https://webgl2fundamentals.org/webgl/lessons/ko/webgl-points-lines-triangles.html) 97 | - [drawElements 레퍼런스 문서](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/drawElements) 98 | 99 | --- 100 | 101 | [다음 강의](../04_shader_uniform/) 102 | 103 | [목록으로](../) 104 | -------------------------------------------------------------------------------- /resources/tdl/buffers.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | /** 34 | * @fileoverview This file contains objects to deal with WebGL 35 | * buffers. 36 | */ 37 | 38 | tdl.provide('tdl.buffers'); 39 | 40 | /** 41 | * A module for buffers. 42 | * @namespace 43 | */ 44 | tdl.buffers = tdl.buffers || {}; 45 | 46 | tdl.buffers.Buffer = function(array, opt_target) { 47 | var target = opt_target || gl.ARRAY_BUFFER; 48 | var buf = gl.createBuffer(); 49 | this.target = target; 50 | this.buf = buf; 51 | this.set(array); 52 | this.numComponents_ = array.numComponents; 53 | this.numElements_ = array.numElements; 54 | this.totalComponents_ = this.numComponents_ * this.numElements_; 55 | if (array.buffer instanceof Float32Array) { 56 | this.type_ = gl.FLOAT; 57 | this.normalize_ = false; 58 | } else if (array.buffer instanceof Uint8Array) { 59 | this.type_ = gl.UNSIGNED_BYTE; 60 | this.normalize_ = true; 61 | } else if (array.buffer instanceof Int8Array) { 62 | this.type_ = gl.BYTE; 63 | this.normalize_ = true; 64 | } else if (array.buffer instanceof Uint16Array) { 65 | this.type_ = gl.UNSIGNED_SHORT; 66 | this.normalize_ = true; 67 | } else if (array.buffer instanceof Int16Array) { 68 | this.type_ = gl.SHORT; 69 | this.normalize_ = true; 70 | } else { 71 | throw("unhandled type:" + (typeof array.buffer)); 72 | } 73 | }; 74 | 75 | tdl.buffers.Buffer.prototype.set = function(array, opt_usage) { 76 | gl.bindBuffer(this.target, this.buf); 77 | gl.bufferData(this.target, array.buffer, opt_usage || gl.STATIC_DRAW); 78 | } 79 | 80 | tdl.buffers.Buffer.prototype.setRange = function(array, offset) { 81 | gl.bindBuffer(this.target, this.buf); 82 | gl.bufferSubData(this.target, offset, array); 83 | } 84 | 85 | tdl.buffers.Buffer.prototype.type = function() { 86 | return this.type_; 87 | }; 88 | 89 | tdl.buffers.Buffer.prototype.numComponents = function() { 90 | return this.numComponents_; 91 | }; 92 | 93 | tdl.buffers.Buffer.prototype.numElements = function() { 94 | return this.numElements_; 95 | }; 96 | 97 | tdl.buffers.Buffer.prototype.totalComponents = function() { 98 | return this.totalComponents_; 99 | }; 100 | 101 | tdl.buffers.Buffer.prototype.buffer = function() { 102 | return this.buf; 103 | }; 104 | 105 | tdl.buffers.Buffer.prototype.stride = function() { 106 | return 0; 107 | }; 108 | 109 | tdl.buffers.Buffer.prototype.normalize = function() { 110 | return this.normalize_; 111 | } 112 | 113 | tdl.buffers.Buffer.prototype.offset = function() { 114 | return 0; 115 | }; 116 | 117 | 118 | -------------------------------------------------------------------------------- /resources/jquery.mousecapture.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * jquery.mousecapture.js 4 | * version 1.1 5 | * by Sander Dieleman 6 | * A simple mouse capturing plugin for jQuery. 7 | * 8 | * 9 | * LICENSE 10 | * 11 | * This program is free software. It comes without any warranty, to 12 | * the extent permitted by applicable law. You can redistribute it 13 | * and/or modify it under the terms of the Do What The Fuck You Want 14 | * To Public License, Version 2, as published by Sam Hocevar. See 15 | * http://sam.zoy.org/wtfpl/COPYING for more details. 16 | * 17 | * 18 | * USAGE 19 | * 20 | * $( ... ).mousecapture({ 21 | * "down": function(event, sharedData) { ... }, 22 | * "move": function(event, sharedData) { ... }, 23 | * "up": function(event, sharedData) { ... } 24 | * }); 25 | * 26 | * "down", "move" and "up" are the handlers for the mousedown, mousemove and 27 | * mouseup events respectively. Only "down" is required. 28 | * 29 | * The unmodified event object is passed to the handlers (event), as well as 30 | * a blank slate object (sharedData) which can be used to store data that 31 | * needs to be shared between the handlers. Alternatively, shared variables 32 | * can be declared before the mousecapture call. 33 | * 34 | * Inside the handlers, "this" refers to the target element, just like when 35 | * jQuery's regular mouse events would be used. 36 | * 37 | * 38 | * DEMO 39 | * 40 | * A demo is available at: 41 | * http://benanne.net/misc/jquery-plugins/mousecapture/demo.html 42 | * 43 | * 44 | * MORE INFORMATION 45 | * 46 | * Read http://benanne.net/code/?p=238 for more information. 47 | * 48 | * 49 | * CHANGES 50 | * 51 | * v1.2 52 | * - the context in which the down and up handlers are executed should be 53 | * "$this", not "target". 54 | * - moved some code around to make it smaller: it doesn't matter wether 55 | * the handlers are attached / unattached before or after the actual 56 | * handler is executed. At least I think it doesn't. 57 | * 58 | * v1.1 59 | * - added "return this" to the mousecapture method, so it conforms to the 60 | * jQuery plugin authoring guidelines. 61 | * 62 | * v1.0 63 | * - first version 64 | * 65 | */ 66 | 67 | (function($) { 68 | 69 | $.fn.mousecapture = function(params) { 70 | var $doc = $(document); 71 | 72 | this.each(function() { 73 | var $this = $(this); 74 | var sharedData = {}; 75 | 76 | $this.mousedown(function(e) { 77 | // mousemove 78 | 79 | var moveHandler; 80 | 81 | var capture = true; 82 | if (params.mouseCapture) { 83 | capture = params.mouseCapture.call($this, e, sharedData); 84 | } 85 | 86 | if (capture && params.move) { 87 | moveHandler = function(e) { 88 | params.move.call($this, e, sharedData); 89 | }; 90 | 91 | $doc.mousemove(moveHandler); 92 | } 93 | 94 | // mouseup 95 | 96 | var upHandler; 97 | 98 | var unbind = function() { 99 | if (params.move) $doc.unbind("mousemove", moveHandler); 100 | $doc.unbind("mouseup", upHandler); 101 | }; 102 | 103 | if (params.up) { 104 | upHandler = function(e) { 105 | unbind(); 106 | return params.up.call($this, e, sharedData); 107 | }; 108 | } 109 | else { 110 | upHandler = unbind; 111 | } 112 | 113 | $doc.mouseup(upHandler); 114 | 115 | // mousedown 116 | 117 | return params.down.call($this, e, sharedData); 118 | }); 119 | }); 120 | 121 | return this; 122 | }; 123 | 124 | })(jQuery); 125 | 126 | -------------------------------------------------------------------------------- /resources/tdl/clock.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009, Google Inc. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are 7 | * met: 8 | * 9 | * * Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above 12 | * copyright notice, this list of conditions and the following disclaimer 13 | * in the documentation and/or other materials provided with the 14 | * distribution. 15 | * * Neither the name of Google Inc. nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | 33 | /** 34 | * @fileoverview This file contains various functions for managing a clock 35 | */ 36 | 37 | tdl.provide('tdl.clock'); 38 | 39 | tdl.require('tdl.io'); 40 | tdl.require('tdl.log'); 41 | 42 | /** 43 | * Creates a clock. Optionally synced to a server 44 | * @param {number} opt_syncRate. If passed, this is the number of seconds 45 | * between syncing to the server. If not passed the local clock is used. 46 | * Note: If the client is faster than the server this means it's possible 47 | * the clock will report a certain time and then later a previous time. 48 | */ 49 | tdl.clock.createClock = function(opt_syncRate, opt_url) { 50 | if (opt_syncRate) { 51 | return new tdl.clock.SyncedClock(opt_syncRate, opt_url); 52 | } else { 53 | return new tdl.clock.LocalClock(); 54 | } 55 | }; 56 | 57 | 58 | /** 59 | * A clock that gets the local current time in seconds. 60 | * @private 61 | */ 62 | tdl.clock.LocalClock = function() { 63 | } 64 | 65 | /** 66 | * Gets the current time in seconds. 67 | * @private 68 | */ 69 | tdl.clock.LocalClock.prototype.getTime = function() { 70 | return (new Date()).getTime() * 0.001; 71 | } 72 | 73 | /** 74 | * A clock that gets the current time in seconds attempting to eep the clock 75 | * synced to the server. 76 | * @private 77 | */ 78 | tdl.clock.SyncedClock = function(opt_syncRate, opt_url) { 79 | this.url = opt_url || window.location.href; 80 | this.syncRate = opt_syncRate || 10; 81 | this.timeOffset = 0; 82 | this.syncToServer(); 83 | } 84 | 85 | tdl.clock.SyncedClock.prototype.getLocalTime_ = function() { 86 | return (new Date()).getTime() * 0.001; 87 | } 88 | 89 | tdl.clock.SyncedClock.prototype.syncToServer = function() { 90 | var that = this; 91 | var sendTime = this.getLocalTime_(); 92 | tdl.io.sendJSON(this.url, {cmd: 'time'}, function(obj, exception) { 93 | if (exception) { 94 | tdl.log("error: syncToServer: " + exception); 95 | } else { 96 | var receiveTime = that.getLocalTime_(); 97 | var duration = receiveTime - sendTime; 98 | var serverTime = obj.time + duration * 0.5; 99 | that.timeOffset = serverTime - receiveTime; 100 | tdl.log("new timeoffset: " + that.timeOffset); 101 | } 102 | setTimeout(function() { 103 | that.syncToServer(); 104 | }, that.syncRate * 1000); 105 | }); 106 | }; 107 | 108 | /** 109 | * Gets the current time in seconds. 110 | * @private 111 | */ 112 | tdl.clock.SyncedClock.prototype.getTime = function() { 113 | return (new Date()).getTime() * 0.001 + this.timeOffset; 114 | } 115 | 116 | -------------------------------------------------------------------------------- /lessons/12_model_matrix_and_load_obj/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | //Classes 4 | import VertexBuffer from '../_classes/VertexBuffer.js'; 5 | import IndexBuffer from '../_classes/IndexBuffer.js'; 6 | import VertexArray from '../_classes/VertexArray.js'; 7 | import Shader from '../_classes/Shader.js'; 8 | import Renderer from '../_classes/Renderer.js'; 9 | import Camera from '../_classes/Camera.js'; 10 | 11 | //Shaders 12 | import basicVertexShader from '../_shaders/basicVertex.js'; 13 | import basicFragmentShader from '../_shaders/basicFragment.js'; 14 | 15 | const {mat2, mat3, mat4, vec2, vec3, vec4} = glMatrix; 16 | 17 | async function main() { 18 | // Get A WebGL context 19 | let canvas = document.querySelector("#c"); 20 | let gl = canvas.getContext("webgl2"); 21 | if (!gl) { 22 | return; 23 | } 24 | 25 | //이제 모델의 정점 데이터를 직접 정의하지 않고, 외부 파일에서 가져옴 26 | //모델을 로딩하는 과정에서 freeze가 걸리지 않도록 async/await로 obj 파일을 읽어옵니다. (main함수 앞의 async 주목) 27 | //const response = await fetch('../../resources/models/cube/cube.obj'); 28 | const response = await fetch('../../resources/models/cube/cube.obj'); 29 | const text = await response.text(); 30 | let mesh = new OBJ.Mesh(text); //라이브러리의 Mesh 메소드로 obj를 파싱합니다. 31 | 32 | let meshVertexData = [] 33 | 34 | let vertexCount = mesh.vertices.length/3; 35 | for(let i=0; i 2 | 3 | 4 | 5 | WebGL 3.Draw from Index 6 | 7 | 8 | 9 |
WebGL 3.Draw from Index
10 | 11 | 12 | 13 | 14 | 117 | -------------------------------------------------------------------------------- /lessons/08_vertex_array_abstraction/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | import VertexBuffer from '../_classes/VertexBuffer.js'; 4 | import IndexBuffer from '../_classes/IndexBuffer.js'; 5 | 6 | class VertexArray{ 7 | id; 8 | 9 | //VertexBuffer에는 vertex의 position 뿐만 아니라 다양한 vertex 관련 데이터가 들어올 수 있다. 10 | //이를 손쉽게 다루기 위해 VertexBuffer보다 상위 수준인 vao를 관리할 수 있는 클래스를 정의 11 | constructor(gl) 12 | { 13 | this.id = gl.createVertexArray(); //this.id == vao 14 | //vao의 바인딩은 AddBuffer 직전에 수행하도록 한다. 15 | } 16 | 17 | Bind(gl) 18 | { 19 | gl.bindVertexArray(this.id); 20 | } 21 | 22 | Unbind(gl) 23 | { 24 | gl.bindVertexArray(null); 25 | } 26 | 27 | AddBuffer(gl, vb, countArray, normalizedArray) 28 | { 29 | //countArray와 normalizedArray의 길이는 같아야 함 30 | console.assert(countArray.length == normalizedArray.length, 31 | "length of countArray and normalizedArray should match!"); 32 | this.Bind(gl); //VAO binding 33 | vb.Bind(gl); //입력된 VertexBuffer binding 34 | 35 | var stride = 0; 36 | for(var i=0;i