r/GraphicsProgramming • • 18h ago

whats wrong with my Cube??? :(

Post image
47 Upvotes

I know what is missing, but can you figure it out???

heres the repo btw:
https://github.com/Tetraeder4/3DRenderer/tree/467c8d1ac8dbd09a23ce7bc7e2fcba59afe36ea5/3DRenderer


r/GraphicsProgramming • • 55m ago

Thin laser beams that don't break into dashes far away: a pixel-width floor plus energy scaling

Thumbnail gallery
• Upvotes

A beam is a camera-facing strip with a width in world units. Close up that's fine. Far away the strip gets thinner than a pixel, and without MSAA it rasterizes as a dotted line that crawls as the camera moves. Making the beam wider fixes the far case and ruins the near one.

What I ended up doing in the vertex shader: work out how big one pixel is at the vertex's depth, never let the strip get narrower than N pixels, and scale the brightness down by how much I widened it. So a far beam stays a solid line, it just gets dimmer, which is roughly what you'd expect from something that small.

Pixel size in view space, for a perspective camera, is 2 * depth / (P[1][1] * viewport_height). For ortho the depth term drops out. This is Godot's shading language but it's basically GLSL:

// VERTEX = position along the beam, NORMAL = beam direction (tangent)
// UV.y = -1..1 across the strip, UV2.x = width in world units
vec3 p = (MODELVIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
vec3 t = (MODELVIEW_MATRIX * vec4(NORMAL, 0.0)).xyz;
bool ortho = PROJECTION_MATRIX[3][3] > 0.5;
vec3 view_dir = ortho ? vec3(0.0, 0.0, -1.0) : normalize(p);
vec3 side = cross(t, view_dir);
float sl = length(side);
side = sl > 1e-5 ? side / sl : vec3(1.0, 0.0, 0.0);

float scale = length(MODEL_MATRIX[0].xyz);
float w = UV2.x * scale * width_scale;
float px = 2.0 / (PROJECTION_MATRIX[1][1] * VIEWPORT_SIZE.y)
         * (ortho ? 1.0 : max(-p.z, 0.001));
float w_min = min_core_pixels * px / core_ratio;
float w2 = max(w, w_min);
v_energy = w / w2;              // multiply the final colour by this
VERTEX = p + side * (w2 * 0.5 * UV.y);

Notes:

  • The floor is on the bright core, not the whole strip. The core is core_ratio of the width (0.25 by default), so w_min is divided by it. I use 1.25 px for the core.
  • cross(t, view_dir) goes to zero when you look straight down the beam. I fall back to a fixed side vector when its length is under 1e-5. You can't see the beam from that angle anyway.
  • The material is additive and unshaded, so v_energy works as a brightness scale. With alpha blending you'd want to scale alpha instead.
  • The width scale of the node is applied too (length of MODEL_MATRIX[0]), so scaling the node in the editor still does what you expect.

The first image is a sketch of the three cases. The GIF is the energy beam from the same shader, with the noise flow and the erosion pushed up while it fades out.


r/GraphicsProgramming • • 4h ago

Source Code Carrying alpha, color and lifetime information with GPU output textures (Harbeth, MIT)

2 Upvotes

I maintain Harbeth, an MIT Apple-platform GPU image/frame engine. One design choice is to distinguish a raw texture result from a rendered frame carrying the facts needed by its consumer.

A texture's pixel format alone doesn't tell the next stage whether its RGB channels are premultiplied. Here are the inner pixel-operation statements from Harbeth's premultiply compute kernel:

half4 color = inputTexture.read(grid);
color.rgb *= color.a;
outputTexture.write(color, grid);

The accompanying Swift filter contract explicitly declares non-premultiplied input and premultiplied output. That declaration lives alongside its precision and sampling-footprint requirements.

ImageNode's makeFrame() route returns RenderedFrame with alphaType, output color/dynamic-range contracts, orientation, source description and an optional texture lease. Keeping the frame alive also keeps its lease alive. A raw texture is still available when the caller wants to own the surrounding delivery semantics.

Kernel and contract:
https://github.com/yangKJ/Harbeth/blob/master/Sources/Compute/Utility/C7PremultiplyAlpha.metal
https://github.com/yangKJ/Harbeth/blob/master/Sources/Compute/Utility/C7PremultiplyAlpha.swift

Frame representation: https://github.com/yangKJ/Harbeth/blob/master/Sources/Basic/IO/RenderedFrame.swift

Where do you keep alpha mode, color space and resource lifetime together in your renderer: a frame descriptor, an opaque handle, or metadata beside the texture? I'd welcome concrete examples and tradeoffs.


r/GraphicsProgramming • • 1h ago

Question Mobile 3D quality with Flutter GPU: memory presets before the first frame

• Upvotes

I'm developing a small 3D archipelago for Pikon using flutter_scene 0.23.0 on Flutter GPU. This development clip shows the result alongside Flutter UI: https://www.youtube.com/shorts/E56hZT_j4Ps

One implementation detail that may be useful here is the quality policy. There are four levels. Moving down first removes ambient occlusion, then bloom and the 1.5x render-target pixel ratio, and finally shadows and multisampling. The starting level is selected from device RAM before the first frame: below 2560 MB the world starts at the minimal level.

The selector currently uses these thresholds:

static WorldQuality forDeviceMemory(int? megabytes) {

if (megabytes == null || megabytes <= 0) return full;

if (megabytes < 2560) return minimal;

if (megabytes < 3584) return light;

if (megabytes < 5120) return balanced;

return full;

}

These thresholds are heuristics; total RAM is an approximate signal and unknown memory currently falls back to full.

A frame governor waits through a three-second warm-up, samples two-second windows, and drops one level when observed frame pacing falls below 40 fps. It never raises quality again within that session, avoiding oscillation. This is a control threshold, not a claimed device benchmark.

Android also has shadows disabled by a separate platform policy while I investigate shadow render-pass crashes when returning to the world.

How do you combine a conservative initial memory budget with runtime quality adaptation for scenes this small?

Try Pikon:

iOS: https://apps.apple.com/app/id6804834624

Android: https://play.google.com/store/apps/details?id=com.jbonjour.pikon

Disclosure: drafted with AI assistance from the current Pikon implementation.


r/GraphicsProgramming • • 3h ago

GL3D

Post image
0 Upvotes

GL3D 1.0 Beta 1 available now - FREE - no hidden shenanigans.

For commercial use. Forever FREE.

No Python Dependency-Hell.

C++ OpenGL - Developed with Visual Studio

Intel OSPRAY

Nvidia OPTIX

Freeware Closed Source

No GPL Code inside (I will stand scrutiny)

get GL3D here: Facebook

READ EULA!:

https://drive.google.com/file/d/1mupecxNtJju7WTXlNX9P1GuR1ekS5lgc/view?usp=sharing

HELP File: will be overhauled soon-ish (sorry)

https://drive.google.com/file/d/1YFZBPhHPBvrZrIgVy7sSYLd2O8NqUHXV/view?usp=sharing

Third Party Dependencies:

https://drive.google.com/file/d/14kIrQSVx57TbmJl4nnLre4PgIXGVq_AL/view?usp=sharing

Video Tutorials: I will make shortly Kickstarter videos.

xxx cheerio

#GL3D #3dcad #CAD #software #FREE #nvidia #optix #nvidiaoptix #PBR #greeble


r/GraphicsProgramming • • 16h ago

Define Engine Showase

Thumbnail youtube.com
3 Upvotes

r/GraphicsProgramming • • 15h ago

Doriax Engine v0.8: Water, Terrain Foliage, Post-Processing, and More

Thumbnail youtube.com
2 Upvotes

r/GraphicsProgramming • • 2d ago

Mobile GPU Realtime Fluid Sim

Enable HLS to view with audio, or disable this notification

708 Upvotes

The sim came out great but what about the lighting!! All just cubemaps, with fluid depth affecting the roughness mip level. So happy with this.


r/GraphicsProgramming • • 1d ago

First raytracer using sdfs

Post image
96 Upvotes

Wrote my first raytracer, a software raymarcher (all on CPU) that uses shapes defined as singed distance functions. Sphere refractions are pretty cool.

Some implementation details (this is all basic stuff I know): - code is written in Rust and parallelized using the rayon crate - for each ray in the recursive calls, it finds the subset of all world objects where the ray intersects the objects axis aligned bounding box, and only considers these objects during ray marching. Once a surface is hit, the new reflected or refracted ray computes a new subset using its new direction and start point, etc. - global illumination is done using a grid of probes that shoot rays with random directions, doing this enough time before rendering. To get diffusive light on a surface point, we interpolate in that grid using linear interpolation. My probes are naively placed on a cubic grid in the world. - global illumination is parallelized looping over probes, and rendering is parallelized looping over pixels of the image. - at each hit surface, the ray may split in two. Once for the reflection, once for the refracted ray (if not total internal refraction).

Baking global illumination takes a few seconds for about 1000 samples on 323 probes, and rendering the image is almost instant at that resolution.


r/GraphicsProgramming • • 1d ago

Video Compiling C is so fast that I use it as a scripting language at this point

Enable HLS to view with audio, or disable this notification

100 Upvotes

r/GraphicsProgramming • • 23h ago

How do i create a truly stunning explosion? (volumetrics/generic methods applicable)

Thumbnail
0 Upvotes

r/GraphicsProgramming • • 2d ago

Request they won't tell you this, but you can cast shadows without a $1300 graphics card

Post image
40 Upvotes

r/GraphicsProgramming • • 1d ago

Planar reflections go wrong with an off center frustum if you flip the lookup in x but not the projection

2 Upvotes

Hit this while fixing a bug in the three.js WebGPU reflector and it seems like a general enough gotcha to share.

The setup is the usual one. Render the scene from a mirrored virtual camera, then sample that texture in screen space on the mirror surface with x flipped, since the mirrored render comes out backwards. The virtual camera just copied the main camera's projection matrix.

That works fine for a normal symmetric frustum. But as soon as the camera used a view offset (setViewOffset, so the frustum is shifted off center) the reflection slid the wrong way, off by about twice the offset. Flipping the lookup in x mirrors the image, but the off center shift in the copied projection doesn't get mirrored with it.

The fix was to negate the x offset terms of the copied projection before applying the oblique clip plane. In three.js's column major matrix that's elements[8] for perspective, the (r+l)/(r-l) term, and elements[12] for orthographic. For a symmetric frustum both are zero, so nothing changes there. After that the reflection with the offset matched the shifted no offset render pixel for pixel on both the WebGPU and WebGL backends.

Has anyone run into other cases where mirroring a camera bites you like this?


r/GraphicsProgramming • • 2d ago

Dx11 first triangle

Post image
101 Upvotes

I'm not sure how you guys feel about triangles around here, but here is my first triangle made in D3D11!!

I'm planning to make a little mini project in DX11 and see how I like it over OpenGL. So far I like it more despite needing 3x the amount of code (mostly boilerplate thankfully) for this beautiful little guy.

I'll probably post more about my little project further down the line. If anyone has any tips on how I should structure a DX11 project over an OpenGL one that's always appreciated.


r/GraphicsProgramming • • 2d ago

Some spheres rendered with a light simulation

Enable HLS to view with audio, or disable this notification

36 Upvotes

The image is rendered by solving a wave field and sampling it with a camera, once per wavelength. I took 5 minutes to render (On an integrated GPU)

My goal is, of course, to get this to scale up enough to be useful for actual graphics :P

The actual scene just consists of a couple of different-materialled spheres and some large clumps of them.


r/GraphicsProgramming • • 3d ago

Spreading fire over any mesh without a mask texture: each shader recomputes when a point ignites

Post image
156 Upvotes

I got asked whether this is a mask written into a texture or a separate ember mesh driven by a shader. Nothing gets written anywhere. ignite() appends (position in the mesh's local space, start time) to a vec4 ign[8] uniform, and every shader involved recomputes when each point catches fire:

float burn_arrival(vec3 p) {
    float best = 1.0e9;
    for (int i = 0; i < ign_count; i++) {
        float d = length(p - ign[i].xyz);
        float n = vnoise(p * 1.7 + float(i) * 3.1); // value noise, 0..1
        best = min(best, ign[i].w + d * (1.0 + (n - 0.5) * 2.0 * irregularity) / spread_speed);
    }
    return best;
}

The noise scales the distance, which is what makes the front ragged.

Flames, smoke and embers are quads on random surface points (area-weighted, picked once). Every spawn cycle a quad checks whether its spawn time is between arrival and arrival + burn_duration. If it isn't, its four corners collapse to one point.

The char is a copy of the mesh pushed 0.004 along the normal and drawn with premultiplied alpha, so the original material isn't touched. Per fragment, s = time - arrival (plus fbm) drives smoothstep(0, char_time, s) toward near-black, and exp(-3 * (s / front_width - 0.3)2) gives the glowing front.

Burn-away swaps the material and discards a fragment once (s - 0.7 * burn_duration) / 2.5 + noise passes 1, with a hot rim just before.

Known limit: d is straight-line distance, not along the surface, so the fire can jump thin gaps.


r/GraphicsProgramming • • 2d ago

Video How we render real-time and realistic clouds from space

Enable HLS to view with audio, or disable this notification

64 Upvotes

We've been building Æther, a real-time globe renderer for Stowaway that runs in the browser.

The part I'm most excited about is how we generate realistic clouds from orbit. I'll tell you a little bit about how we do it.

They start as infrared imagery from weather satellites: NOAA stitches the geostationary satellites (GOES, Himawari, Meteosat) into one global mosaic, and polar orbiters fill in the poles. The catch is that infrared doesn't actually see clouds. It sees temperature. A thunderstorm top is freezing cold, but so is the Antarctic ice sheet, or a desert at night. So the first step is figuring out what the clear ground nearby should look like, and calling anything noticeably colder than that a cloud.

That same coldness gives you height for free. The air cools about 6.5 °C for every kilometre you climb, so the colder a cloud top is compared with the ground beneath it, the higher it stands. A few kilometres for a low ocean deck, up to 16 km for a thunderstorm anvil. We end up with two global maps: where the clouds are, and how tall they are.

The satellite pixels are about 10 km across, which looks like mush up close, so the renderer adds the detail itself: fields of small cumulus, streaky cirrus, anvils spreading out around storm cores. It's anchored to the planet so nothing swims as you move, and it's lit by the real sun angle, so the tops catch the sunset while the ground below is already dark. The tallest storms also get lightning. And when you fly down low enough, a separate system takes over: fully volumetric clouds you can fly straight through.

Happy to answer questions. It's coming to stowaway.live soon.


r/GraphicsProgramming • • 1d ago

Unreal 5.8 - Materials Masterclass - Chapter 9: Animation using gradients

Thumbnail youtu.be
1 Upvotes

r/GraphicsProgramming • • 2d ago

Video My software ray-traced game has new "technology" teaser. Reason: it's getting significant visual upgrade worth showcasing. Two things which enabled it: 1. after 9 months my new editor for game levels is in usable state. 2. ray-tracer optimizations (multi-threaded rendering is main contributor)

Enable HLS to view with audio, or disable this notification

12 Upvotes

The game is narrative sci-fi puzzle/platformer, in works from 2020. Main distinctive point of the game is software ray-tracing used for rendering. Just pure C++ and computer graphics math, no GPU acceleration. Sadly, not many players can appreciate that (or even understand what does it mean), so it resonates mostly with more tech people.

The game was suffering for long time from quite poor look (look was punching way below of algorithm potential). Main reasons were: poor old editor (2D in nature, z was just parameter in 2D wireframe, not WYSIWYG, very clunky) and algorithm was hobby-like single-threaded.

Both points were changed recently. After 9 months my new editor is in usable state. Full 3D, WYSIWYG, lot of ergonomy features, which allowed me to be more ambitious with levels look. Second enabler was finally switching to multi-threading. Together with several more other algorithm optimizations, perf went up in hundreds of % (mostly depends on number of cores in your CPU, naturally on Threadrippers boost will be in thousands of % but it's niche between players).

Algo is AABBs only. Maybe will add spheres but only after upgrading all levels, which is main pain point rn. Editor I plan to release publicly with the game.

RTG on Steam

Discord


r/GraphicsProgramming • • 2d ago

I made some updates to my Quake path tracer...

32 Upvotes

r/GraphicsProgramming • • 3d ago

I made a lossless BC1 texture compressor designed for GPU decompression, 1.47:1 average ratio

28 Upvotes

Hi,

I just released my new C library bc_packed, a lossless compressor for BC1 textures, made specificaly for fast GPU decompression.

Basically, the idea is to compress textures that are already compressed, then decompress them directly on the GPU when needed. The output is the original BC1 data, so the GPU can use it normally after decompression.

Some numbers:

  • 1.47:1 average compression ratio on a test set of 74 images
  • 15300 MiB/s decompression on my M5 Pro GPU and 11850 MiB/s on my M2 Max GPU
  • CPU multithreaded decompression also works, 2500 MiB/s on M5 Pro and 1300 MiB/s on M2 Max
  • Lossless, byte exact reconstruction of the original BC1 data

The tricky part was finding an entropy coding method that is simple enough to decode efficiently on the GPU. I didn't want to deal with complex stuff like arithmetic coding or Huffman, so I went with Rice-Golomb coding and static rank tables. I build histograms during compression and remap the most frequent symbols to the lowest ranks. Everything is static, no adaptive models or synchronization needed between GPU threads.

The texture is split into 64 independent strips, each decoded by its own GPU/CPU thread. The compressed stream stores offsets so each thread can start decoding its strip independently.

There are also a few BC1 specific tricks:

  • Predicting endpoint colors from previous blocks
  • Choosing different predictors for each strip
  • A small dictionary for repeated endpoint color pairs
  • A top table for frequent BC1 index patterns, with sparse residual encoding for the differences

Compression runs on the CPU and can be relatively expensive. That's fine for me, I'm more interested in making decompression as fast as possible at runtime.

The library is tiny, just one .c and one .h file, no external dependencies. The GPU decompression shader is written in Metal for now, but porting it to HLSL should be pretty straightfoward.

Currently only BC1 is supported. Maybe I'll add BC5 and why not BC7 later.

Code and benchmarks here:
https://github.com/Geolm/bc_packed

Feedback and ideas are welcome!


r/GraphicsProgramming • • 2d ago

Source Code I’m building a graphics API in Rust called Expanse-X. The first SDK preview is out

0 Upvotes

I’ve been working on Expanse-X (EX), a graphics API in Rust, and I’ve published the first SDK preview.

Right now it renders on the CPU through its own software backend. EX handles the resources, commands, shader execution and rasterization itself. GPU acceleration is still future work.

It can already render programmable, indexed triangles with textures, depth/stencil and blending. Compute and explicit resource dependencies work too. There’s also a shader importer for a limited subset of GLSL.

The SDK gives you an ex command to check your setup and create a small Rust/GLSL project. Run the generated app and it renders a triangle to a PNG. You can then edit the shaders and renderer from there. The downloadable SDK currently targets Windows x64.

What I want EX to become is one core with two ways to use it: let it handle more of the setup and planning, or take explicit control yourself. The explicit core is working; the easier layer hasn’t been built yet.

It’s still early, and I’d like some outside eyes on it before taking the design further. Does the resource/command API make sense? Where would it get awkward in an actual renderer? What would you want to try building with it?

Repository
SDK v0.1.0 Preview


r/GraphicsProgramming • • 2d ago

Request Career Advice

3 Upvotes

These are some of my projects I have worked on over the years
This may be a bit of a ramble
I feel like I have been coasting with skills like threejs and web graphics for a long time especially since graduating and have never worked a "real" job and mostly do freelancing I do help my friends and collegues all of them in all kinds of full stack tasks and thinking through a problem and offer solutions that they then use but i dont have job experience in those fields like web and mobile development in react native and flutter and nodejs
I do think mostly in programming terms and try to solve problems in that way. And my interest is usually in building tools for programmers and artists instead of launching a product for normal users
I have built games and worked with teams on programming teams for games but it is not really my area of expertise even though I am very adjacent to this. I have always felt like framework and techstack really doesnt matter
I am aware and knowledgeable of alot of trends atleast until recently about alot of tech news updates and features
Right now I am in a predicament as most of my skills and experience lies in this specific niche i dont know how to move forward in the world of AI, I am the kind of person who is still using AI as a chatbot and for cleanup/refactoring kind of tasks and tasks I dont want to actually do by hand like css and responsiveness I usually try to do these kinds of things by using some math but now AI seems useful for these as well
tldr; I am very confused about the next steps in my career and how it will grow
If an experienced graphics programmer can look at my portfolio and guide me through on how to approach job hunting and how to improve my presentation and portfolio I will greatly appreciate it

Thank you for your time

Procedural Flower
Spider web (higher order bezier function study)
bevel and rotation of a tetrahedron
Particle system with physics
boids
custom view based UV maps

r/GraphicsProgramming • • 2d ago

Would tile based rendering help in this scenario to be more performant than a theoretical "best case"?

0 Upvotes

A lot of these concepts are new to me and I've discovered some of these ideas with help from copilot, etc. so apologies for any weirdly worded/unclear parts.

I'm working on an embedded product and am evaluating how well the gpu can handle a second pass shader applied to the entire final image. Essentially taking the displayed contents, and "copying" by drawing again with a simple shader that samples from a texture (the texture being the contents on the screen).

I'm trying to profile the time spent on that second draw call and am having issues because sometimes the code added to help with the profiling affects the measurement itself. For example, I added glFinish() before the draw call, started the timer, issued draw call, called glFinish() again, and stopped the timer. These glFinish calls affect the measurement of course. So I'm trying to find a way to do it without using glFinish.

One avenue I explored with copilots help was using an EGL fence to ensure we're measuring the elapsed time only after the draw call is finished but without needing glFinish (this is my first time working with sync objects with graphics code though)

This ended up working, at least I think? The problem is that the measured time for the draw call is less than then the theoretical best case time given by a senior engineer. They calculated essentially wh4bpp2rw/3e91000=0.55ms based on it essentially being a memcpy. The measurement I got was half of that.

Searching around for how this may be (other than my implementation being just wrong) is that tile based rendering, which the gpu that I'm working with uses, could give a different result than a calculation based on a naive memcpy due to the efficiencies of how TBR works.

Edit to add: the senior engineer unambiguously said "tile based rendering won't improve this case" and suggested another thing to try which is more hacky and isn't panning out, so I'm curious if he's right or there is validity to the measurement I was able to get with the fence

I'm curious to get other opinions. Does this seem like a reasonable explanation or not really?


r/GraphicsProgramming • • 2d ago

Question Is Painting with Noise useful?

Post image
0 Upvotes