Repository files navigation

Computer Graphics 2020, Course Project

Politecnico di Milano - MSc in Computer Science and Engineering

Project Description

The aim of this project was to develop a WebGL application and associated OpenGL shaders that will render a 3D model of Cat Wall Watch like the one below from a frame of Back to the Future.

Implementation

The application has been written in JavaScript and GLSL and consists of different 3D .obj files with the requirement that the final implementation should show the current time and the movement of the cat's eyes and tail needs to be in the same direction, as the real clock does.

The final result is:

Textures

Most of the components of the watch use two kinds of textures: a normal color texture and a normal map texture that encodes information about normal vectors for each internal point of a triangle. Because of the tangent space encoding of this values in the normal map, the fragment shader will perform an on-the-fly computation of geometrical normals to obtain the tangent and bitangent vectors. This dynamic computation can be enabled in the UI control "Compute geometrical normals" and is not enabled by default because using the normal vector direction stored with the geometry results in a better rendering.

UI Controls

In addition to a simple implementation of the cat watch I've also implemented an interface to control the lights inside the scene, with the related diffuse and specular effects. This UI communicates directly with the GLSL program of each 3D component setting the current option, light positions and colors.

Lights

It's possible to enable up to 3 different types of lights in the scene: directional, point and spot lights, with their related color, coordinates and angles. In addition to that I've implemented Diffuse(Lambert, Toon) and Specular (Phong, Blinn, Toon Phong, Toon Blinn).

Camera

The camera looks at the cat and, by default, it's set at the coordinates x = 0.0, y = 0.05, z = 0.2. However it's possible to change these parameters and move the "eye" around the object by using the arrow keys to change coordinates x and y, and +/- keys to move along the z axis.

Eyes and Tail Movement

The animation of eyes and tail is performed by the function animate() of main.js and it relies on the assumption that the window.requestAnimationFrame method performs a number of callbacks to it that is usually 60 times per second. Therefore in 60fps the tail and eyes will have 15 frames to move in a fixed direction, 15 frames to return to the centre and again 15+15 frames in the opposite direction, resulting in a 60 frames pendulum movement. A delta equal to 1, as it's set by default, will move the objects of 15 degrees in both directions.

Clockhands Movement

The clockhands rotation (in degrees) is calculated on the current time as follows:

hoursRotationMatrix = rotateZ( -(hour + minutes/60) * 2*Math.PI/12 );

minutesRotationMatrix = rotateZ( -minutes * 2*Math.PI/60 );

where hour is a number between 0 and 11 while minutes varies from 0 to 59. For a better result the hours clockhand's rotation is also influenced by the number of elapsed minutes.

Building and Deploying the project

The last version of the project is available at this GitHub Page but can also be build offline by cloning this repository and running a webserver (e.g. Apache) in the same folder.

Screenshots

Fig. 1 - a single white direct light with Lambert diffuse and Phong Specular. Fig. 2 - a yellow direct light with Toon diffuse and warmer yellow Phong Specular. Fig. 3 - a yellow direct light and a red point light with Toon diffuse and Phong Specular. Fig. 4 - in addition to the previous two lights, a blue spot light with Toon diffuse and Phong Specular.

About

πŸ‘Ύ Computer Graphics course project at Politecnico di Milano (2020)

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Computer Graphics 2020, Course Project

Politecnico di Milano - MSc in Computer Science and Engineering

Project Description

The aim of this project was to develop a WebGL application and associated OpenGL shaders that will render a 3D model of Cat Wall Watch like the one below from a frame of Back to the Future.

Implementation

The application has been written in JavaScript and GLSL and consists of different 3D .obj files with the requirement that the final implementation should show the current time and the movement of the cat's eyes and tail needs to be in the same direction, as the real clock does.

The final result is:

Textures

Most of the components of the watch use two kinds of textures: a normal color texture and a normal map texture that encodes information about normal vectors for each internal point of a triangle. Because of the tangent space encoding of this values in the normal map, the fragment shader will perform an on-the-fly computation of geometrical normals to obtain the tangent and bitangent vectors. This dynamic computation can be enabled in the UI control "Compute geometrical normals" and is not enabled by default because using the normal vector direction stored with the geometry results in a better rendering.

UI Controls

In addition to a simple implementation of the cat watch I've also implemented an interface to control the lights inside the scene, with the related diffuse and specular effects. This UI communicates directly with the GLSL program of each 3D component setting the current option, light positions and colors.

Lights

It's possible to enable up to 3 different types of lights in the scene: directional, point and spot lights, with their related color, coordinates and angles. In addition to that I've implemented Diffuse(Lambert, Toon) and Specular (Phong, Blinn, Toon Phong, Toon Blinn).

Camera

The camera looks at the cat and, by default, it's set at the coordinates x = 0.0, y = 0.05, z = 0.2. However it's possible to change these parameters and move the "eye" around the object by using the arrow keys to change coordinates x and y, and +/- keys to move along the z axis.

Eyes and Tail Movement

The animation of eyes and tail is performed by the function animate() of main.js and it relies on the assumption that the window.requestAnimationFrame method performs a number of callbacks to it that is usually 60 times per second. Therefore in 60fps the tail and eyes will have 15 frames to move in a fixed direction, 15 frames to return to the centre and again 15+15 frames in the opposite direction, resulting in a 60 frames pendulum movement. A delta equal to 1, as it's set by default, will move the objects of 15 degrees in both directions.

Clockhands Movement

The clockhands rotation (in degrees) is calculated on the current time as follows:

hoursRotationMatrix = rotateZ( -(hour + minutes/60) * 2*Math.PI/12 );

minutesRotationMatrix = rotateZ( -minutes * 2*Math.PI/60 );

where hour is a number between 0 and 11 while minutes varies from 0 to 59. For a better result the hours clockhand's rotation is also influenced by the number of elapsed minutes.

Building and Deploying the project

The last version of the project is available at this GitHub Page but can also be build offline by cloning this repository and running a webserver (e.g. Apache) in the same folder.

Screenshots

Fig. 1 - a single white direct light with Lambert diffuse and Phong Specular. Fig. 2 - a yellow direct light with Toon diffuse and warmer yellow Phong Specular. Fig. 3 - a yellow direct light and a red point light with Toon diffuse and Phong Specular. Fig. 4 - in addition to the previous two lights, a blue spot light with Toon diffuse and Phong Specular.

About

πŸ‘Ύ Computer Graphics course project at Politecnico di Milano (2020)

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Computer Graphics 2020, Course Project

Politecnico di Milano - MSc in Computer Science and Engineering

Project Description

The aim of this project was to develop a WebGL application and associated OpenGL shaders that will render a 3D model of Cat Wall Watch like the one below from a frame of Back to the Future.

Implementation

The application has been written in JavaScript and GLSL and consists of different 3D .obj files with the requirement that the final implementation should show the current time and the movement of the cat's eyes and tail needs to be in the same direction, as the real clock does.

The final result is:

Textures

Most of the components of the watch use two kinds of textures: a normal color texture and a normal map texture that encodes information about normal vectors for each internal point of a triangle. Because of the tangent space encoding of this values in the normal map, the fragment shader will perform an on-the-fly computation of geometrical normals to obtain the tangent and bitangent vectors. This dynamic computation can be enabled in the UI control "Compute geometrical normals" and is not enabled by default because using the normal vector direction stored with the geometry results in a better rendering.

UI Controls

In addition to a simple implementation of the cat watch I've also implemented an interface to control the lights inside the scene, with the related diffuse and specular effects. This UI communicates directly with the GLSL program of each 3D component setting the current option, light positions and colors.

Lights

It's possible to enable up to 3 different types of lights in the scene: directional, point and spot lights, with their related color, coordinates and angles. In addition to that I've implemented Diffuse(Lambert, Toon) and Specular (Phong, Blinn, Toon Phong, Toon Blinn).

Camera

The camera looks at the cat and, by default, it's set at the coordinates x = 0.0, y = 0.05, z = 0.2. However it's possible to change these parameters and move the "eye" around the object by using the arrow keys to change coordinates x and y, and +/- keys to move along the z axis.

Eyes and Tail Movement

The animation of eyes and tail is performed by the function animate() of main.js and it relies on the assumption that the window.requestAnimationFrame method performs a number of callbacks to it that is usually 60 times per second. Therefore in 60fps the tail and eyes will have 15 frames to move in a fixed direction, 15 frames to return to the centre and again 15+15 frames in the opposite direction, resulting in a 60 frames pendulum movement. A delta equal to 1, as it's set by default, will move the objects of 15 degrees in both directions.

Clockhands Movement

The clockhands rotation (in degrees) is calculated on the current time as follows:

hoursRotationMatrix = rotateZ( -(hour + minutes/60) * 2*Math.PI/12 );

minutesRotationMatrix = rotateZ( -minutes * 2*Math.PI/60 );

where hour is a number between 0 and 11 while minutes varies from 0 to 59. For a better result the hours clockhand's rotation is also influenced by the number of elapsed minutes.

Building and Deploying the project

The last version of the project is available at this GitHub Page but can also be build offline by cloning this repository and running a webserver (e.g. Apache) in the same folder.

Screenshots

Fig. 1 - a single white direct light with Lambert diffuse and Phong Specular. Fig. 2 - a yellow direct light with Toon diffuse and warmer yellow Phong Specular. Fig. 3 - a yellow direct light and a red point light with Toon diffuse and Phong Specular. Fig. 4 - in addition to the previous two lights, a blue spot light with Toon diffuse and Phong Specular.

About

πŸ‘Ύ Computer Graphics course project at Politecnico di Milano (2020)

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Computer Graphics 2020, Course Project

Politecnico di Milano - MSc in Computer Science and Engineering

Project Description

The aim of this project was to develop a WebGL application and associated OpenGL shaders that will render a 3D model of Cat Wall Watch like the one below from a frame of Back to the Future.

Implementation

The application has been written in JavaScript and GLSL and consists of different 3D .obj files with the requirement that the final implementation should show the current time and the movement of the cat's eyes and tail needs to be in the same direction, as the real clock does.

The final result is:

Textures

Most of the components of the watch use two kinds of textures: a normal color texture and a normal map texture that encodes information about normal vectors for each internal point of a triangle. Because of the tangent space encoding of this values in the normal map, the fragment shader will perform an on-the-fly computation of geometrical normals to obtain the tangent and bitangent vectors. This dynamic computation can be enabled in the UI control "Compute geometrical normals" and is not enabled by default because using the normal vector direction stored with the geometry results in a better rendering.

UI Controls

In addition to a simple implementation of the cat watch I've also implemented an interface to control the lights inside the scene, with the related diffuse and specular effects. This UI communicates directly with the GLSL program of each 3D component setting the current option, light positions and colors.

Lights

It's possible to enable up to 3 different types of lights in the scene: directional, point and spot lights, with their related color, coordinates and angles. In addition to that I've implemented Diffuse(Lambert, Toon) and Specular (Phong, Blinn, Toon Phong, Toon Blinn).

Camera

The camera looks at the cat and, by default, it's set at the coordinates x = 0.0, y = 0.05, z = 0.2. However it's possible to change these parameters and move the "eye" around the object by using the arrow keys to change coordinates x and y, and +/- keys to move along the z axis.

Eyes and Tail Movement

The animation of eyes and tail is performed by the function animate() of main.js and it relies on the assumption that the window.requestAnimationFrame method performs a number of callbacks to it that is usually 60 times per second. Therefore in 60fps the tail and eyes will have 15 frames to move in a fixed direction, 15 frames to return to the centre and again 15+15 frames in the opposite direction, resulting in a 60 frames pendulum movement. A delta equal to 1, as it's set by default, will move the objects of 15 degrees in both directions.

Clockhands Movement

The clockhands rotation (in degrees) is calculated on the current time as follows:

hoursRotationMatrix = rotateZ( -(hour + minutes/60) * 2*Math.PI/12 );

minutesRotationMatrix = rotateZ( -minutes * 2*Math.PI/60 );

where hour is a number between 0 and 11 while minutes varies from 0 to 59. For a better result the hours clockhand's rotation is also influenced by the number of elapsed minutes.

Building and Deploying the project

The last version of the project is available at this GitHub Page but can also be build offline by cloning this repository and running a webserver (e.g. Apache) in the same folder.

Screenshots

Fig. 1 - a single white direct light with Lambert diffuse and Phong Specular. Fig. 2 - a yellow direct light with Toon diffuse and warmer yellow Phong Specular. Fig. 3 - a yellow direct light and a red point light with Toon diffuse and Phong Specular. Fig. 4 - in addition to the previous two lights, a blue spot light with Toon diffuse and Phong Specular.

About

πŸ‘Ύ Computer Graphics course project at Politecnico di Milano (2020)

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Computer Graphics 2020, Course Project

Politecnico di Milano - MSc in Computer Science and Engineering

Project Description

The aim of this project was to develop a WebGL application and associated OpenGL shaders that will render a 3D model of Cat Wall Watch like the one below from a frame of Back to the Future.

Implementation

The application has been written in JavaScript and GLSL and consists of different 3D .obj files with the requirement that the final implementation should show the current time and the movement of the cat's eyes and tail needs to be in the same direction, as the real clock does.

The final result is:

Textures

Most of the components of the watch use two kinds of textures: a normal color texture and a normal map texture that encodes information about normal vectors for each internal point of a triangle. Because of the tangent space encoding of this values in the normal map, the fragment shader will perform an on-the-fly computation of geometrical normals to obtain the tangent and bitangent vectors. This dynamic computation can be enabled in the UI control "Compute geometrical normals" and is not enabled by default because using the normal vector direction stored with the geometry results in a better rendering.

UI Controls

In addition to a simple implementation of the cat watch I've also implemented an interface to control the lights inside the scene, with the related diffuse and specular effects. This UI communicates directly with the GLSL program of each 3D component setting the current option, light positions and colors.

Lights

It's possible to enable up to 3 different types of lights in the scene: directional, point and spot lights, with their related color, coordinates and angles. In addition to that I've implemented Diffuse(Lambert, Toon) and Specular (Phong, Blinn, Toon Phong, Toon Blinn).

Camera

The camera looks at the cat and, by default, it's set at the coordinates x = 0.0, y = 0.05, z = 0.2. However it's possible to change these parameters and move the "eye" around the object by using the arrow keys to change coordinates x and y, and +/- keys to move along the z axis.

Eyes and Tail Movement

The animation of eyes and tail is performed by the function animate() of main.js and it relies on the assumption that the window.requestAnimationFrame method performs a number of callbacks to it that is usually 60 times per second. Therefore in 60fps the tail and eyes will have 15 frames to move in a fixed direction, 15 frames to return to the centre and again 15+15 frames in the opposite direction, resulting in a 60 frames pendulum movement. A delta equal to 1, as it's set by default, will move the objects of 15 degrees in both directions.

Clockhands Movement

The clockhands rotation (in degrees) is calculated on the current time as follows:

hoursRotationMatrix = rotateZ( -(hour + minutes/60) * 2*Math.PI/12 );

minutesRotationMatrix = rotateZ( -minutes * 2*Math.PI/60 );

where hour is a number between 0 and 11 while minutes varies from 0 to 59. For a better result the hours clockhand's rotation is also influenced by the number of elapsed minutes.

Building and Deploying the project

The last version of the project is available at this GitHub Page but can also be build offline by cloning this repository and running a webserver (e.g. Apache) in the same folder.

Screenshots

Fig. 1 - a single white direct light with Lambert diffuse and Phong Specular. Fig. 2 - a yellow direct light with Toon diffuse and warmer yellow Phong Specular. Fig. 3 - a yellow direct light and a red point light with Toon diffuse and Phong Specular. Fig. 4 - in addition to the previous two lights, a blue spot light with Toon diffuse and Phong Specular.

About

πŸ‘Ύ Computer Graphics course project at Politecnico di Milano (2020)

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Computer Graphics 2020, Course Project

Politecnico di Milano - MSc in Computer Science and Engineering

Project Description

The aim of this project was to develop a WebGL application and associated OpenGL shaders that will render a 3D model of Cat Wall Watch like the one below from a frame of Back to the Future.

Implementation

The application has been written in JavaScript and GLSL and consists of different 3D .obj files with the requirement that the final implementation should show the current time and the movement of the cat's eyes and tail needs to be in the same direction, as the real clock does.

The final result is:

Textures

Most of the components of the watch use two kinds of textures: a normal color texture and a normal map texture that encodes information about normal vectors for each internal point of a triangle. Because of the tangent space encoding of this values in the normal map, the fragment shader will perform an on-the-fly computation of geometrical normals to obtain the tangent and bitangent vectors. This dynamic computation can be enabled in the UI control "Compute geometrical normals" and is not enabled by default because using the normal vector direction stored with the geometry results in a better rendering.

UI Controls

In addition to a simple implementation of the cat watch I've also implemented an interface to control the lights inside the scene, with the related diffuse and specular effects. This UI communicates directly with the GLSL program of each 3D component setting the current option, light positions and colors.

Lights

It's possible to enable up to 3 different types of lights in the scene: directional, point and spot lights, with their related color, coordinates and angles. In addition to that I've implemented Diffuse(Lambert, Toon) and Specular (Phong, Blinn, Toon Phong, Toon Blinn).

Camera

The camera looks at the cat and, by default, it's set at the coordinates x = 0.0, y = 0.05, z = 0.2. However it's possible to change these parameters and move the "eye" around the object by using the arrow keys to change coordinates x and y, and +/- keys to move along the z axis.

Eyes and Tail Movement

The animation of eyes and tail is performed by the function animate() of main.js and it relies on the assumption that the window.requestAnimationFrame method performs a number of callbacks to it that is usually 60 times per second. Therefore in 60fps the tail and eyes will have 15 frames to move in a fixed direction, 15 frames to return to the centre and again 15+15 frames in the opposite direction, resulting in a 60 frames pendulum movement. A delta equal to 1, as it's set by default, will move the objects of 15 degrees in both directions.

Clockhands Movement

The clockhands rotation (in degrees) is calculated on the current time as follows:

hoursRotationMatrix = rotateZ( -(hour + minutes/60) * 2*Math.PI/12 );

minutesRotationMatrix = rotateZ( -minutes * 2*Math.PI/60 );

where hour is a number between 0 and 11 while minutes varies from 0 to 59. For a better result the hours clockhand's rotation is also influenced by the number of elapsed minutes.

Building and Deploying the project

The last version of the project is available at this GitHub Page but can also be build offline by cloning this repository and running a webserver (e.g. Apache) in the same folder.

Screenshots

Fig. 1 - a single white direct light with Lambert diffuse and Phong Specular. Fig. 2 - a yellow direct light with Toon diffuse and warmer yellow Phong Specular. Fig. 3 - a yellow direct light and a red point light with Toon diffuse and Phong Specular. Fig. 4 - in addition to the previous two lights, a blue spot light with Toon diffuse and Phong Specular.

About

πŸ‘Ύ Computer Graphics course project at Politecnico di Milano (2020)

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Computer Graphics 2020, Course Project

Politecnico di Milano - MSc in Computer Science and Engineering

Project Description

The aim of this project was to develop a WebGL application and associated OpenGL shaders that will render a 3D model of Cat Wall Watch like the one below from a frame of Back to the Future.

Implementation

The application has been written in JavaScript and GLSL and consists of different 3D .obj files with the requirement that the final implementation should show the current time and the movement of the cat's eyes and tail needs to be in the same direction, as the real clock does.

The final result is:

Textures

Most of the components of the watch use two kinds of textures: a normal color texture and a normal map texture that encodes information about normal vectors for each internal point of a triangle. Because of the tangent space encoding of this values in the normal map, the fragment shader will perform an on-the-fly computation of geometrical normals to obtain the tangent and bitangent vectors. This dynamic computation can be enabled in the UI control "Compute geometrical normals" and is not enabled by default because using the normal vector direction stored with the geometry results in a better rendering.

UI Controls

In addition to a simple implementation of the cat watch I've also implemented an interface to control the lights inside the scene, with the related diffuse and specular effects. This UI communicates directly with the GLSL program of each 3D component setting the current option, light positions and colors.

Lights

It's possible to enable up to 3 different types of lights in the scene: directional, point and spot lights, with their related color, coordinates and angles. In addition to that I've implemented Diffuse(Lambert, Toon) and Specular (Phong, Blinn, Toon Phong, Toon Blinn).

Camera

The camera looks at the cat and, by default, it's set at the coordinates x = 0.0, y = 0.05, z = 0.2. However it's possible to change these parameters and move the "eye" around the object by using the arrow keys to change coordinates x and y, and +/- keys to move along the z axis.

Eyes and Tail Movement

The animation of eyes and tail is performed by the function animate() of main.js and it relies on the assumption that the window.requestAnimationFrame method performs a number of callbacks to it that is usually 60 times per second. Therefore in 60fps the tail and eyes will have 15 frames to move in a fixed direction, 15 frames to return to the centre and again 15+15 frames in the opposite direction, resulting in a 60 frames pendulum movement. A delta equal to 1, as it's set by default, will move the objects of 15 degrees in both directions.

Clockhands Movement

The clockhands rotation (in degrees) is calculated on the current time as follows:

hoursRotationMatrix = rotateZ( -(hour + minutes/60) * 2*Math.PI/12 );

minutesRotationMatrix = rotateZ( -minutes * 2*Math.PI/60 );

where hour is a number between 0 and 11 while minutes varies from 0 to 59. For a better result the hours clockhand's rotation is also influenced by the number of elapsed minutes.

Building and Deploying the project

The last version of the project is available at this GitHub Page but can also be build offline by cloning this repository and running a webserver (e.g. Apache) in the same folder.

Screenshots

Fig. 1 - a single white direct light with Lambert diffuse and Phong Specular. Fig. 2 - a yellow direct light with Toon diffuse and warmer yellow Phong Specular. Fig. 3 - a yellow direct light and a red point light with Toon diffuse and Phong Specular. Fig. 4 - in addition to the previous two lights, a blue spot light with Toon diffuse and Phong Specular.

About

πŸ‘Ύ Computer Graphics course project at Politecnico di Milano (2020)

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Computer Graphics 2020, Course Project

Politecnico di Milano - MSc in Computer Science and Engineering

Project Description

The aim of this project was to develop a WebGL application and associated OpenGL shaders that will render a 3D model of Cat Wall Watch like the one below from a frame of Back to the Future.

Implementation

The application has been written in JavaScript and GLSL and consists of different 3D .obj files with the requirement that the final implementation should show the current time and the movement of the cat's eyes and tail needs to be in the same direction, as the real clock does.

The final result is:

Textures

Most of the components of the watch use two kinds of textures: a normal color texture and a normal map texture that encodes information about normal vectors for each internal point of a triangle. Because of the tangent space encoding of this values in the normal map, the fragment shader will perform an on-the-fly computation of geometrical normals to obtain the tangent and bitangent vectors. This dynamic computation can be enabled in the UI control "Compute geometrical normals" and is not enabled by default because using the normal vector direction stored with the geometry results in a better rendering.

UI Controls

In addition to a simple implementation of the cat watch I've also implemented an interface to control the lights inside the scene, with the related diffuse and specular effects. This UI communicates directly with the GLSL program of each 3D component setting the current option, light positions and colors.

Lights

It's possible to enable up to 3 different types of lights in the scene: directional, point and spot lights, with their related color, coordinates and angles. In addition to that I've implemented Diffuse(Lambert, Toon) and Specular (Phong, Blinn, Toon Phong, Toon Blinn).

Camera

The camera looks at the cat and, by default, it's set at the coordinates x = 0.0, y = 0.05, z = 0.2. However it's possible to change these parameters and move the "eye" around the object by using the arrow keys to change coordinates x and y, and +/- keys to move along the z axis.

Eyes and Tail Movement

The animation of eyes and tail is performed by the function animate() of main.js and it relies on the assumption that the window.requestAnimationFrame method performs a number of callbacks to it that is usually 60 times per second. Therefore in 60fps the tail and eyes will have 15 frames to move in a fixed direction, 15 frames to return to the centre and again 15+15 frames in the opposite direction, resulting in a 60 frames pendulum movement. A delta equal to 1, as it's set by default, will move the objects of 15 degrees in both directions.

Clockhands Movement

The clockhands rotation (in degrees) is calculated on the current time as follows:

hoursRotationMatrix = rotateZ( -(hour + minutes/60) * 2*Math.PI/12 );

minutesRotationMatrix = rotateZ( -minutes * 2*Math.PI/60 );

where hour is a number between 0 and 11 while minutes varies from 0 to 59. For a better result the hours clockhand's rotation is also influenced by the number of elapsed minutes.

Building and Deploying the project

The last version of the project is available at this GitHub Page but can also be build offline by cloning this repository and running a webserver (e.g. Apache) in the same folder.

Screenshots

Fig. 1 - a single white direct light with Lambert diffuse and Phong Specular. Fig. 2 - a yellow direct light with Toon diffuse and warmer yellow Phong Specular. Fig. 3 - a yellow direct light and a red point light with Toon diffuse and Phong Specular. Fig. 4 - in addition to the previous two lights, a blue spot light with Toon diffuse and Phong Specular.

About

πŸ‘Ύ Computer Graphics course project at Politecnico di Milano (2020)

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages