Hone logo
Hone
Problems

Interactive 3D Sphere Renderer in Vue with WebGL

This challenge asks you to build a simple interactive 3D sphere renderer within a Vue component using WebGL. The sphere should be visually appealing, respond to mouse movements to rotate, and have a basic lighting model. This exercise combines front-end framework proficiency (Vue) with low-level graphics programming (WebGL), demonstrating a practical application of both.

Problem Description

You need to create a Vue component that renders a 3D sphere using WebGL. The sphere should be initially centered in the component's canvas and should rotate continuously when the mouse is moved within the component's bounds. The sphere should have a basic diffuse lighting model, with a single directional light source.

Key Requirements:

  • Vue Component: The solution must be a valid Vue component.
  • WebGL Canvas: The component must create and manage a WebGL rendering context within a <canvas> element.
  • Sphere Geometry: The sphere should be rendered using a sufficient number of vertices to appear smooth (e.g., at least 32 segments in each direction).
  • Shaders: You must implement basic vertex and fragment shaders for rendering the sphere. The shaders should handle vertex transformations, lighting, and color.
  • Mouse Interaction: The sphere should rotate around the X and Y axes based on the mouse's position relative to the center of the canvas. The rotation speed should be proportional to the mouse's distance from the center.
  • Lighting: Implement a simple directional light source. The light direction should be fixed (e.g., pointing downwards).
  • Error Handling: Basic error handling for WebGL initialization is expected.

Expected Behavior:

  • The component should render a visually appealing 3D sphere within the canvas.
  • Moving the mouse within the canvas should cause the sphere to rotate smoothly.
  • The sphere should be lit, with visible shading based on the light direction.
  • The component should handle WebGL initialization errors gracefully.

Edge Cases to Consider:

  • Canvas size changes: The component should adapt to different canvas sizes.
  • Browser support: Ensure the code works in modern browsers with WebGL support.
  • Performance: While not a primary focus, avoid excessive calculations that could lead to poor performance.

Examples

Example 1:

Input: Initial mouse position at the center of the canvas. Canvas size: 500x500.
Output: A static, lit sphere centered in the canvas.
Explanation: The sphere is initially not rotating because the mouse is at the center.

Example 2:

Input: Mouse position at (100, 150) on a 500x500 canvas.
Output: The sphere is rotating around the X and Y axes, with the rotation speed proportional to the distance from the center.
Explanation: The mouse position triggers rotation. The further the mouse is from the center, the faster the rotation.

Example 3:

Input: Canvas size changes from 500x500 to 800x600.
Output: The sphere remains centered within the new canvas dimensions, and the rotation behavior remains consistent.
Explanation: The component adapts to the new canvas size, maintaining the sphere's position and rotation.

Constraints

  • Canvas Size: The component should be able to handle canvas sizes ranging from 200x200 to 1000x800 pixels.
  • Shader Complexity: Keep the shaders relatively simple. Focus on demonstrating the core concepts of vertex transformation, lighting, and color. Avoid complex textures or advanced lighting techniques.
  • Performance: The rendering should maintain a frame rate of at least 30 FPS on a reasonably modern computer.
  • Dependencies: You are allowed to use only standard WebGL APIs and Vue.js. No external WebGL libraries are permitted.

Notes

  • Start by setting up the WebGL context and creating the canvas within the Vue component.
  • Consider using a ref to access the canvas element directly.
  • The vertex shader should transform the sphere's vertices into clip space.
  • The fragment shader should calculate the diffuse lighting contribution and apply it to the sphere's color.
  • Use requestAnimationFrame for smooth animation.
  • Think about how to normalize mouse coordinates to a range between -1 and 1 for rotation calculations.
  • Remember to handle WebGL errors appropriately. Check for gl.getError() after WebGL calls.
Loading editor...
typescript