Commits

David Lin committed f6d30f2

rotate cube

Comments (0)

Files changed (5)

data/assets/programs/depth.program.yml

+---
+:attribs: 
+  in_Position: 0
+:frag_datas:
+  fs_FragColor: 0
+:shaders:
+  - :type: :vertex
+    :file: cube_normal.vertex.glsl
+  - :type: :geometry
+    :file: cube_normal.geometry.glsl
+  - :type: :fragment
+    :code: |
+           #version 150 core
+           in vec3 gs_Position;
+           in vec3 gs_Normal;
+           out vec4 fs_FragColor;
+           void main()
+           { // BEGIN
+             fs_FragColor = vec4(gl_FragCoord.z);
+           } // END
+

data/assets/programs/plastic.program.yml

   - :type: :fragment
     :code: |
            #version 150 core
-           uniform vec3 u_Ka;
-           uniform vec3 u_Kd;
+           uniform vec3 u_Albedo;
            uniform vec3 u_Ks;
            uniform float u_Ns;
            uniform vec3 u_Light_Ka;
              // Half Vector (from point)
              vec3 hv = normalize(lv + vec3(0,0,1));
              // Ambient
-             vec3 ka = u_Ka * u_Light_Ka;
+             vec3 ka = u_Albedo * u_Light_Ka;
              // Diffuse
-             vec3 kd = u_Kd * u_Light_Kd;
+             vec3 kd = u_Albedo * u_Light_Kd;
              kd *= max(0, dot(gs_Normal, lv));
              // Specular
              vec3 ks = u_Ks * u_Light_Ks;

data/assets/programs/scattering.program.yml

+---
+:attribs: 
+  in_Position: 0
+:frag_datas:
+  fs_FragColor: 0
+:shaders:
+  - :type: :vertex
+    :file: cube_normal.vertex.glsl
+  - :type: :geometry
+    :file: cube_normal.geometry.glsl
+  - :type: :fragment
+    :code: |
+           #version 150 core
+           uniform vec3 u_Albedo;
+           uniform vec3 u_Ks;
+           uniform float u_Ns;
+           uniform vec3 u_Light_Ka;
+           uniform vec3 u_Light_Kd;
+           uniform vec3 u_Light_Ks;
+           uniform vec3 u_Light_Pos;
+           uniform vec3 u_Light_SpotDir;
+           uniform float u_Light_SpotCosCutoff;
+           uniform mat4 u_Light_XfmFromView;
+           uniform sampler2D s_ShadowMap;
+           uniform float u_SSS_Strength;
+           in vec3 gs_Position;
+           in vec3 gs_Normal;
+           out vec4 fs_FragColor;
+           // distance
+           float distance(vec3 posV, vec3 normalV, int i) {
+             // Shrink the position to avoid artifacts on the silhouette
+             posV = posV - 0.005 * normalV;
+             // Transform to light space (from view space)
+             vec4 posL = u_Light_XfmFromView * vec4(posV, 1.0);
+             // Fetch depth from the shadow map
+             float d1 = texture(s_ShadowMap, posL.xy / posL.w);
+             float d2 = posL.z;
+             // Calculate the difference
+             return abs(d1 - d2);
+           } // END distance
+           // T function
+           vec3 T(float s) {
+             return vec3(0.233, 0.455, 0.648) * exp(-s * s / 0.0064) +
+                    vec3(0.1,   0.336, 0.344) * exp(-s * s / 0.0484) +
+                    vec3(0.118, 0.198, 0.0)   * exp(-s * s / 0.187)  +
+                    vec3(0.113, 0.007, 0.007) * exp(-s * s / 0.567)  +
+                    vec3(0.358, 0.004, 0.0)   * exp(-s * s / 1.99)   +
+                    vec3(0.078, 0.0,   0.0)   * exp(-s * s / 7.41);
+           } // END T
+           // entry point
+           void main()
+           { // BEGIN
+             // Light Vector (from point to light)
+             vec3 lv = normalize(u_Light_Pos - gs_Position);
+             // Half Vector (from point)
+             vec3 hv = normalize(lv + vec3(0,0,1));
+             // Ambient
+             vec3 ka = u_Albedo * u_Light_Ka;
+             // Diffuse
+             vec3 kd = u_Albedo * u_Light_Kd;
+             kd *= max(0, dot(gs_Normal, lv));
+             // Specular
+             vec3 ks = u_Ks * u_Light_Ks;
+             ks *= pow(max(0, dot(gs_Normal, hv)), u_Ns);
+             // Spot cutoff
+             float cut = dot(lv, -u_Light_SpotDir) - u_Light_SpotCosCutoff;
+             cut = max(0.0, sign(cut));
+             kd *= cut; ks *= cut;
+             // Scattering
+             // Calculate the distance traveled by the light inside of the object
+             float s = distance(gs_Position, gs_Normal) / u_SSS_Strength;
+             // Estimate the irradiance on the back
+             vec3 light = normalize(u_Light_Pos - gs_Position); // regular light vec
+             float irradiance = max(0.3 + dot(-gs_Normal, light), 0.0);
+             // Calculate transmitted light
+             vec3 transmittance = T(s) * u_Albedo * u_Light_Kd * cut * irradiance;
+             // Final
+             vec3 color = /*ka + kd + ks +*/ transmittance;
+             fs_FragColor = vec4(color, 1.0);
+           } // END
+
     super(version: [4, 2], depth: true)
     @render = Render.new(gl_functions)
     @render[:view] = Matrix3D.translate(0, 0, -5)
+    @render[:inverse_view] = Matrix3D.translate(0, 0, 5)
     @render[:world] = Matrix3D.identity
+    @render[:light_pos] = Vector[3.0, 3.0, 3.0, 1.0]
+    @render[:light_dir] = Vector[-1, -1, -1, 0.0].normalize
+    @render[:light_znear] = 1.0
+    @render[:light_zfar] = 10.0
+    @render[:light_cut_angle] = Math::PI * 0.25
+    @render[:light_up] = Vector[0.0, 1.0, 0.0, 0.0]
+    @render[:light_proj] = Matrix3D.perspective @render[:light_cut_angle], 1.0,
+                                                @render[:light_znear],
+                                                @render[:light_zfar]
   end
   
   def display
   
   def reshape(width, height)
     glViewport(0, 0, width, height)
+    @render[:window_width] = width
+    @render[:window_height] = height
     
     fovy = 45.0 / 180.0 * Math::PI
     aspect = Float(width) / Float(height)
     if button == :LEFT
       case button_state
       when :DOWN
-        @mouse_tracking_pos = [x, y]
+        @left_mouse_pos = [x, y]
       when :UP
-        remove_instance_variable(:@mouse_tracking_pos)
+        remove_instance_variable(:@left_mouse_pos)
+      end
+    end
+    if button == :RIGHT
+      case button_state
+      when :DOWN
+        @right_mouse_pos = [x, y]
+      when :UP
+        remove_instance_variable(:@right_mouse_pos)
       end
     end
   end
   
   def motion(x, y)
-    if defined? @mouse_tracking_pos
-      delta_x = (x - @mouse_tracking_pos[0]) * 0.01
-      delta_y = (y - @mouse_tracking_pos[1]) * 0.01
+    if defined? @left_mouse_pos
+      delta_x = (x - @left_mouse_pos[0]) * 0.01
+      delta_y = (y - @left_mouse_pos[1]) * 0.01
       
       rotx = Matrix3D.rotate(delta_y, 1.0, 0.0, 0.0)
       roty = Matrix3D.rotate(delta_x, 0.0, 1.0, 0.0)
       @render[:world] = rotx * roty * @render[:world]
       
-      @mouse_tracking_pos = [x, y]
+      @left_mouse_pos = [x, y]
+      glutPostRedisplay()
+    end
+    if defined? @right_mouse_pos
+      delta_x = (x - @right_mouse_pos[0]) * 0.001
+      delta_y = (y - @right_mouse_pos[1]) * 0.001
+      
+      rotx = Matrix3D.rotate(delta_y, 1.0, 0.0, 0.0)
+      roty = Matrix3D.rotate(delta_x, 0.0, 1.0, 0.0)
+      r = rotx * roty
+      lpos = rotx * roty * @render[:light_pos]
+      @render[:light_dir] = @render[:light_dir]
+      @render[:light_pos] = r * @render[:light_pos]
+      @render[:light_up] = r * @render[:light_up]
+      
       glutPostRedisplay()
     end
   end
     @program = My::Program.new(gl).tap do |program|
       program.prepare 'plastic'
     end
+    
   end
   
   def [](key)
     @parameters.store(key, value)
   end
   
+  def update_uniform(prog)
+    prog.set_matrix_4x4f 'u_Projection', self[:projection]
+    prog.set_matrix_4x4f 'u_ModelView', self[:view] * self[:world]
+    prog.set_3f 'u_Albedo', Vector[0.4, 0.4, 0.4]
+    prog.set_3f 'u_Ks', Vector[0.5, 0.5, 0.5]
+    prog.set_1f 'u_Ns', 2.0
+    prog.set_3f 'u_Light_Ka', Vector[0.0, 0.0, 0.0]
+    prog.set_3f 'u_Light_Kd', Vector[1.0, 1.0, 1.0]
+    prog.set_3f 'u_Light_Ks', Vector[1.0, 1.0, 1.0]
+    prog.set_3f 'u_Light_Pos', (self[:view] * self[:light_pos])
+    prog.set_3f 'u_Light_SpotDir', (self[:view] * self[:light_dir]).normalize
+    prog.set_1f 'u_Light_SpotCosCutoff', Math.cos(self[:light_cut_angle])
+    prog.set_1f 'u_SSS_Strength', 1.0
+    prog.set_1i 's_ShadowMap', 0
+    #light_xfm_from_view = @light_proj * self[:inverse_view]
+    #prog.set_matrix_4x4f 'u_Light_XfmFromView', light_xfm_from_view
+  end
+  
   def draw
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
-    
-    glUseProgram(@program.id)
-    @program.set_matrix_4x4f 'u_Projection', self[:projection]
-    @program.set_matrix_4x4f 'u_ModelView', self[:view] * self[:world]
-    @program.set_3f 'u_Ka', Vector[0.0, 0.0, 0.0]
-    @program.set_3f 'u_Kd', Vector[0.4, 0.4, 0.4]
-    @program.set_3f 'u_Ks', Vector[0.5, 0.5, 0.5]
-    @program.set_1f 'u_Ns', 2.0
-    @program.set_3f 'u_Light_Ka', Vector[0.0, 0.0, 0.0]
-    @program.set_3f 'u_Light_Kd', Vector[1.0, 1.0, 1.0]
-    @program.set_3f 'u_Light_Ks', Vector[1.0, 1.0, 1.0]
-    @program.set_3f 'u_Light_Pos', (self[:view] * Vector[1.3, 1.3, 1.3, 1.0])
-    @program.set_3f 'u_Light_SpotDir', (self[:view] * Vector[-1.0, -1.0, -1.0, 0.0]).normalize
-    @program.set_1f 'u_Light_SpotCosCutoff', Math.cos(Math::PI * 0.25)
+    light_lookat = Matrix3D.look_at self[:light_pos].xyz,
+                                    self[:light_pos].xyz + self[:light_dir].xyz,
+                                    self[:light_up].xyz
     
     glEnable GL_DEPTH_TEST
-    @geom.bind_vertex_attrib
+    glEnable GL_CULL_FACE
+    
+    # Display Back Buffer
+    #glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)
+    #glDrawBuffer(GL_BACK)
+    #glViewport(0, 0, self[:window_width], self[:window_height])
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
+    
+    @program.tap do |prog|
+      glUseProgram(prog.id)
+      update_uniform(prog)
+    end
+   
+    @geom.bind_vertex_attrib 
     @geom.draw
+    
   end
   
 end