<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Synthetic data generation journey]]></title><description><![CDATA[Synthetic data generation journey]]></description><link>https://data-generation.hashnode.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1593680282896/kNC7E8IR4.png</url><title>Synthetic data generation journey</title><link>https://data-generation.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 14:19:15 GMT</lastBuildDate><atom:link href="https://data-generation.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building a Reusable WebGPU & Rust Engine: Part 2 — Loading Custom Geometry & WGSL Shaders]]></title><description><![CDATA[In Part 1, we talked about the CPU event loop and established our foundational wgpu state. Now, we expand our engine to load 3D geometry (.obj files) from disk and feed it through a custom WGSL Shader]]></description><link>https://data-generation.hashnode.dev/building-a-reusable-webgpu-rust-engine-part-2-loading-custom-geometry-wgsl-shaders</link><guid isPermaLink="true">https://data-generation.hashnode.dev/building-a-reusable-webgpu-rust-engine-part-2-loading-custom-geometry-wgsl-shaders</guid><dc:creator><![CDATA[J]]></dc:creator><pubDate>Fri, 09 Oct 2026 05:40:42 GMT</pubDate><content:encoded><![CDATA[<p>In Part 1, we talked about the CPU event loop and established our foundational wgpu state. Now, we expand our engine to load 3D geometry (.obj files) from disk and feed it through a custom WGSL Shader Pipeline.<br /><a href="https://hashnode.com/edit/cmuwp4t7j000106nu1vau2qjt">old-post link</a></p>
<h2><strong>Writing WGSL Shaders</strong></h2>
<p><strong>Shaders</strong> are the small, highly parallel programs that run directly on the GPU to render 3D geometry and color pixels.</p>
<p>In wgpu, we primarily work with two types of shaders:</p>
<ul>
<li><p><strong>Vertex Shader</strong> (<a href="https://dev.to/vertex">@vertex</a>): Processes incoming vertex positions and attributes. Its primary job is converting 3D coordinates into Clip Space coordinates.(homogenous coordinates used by the GPU rasterizer)</p>
</li>
<li><p><strong>Fragment Shader</strong> (@fragment): Runs once for every pixel (or fragment) covered by a primitive (like a triangle) to determine its output color.<br />We will go back to this part in short furture! it’s very useful process.</p>
</li>
</ul>
<p>(Note: traditional APIs had geometry shaders, WebGPU omits them to ensure consistent cross-platform performance.)</p>
<p>When loading external 3D models (like an .obj file), here I pass three core vertex attributes to the vertex shader:</p>
<ol>
<li><p>Position: The 3D spatial coordinates [x, y, z].</p>
</li>
<li><p>Texture Coordinates (UV): Mappings used to align 2D textures onto 3D surfaces.</p>
</li>
<li><p>Normals: Surface direction vectors, essential for calculating real-time lighting in the fragment shader.</p>
</li>
</ol>
<hr />
<h2><strong>Preparing Memory Layouts &amp; CPU-to-GPU Buffers</strong></h2>
<p>To pass .obj model data from the CPU to GPU memory, we establish two key data structures:</p>
<p><strong>1, Vertex custom data struct (wgpu::VertexBufferLayout &amp; wgpu::VertexAttribute):</strong></p>
<ul>
<li><p><code>position — [f32; 3]</code></p>
</li>
<li><p><code>tex_coords — [f32; 2]</code></p>
</li>
<li><p><code>normal — [f32; 3]</code></p>
</li>
</ul>
<p>Defines how memory is ordered inside the vertex buffer. Using wgpu::VertexAttribute, we specify memory offsets for each field (Position, UV, Normal) so the GPU knows exactly where each attribute begins in raw binary data.</p>
<p><strong>2, Mesh custom data struct (CPU Side):</strong></p>
<p>Once the .obj file is loaded into your Vertex structs, you upload them to the GPU. You create a Mesh struct to hold onto those GPU handles:</p>
<ul>
<li><p>Vertex Buffer: Stores the array of packed vertex data.</p>
</li>
<li><p>Index Buffer: Stores the vertex indices, allowing triangles to reuse shared vertices to save GPU memory.</p>
</li>
<li><p>Index Count (indices.len()): Tracks the total element count required by render_pass.draw_indexed().</p>
</li>
</ul>
<p><strong>3. Connecting Everything in the Render Pipeline</strong></p>
<img src="https://cdn.hashnode.com/uploads/covers/6ab53a7058d1a9925b496a70/1faffbf7-feae-4dec-9325-8fdfda2c9cd6.png" alt="" style="display:block;margin:0 auto" />

<ol>
<li><p>Load Assets: Read the .obj file into a Mesh struct and compile the WGSL shader code using device.create_shader_module().</p>
</li>
<li><p>Build the <code>RenderPipeline</code>: Create the pipeline via <code>device.create_render_pipeline()</code>, setting the <code>@vertex</code> and <code>@fragment</code> entry points. Pass description <code>Vertex::desc()</code> into the pipeline setup so <code>wgpu render_pipeline</code> knows how to map the vertex buffer straight into shader inputs.</p>
</li>
<li><p>Execute during Render: Store both the <code>RenderPipeline</code> and Mesh inside your State. Inside <code>render()</code> loop, bind the pipeline and draw the mesh buffers</p>
</li>
</ol>
<img src="https://cdn.hashnode.com/uploads/covers/6ab53a7058d1a9925b496a70/97d503d2-50f6-4a6c-ac26-027dfc559e5b.png" alt="" style="display:block;margin:0 auto" />

<p>Just like in Part 1, in the end the exciting result: we can load a 3D box into the scene using our custom shader—even without setting up a camera yet!</p>
<p>--------------------------------------------------------------------------------<br />Thanks for reading, here is my Industrial Rust Projects:<br />Building industrial 3D vision or AI pipelines? Check out <a href="https://5940734191807.gumroad.com/l/eqxti">ForgeOptics on Gumroad</a> for high-performance Rust ray-tracing, physical sensor noise, and synthetic dataset generation.</p>
]]></content:encoded></item><item><title><![CDATA[Building a Reusable WebGPU & Rust Engine: Part 1 — Windowing & Pipeline Architecture]]></title><description><![CDATA[Building a modular render engine or simulator template requires a clean separation between CPU-bound application logic and GPU-driven rendering pipelines.
In this post, I will track the process of bui]]></description><link>https://data-generation.hashnode.dev/building-a-reusable-webgpu-rust-engine-part-1-windowing-pipeline-architecture</link><guid isPermaLink="true">https://data-generation.hashnode.dev/building-a-reusable-webgpu-rust-engine-part-1-windowing-pipeline-architecture</guid><category><![CDATA[AI]]></category><category><![CDATA[Cg]]></category><category><![CDATA[Rust]]></category><category><![CDATA[Rendering]]></category><dc:creator><![CDATA[J]]></dc:creator><pubDate>Tue, 06 Oct 2026 13:10:12 GMT</pubDate><content:encoded><![CDATA[<p>Building a modular render engine or simulator template requires a clean separation between CPU-bound application logic and GPU-driven rendering pipelines.</p>
<p>In this post, I will track the process of building a lightweight, reusable render template in Rust using wgpu and winit.</p>
<p>Nowadays, we can utilize AI to handle implementation details, but as creators, we still need to review and master the architecture from a high level. Understanding the top-level structure helps us learn faster, validate the AI's output, and ensure our systems remain robust and maintainable.</p>
<ol>
<li>Project Setup &amp; Dependencies Initialize a new Rust project and add wgpu (for graphics API abstraction) and winit (for cross-platform window management):</li>
</ol>
<p>additionally: pollster: A minimal async executor used to block on GPU async calls during initialization. 2, Host Application Setup (CPU Side) Before setting up wgpu, we build the host CPU process. This handles input, windowing, network requests, and overall application state separately from the renderer.</p>
<p>The event loop is the key structure on the CPU side. It drives the entire application lifecycle and coordinates user interactions, window events, and graphics updates.</p>
<pre><code class="language-c">       +------------------------------------+
       |         winit::EventLoop           |
       +------------------------------------+
                         |
                         v
  +----------------------------------------------+
  |  Event Handling (Main Loop)                  |
  |                                              |
  |  * WindowEvent::CloseRequested -&gt; Exit App   |
  |  * WindowEvent::Resized        -&gt; Resize GPU |
  |  * Other Events                -&gt; Ignore     |
  +----------------------------------------------+
</code></pre>
<ol>
<li>GPU Pipeline Architecture (wgpu) Once the window exists, we initialize the wgpu state. Rather than focusing on syntax, think of the GPU initialization as connecting five key structural primitives:</li>
</ol>
<pre><code class="language-c">+------------------------------------------------------------+
|                              wgpu State                               |
|                                                                       |
|  [ Surface ]&lt;---&gt;  Bridge between the OS window and the GPU         
|  [ Device ]&lt;---&gt;  Virtual GPU interface 
|  [ Queue ]&lt;---&gt; Command channel to physical hardware|
|  [ Config ]&lt;---&gt;  Surface settings|
|  [ Size ]&lt;---&gt;  Tracks viewport bounds for dynamic resizing      |
+------------------------------------------------------------+
</code></pre>
<p>As your engine grows, this structure expands to hold high-level rendering primitives like , , and .</p>
<p>The Core Execution Loop Once initialized, the GPU pipeline operates around two primary execution routines:</p>
<p>[resize]</p>
<p>Fired whenever the window dimensions change. It updates the and reconfigures the so the rendering context stays locked to the window bounds without distortion.</p>
<p>[render]</p>
<p>The per-frame execution sequence: Acquire Frame: Request the current frame buffer (output) and construct its texture view (view). Encode Commands: Open a command encoder and launch a scoped Render Pass. Manage Ownership: Crucially, the render pass must finish and drop its resource locks within its localized block {} before submission. Submit &amp; Present: Pass the encoded commands to the for execution on hardware, then display (present) the output frame. After that, the "event handler" will connect "AboutToWait" and "RedrawRequested", invokes the [render] sequence</p>
<p>Finally showing the exciting result (a colored canvas- yeah!!!):</p>
<img src="https://cdn.hashnode.com/uploads/covers/6ab53a7058d1a9925b496a70/0d16c526-545d-4da5-aa39-edc4eda28e61.png" alt="" style="display:block;margin:0 auto" />]]></content:encoded></item><item><title><![CDATA[Why Vision Models Fail on Glass: A Synthetic Benchmark for Transparent Objects]]></title><description><![CDATA[Transparent objects like glass, acrylic, and water are the ultimate blind spots for modern Computer Vision models.
Whether you are training Depth Estimation, 3D Reconstruction (NeRFs/3DGS), Segment An]]></description><link>https://data-generation.hashnode.dev/why-vision-models-fail-on-glass-a-synthetic-benchmark-for-transparent-objects</link><guid isPermaLink="true">https://data-generation.hashnode.dev/why-vision-models-fail-on-glass-a-synthetic-benchmark-for-transparent-objects</guid><dc:creator><![CDATA[J]]></dc:creator><pubDate>Fri, 25 Sep 2026 15:17:43 GMT</pubDate><content:encoded><![CDATA[<img src="https://cdn.hashnode.com/uploads/covers/6ab53a7058d1a9925b496a70/def5869f-0266-469a-bab8-013866be82a9.png" alt="" style="display:block;margin:0 auto" />

  
<p>Transparent objects like glass, acrylic, and water are the ultimate blind spots for modern Computer Vision models.</p>
<p>Whether you are training Depth Estimation, 3D Reconstruction (NeRFs/3DGS), Segment Anything (SAM), or Object Detection models, transparent surfaces ruin feature matching and depth sensors. RGB light passes right through, reflections distort geometries, and standard datasets completely lack labeled ground truth for transparency.</p>
<p>To solve this, we built a synthetic benchmark dataset tailored specifically for training and evaluating vision models on transparent materials.</p>
<hr />
<h2>🛑 Why Traditional CV Pipelines Break on Glass</h2>
<ol>
<li><p><strong>Depth Sensors Fail:</strong> ToF (Time-of-Flight) and active stereo depth sensors pass through or scatter when hitting optical-grade glass.</p>
</li>
<li><p><strong>Refraction &amp; Reflection:</strong> Standard RGB feature extractors detect background features <em>behind</em> the glass or virtual highlights <em>on</em> the surface—leading to incorrect bounding boxes and false segmentations.</p>
</li>
<li><p><strong>Lack of Ground Truth Data:</strong> Capturing real-world paired RGB-D images of transparent objects with pixel-accurate normal maps and segmentation masks is near impossible manually.</p>
</li>
</ol>
<hr />
<h2>🎬 Synthetic Data Generation Benchmark (Demo)</h2>
<p>Watch our synthetic pipeline render optical-grade reflections, precise refraction passes, and exact ground-truth depth maps in real-time:<br />%[<a href="https://www.youtube.com/watch?v=aKlNZl4Qsro%5C%5D">https://www.youtube.com/watch?v=aKlNZl4Qsro\]</a></p>
<hr />
<h2>📊 What's Inside the Benchmark Package</h2>
<p>To help researchers and engineers train robust models, we synthesized a specialized 3D dataset focused entirely on glass physics and transparent geometries:</p>
<ul>
<li><p><strong>Clean Ground-Truth Annotations:</strong> Instant access to aligned RGB images, 2D Bounding Boxes (BBox), and precise Instance Segmentation masks.</p>
</li>
<li><p><strong>Physics-Based Refraction:</strong> Varied Index of Refraction (IOR) materials—from glass bottles and windows to lab glassware.</p>
</li>
<li><p><strong>Complex Lighting Environments:</strong> High dynamic range (HDR) lighting variations to teach models edge detection under extreme specular reflections.</p>
</li>
<li><p><strong>Ready for Model Training:</strong> Pre-formatted annotations ready for YOLO, SAM, and object detection pipelines.</p>
</li>
</ul>
<hr />
<h2>📦 Get the Synthetic Glass Dataset Package</h2>
<p>Ready to benchmark your depth estimation models or fine-tune your vision architecture for hard transparent objects?</p>
<p>👉 <a href="INSERT_YOUR_GUMROAD_LINK_HERE"><strong>Download the Glass Benchmark Package on</strong></a><br /><a href="https://5940734191807.gumroad.com/l/vjlhry"><strong>PACKAGE1</strong></a><br /><a href="https://5940734191807.gumroad.com/l/yafpul"><strong>PACKAGE2</strong></a></p>
<hr />
<h3>Discussion</h3>
<p>How are you currently handling transparent object segmentation in your vision pipeline? Are you relying on multi-modal sensors, or fine-tuning vision foundation models? Let's discuss in the comments below!</p>
]]></content:encoded></item></channel></rss>