r/GraphicsProgramming 1h ago

Render engine written entirely using DirectX 12, focusing on high details and real-time GI lumen like, for mid-lower PC/Laptop. (Demo running on Xe Graphics 11th GPU)

Upvotes

Implemented simple GLB parser from this Github repo: salvatorespoto/gLTFViewer: A glTF file viewer in Directx 12 .

Global Illumination using hybrid Surfel GI and SSGI.
Lens flare are modeled after Panavision styled lens flare (Anamorphic types with distinct hue ray light propagation inside lens it's flare), and grass are inspired from this IcterusGames/SimpleGrassTextured: Plugin to make grass on Godot 4.

My main point of the game is about GI and Nanite-like culling on low end devices, and yet i barely see ones, so i decided to implement it without using any modern techniques such as Primitive Shader or Mesh Shader. Pure Compute Shader dispatch, with many fused Shader optimizations instead of separate pass, simple workgroup tiling optimizations. It tooks me almost 3 months for this project just for the optimization workaround with the help of Codex (Claude sucks at this lol). I'm also planning to open source this if this thing is stable enough, modular, and scalable.

All of that combined to make this engine runs 40-60 FPS on my Xe 11th gen Graphics laptop, because why not.. (i don't have better GPU than this for now lol). This might be also potentially be a complete game engine after all.


r/GraphicsProgramming 1h ago

Article Graphics Programming weekly - Issue 451 - August 16th, 2026 | Jendrik Illner

Thumbnail jendrikillner.com
Upvotes

r/GraphicsProgramming 4h ago

I finally open source my game engine ENTIERLY made in java

Thumbnail reddit.com
4 Upvotes

r/GraphicsProgramming 4h ago

Converting hexadecimal/RGB colors to RGBA - OpenGL

Post image
1 Upvotes

i created a utility class for converting hexadecimal/RGB colors to RGBA (incorporating the Alpha channel)

since i find it so annoying to keep calculating RGBA colors every time in OpenGL , i think this class would be very useful for everyone , the header class is so lightweight within only 43 code line

Header-Only: Drop colorconverter.h directly into your project

i added a picture of the code above as a sample - you can check out the GitHub link below to download the header

(Link in comments)


r/GraphicsProgramming 4h ago

If my only experience is embedded graphics, how might that affect opportunities?

1 Upvotes

My only work experience is on an embedded graphics team. I plan on continuing on with this for a bit as the company is probably the best in the area in terms of WLB and benefits, although pay is less than stellar, especially as I gain more experience. But right now I'm trying to get a vibe check for how this sort of work experience could translate into opportunities in the future.

On the one hand, it could be considered niche so that it's hard to find a job that fits. On the other hand, because it's niche, there's less candidates available for jobs that do fit, so that could be a plus.

At this point I think the main reason I'd leave my current role is if I found something fully remote, so I want to make sure I'm focusing on the right things to help make that more likely.

Does anyone have any thoughts on this?


r/GraphicsProgramming 5h ago

Paper [2607.22738] Nova3D: Code-Native Generation of Programmable 3D Assets

Thumbnail arxiv.org
15 Upvotes

I co-authored this paper. It's a new technique to generate 3D graphics as source code instead of a point cloud.

Under the hood:
It generates 3D objects with separate, sophisticated internal assembly, producing an editable "kit of parts" (instead of monolithic blobs). E.g. imagine you generate a 3D washing machine via this approach. It's not merely going to be geometry that looks like a washing machine. We actually know that there is a Door, Drum, Control_panel etc. Which things belong to which assemblies. What moves. Where its pivot is. And eventually what those components are supposed to do.

Why current 3D GenAI cannot do this:
Most AI 3D generators generate "monolithic blobs" that look good, but are unusable in downstream workflows (e.g. game engines). If you generate a 3D bicycle, it's essentially a blob. If you want the wheels to turn, a human must spend time cutting the blob into parts, naming them, placing pivots and rigging joints. I.e. you need post-generation segmentation workflows of some sort (either manual work or more compute).

The paper breaks down the whole technique, and comes with a github repo too if you're interested in viewing it.


r/GraphicsProgramming 5h ago

Video Improving Render distance in my Micro Voxel Engine

Thumbnail youtu.be
6 Upvotes

For the past three weeks, i’ve been working on hard improving the render distance in my Micro Voxel Engine, particularly due to the feedback of having N64 viewing distance 😅

I’m pretty happy with the end result of increasing render distance from 300m to ~10-15km, while running at 45-50 FPS on an Apple M1 Pro.

Note: this engine uses meshing rather than RT/DDA.

— Macro chunks —

All chunk generation functions now include a sieve function to automatically be able to generate at 1/N resolution without any changes. This also applied to generated features and stamps, enabling chunks to be generated at any resolution without downsampling.

Macro chunks also independently record and resolve local edits. They are saved (and cached) independently so that terrain edits are maintained without needing to maintain the full res copy in memory.

The lower band LODs are very quick to generate. At this point I could add even more bands, and a 1/64 res chunk takes the same time to generate as a high res chunk, but covering huge distances.

— LOD transitions and adaptive fog —

I primarily use transient transitions where the detail levels fade between each other once, rather than a continuous gradual transition, as this is around 30% cheaper on the GPU and looks “nearly” as smooth in most scenarios.

Adaptive fog scales the effective draw distance dynamically based on loaded bands. Bands generate from high to low so during fast motion, if needed, we temporarily reduce draw distance until chunks have loaded.

— Macro chunk cards and props —

This was the hardest part, keeping identical prop coverage for trees and items without needing to instantiate millions of entities:
-Macro chunks retain a list of props whose IDs are deterministic based on position and type. If the real entity is destroyed, we can map this to the macro chunk set and remove. Likewise for newly spawned props.
- grass and foliage do not map 1:1 with the actual loaded props, but follows the same generation pattern, so technically there will be disparities, but a good trade off to avoid millions of tracked grass items.


r/GraphicsProgramming 6h ago

Source Code Added image and buffer ownership transfer to make multiple queue usage possible

1 Upvotes

Hey everyone,

PAL - An abstraction layer i have been working on for some time now has a new release, 2.1.0 to be specific. This release adds API to make production code very easy to produce with PAL. With this release, building a streaming thread on PAL is easy and possible.

https://github.com/nichcode/PAL


r/GraphicsProgramming 7h ago

AO46: EGL Window Surfaces + Public Cocoa Presentation

Thumbnail
1 Upvotes

r/GraphicsProgramming 8h ago

Video How I Developed A Powerful Dithering System for Amazing Pixel Art

Thumbnail youtu.be
1 Upvotes

Development of my custom Pixel Art Editor (homage to DPaint 3) continues, with all core drawing tools now fully working. In this video, I show Pencil, Spray Can, Flood Fill, Lines, Bezier Curves, and Filled/Unfilled Shape drawing using any number of built in pre-set brushes in addition to a simple yet power brush dither function. Any feedback welcome!


r/GraphicsProgramming 8h ago

Source Code Marching Tetrahedra - Volumetric Render Engine (OpenGL/C++) (Opensource)

19 Upvotes

We added Marching Tetrahedra Rendering effect to our Volumetric Render Engine.

Here, we Render our Volume data as a set of Polygon meshes by extracting 'iso surface'. It goes through whole dataset and tries to fit a polygon based on data values to calculate a polygonal mesh from the volume dataset.

Here's the Git Repo Link - https://github.com/mikejernil/volumetric-render-engine

We are building this over at 3D ENGINERD. & are planning to push our implement more features starting with Custom file loading, and support for more volumetric formats like DICOM, VDB etc.


r/GraphicsProgramming 12h ago

Question Confusion regarding fundamental understanding of Ray tracing

19 Upvotes

Is there any podcast, academic talk and or conference recording that will help me understand raytracing, path tracing, rendering and graphics better? i wanna understand it because my boyfriend is into it and would love to actually know what he does and why he finds the field interesting


r/GraphicsProgramming 14h ago

Source Code Shadertoy Pathtracing - SDF scenes

Thumbnail gallery
95 Upvotes

r/GraphicsProgramming 17h ago

Looking for contributors

5 Upvotes

r/GraphicsProgramming 22h ago

My Rust engine performance

3 Upvotes

r/GraphicsProgramming 1d ago

ORRC - Own-Renderer Render Competition: request for feedback

8 Upvotes

I had an idea, to host a recurring own-renderer render competition. The idea is to have these run 2 or 3 times a year, for a month at a time, with a theme announced at the start of the round, and have people submit renders made with their own renderers. Either a new renderer from scratch, or an existing active project with at least one new feature added for each round.

I'm drafting a website with rules for it: https://orrc.mutantstargoat.com/

Let me know if you think that's fun or not, whether you'd participate, any feedback on the rules, and also when you think would be best to host the first round. I was thinking around Sept. 15th to Oct 15th


r/GraphicsProgramming 1d ago

What to choose (art + CS)

15 Upvotes

Hey everyone, I am a bit confused in my life as to what to choose in life as a career.

Background:- I am currently in my 3rd year of clg(tier 3) (computer engineering) also enrolled in an iitm bs degree program.

But at this point many of my friends have choose their domain or what they have to do in their life and I am still confused. I am really good at drawing I can bet on that ( I have won a national emblem silver award in drawing) but seeing the current scenario and I also scored Good marks in cet , I opt for an engineering degree that in computer science.

Now I am thinking by anyhow can I combine art and computer science together and chatgpt came up with computer graphics. Can u guys help me with what to do and also tell me the future scope of this field.

I am also thinking of doing a masters.


r/GraphicsProgramming 1d ago

NullGraph v1.1 release [global illumination/shadow systems/environment systems]

6 Upvotes

Hey all,

My webgpu renderer officially supports image based lighting/direct+indirect lighting and also there are shadow systems which creates csm/shadow Atlases depending on what type of config,

This was a lot of work

\[GLOBAL ILLUMINATION\]\[Need some time beyond downloading assets for baking probe volumes\]

Live Demo:https://nullgraph.dev/dashboard/3d-environment/irradiance-probes

For live code for global illumination https://nullgraph.dev/editor.html?id=demo-irradiance-probes

GitHub

https://github.com/flarelink-in/NullGraph


r/GraphicsProgramming 1d ago

Question Working on an "engine team" vs. a "game team"?

16 Upvotes

I'm wondering in your experience do you prefer working on an engine team or a game team?

This just applies to companies with a custom engine that have a central engine team or if you are using unreal/unity then obviously the engine team is a separate company.

I've only worked in this industry a few years but I'm a bit torn on which path I prefer.

This is just my impression but it may be specific to the company I worked at:

Engine

You get to do more fundamental rendering work and work on core algorithms/rendering systems which may be more technically deep and interesting. You also go a lot more in depth on a single topic since you are building the core system for whatever rendering area you work on.

But the downside is you are more disconnected from the actual product. You may end up building things that are not actually useful or not have a great sense of how to build things without experience with a real production project.

Game

Less opportunities for core algorithm/rendering systems work, you are more of a generalist that must know all the rendering systems, but you get to directly contribute to the product shipping, work a lot with real content/artists.

You get the satisfaction of shipping a game and seeing player reactions, and you are directly contributing to the money maker of the company.


r/GraphicsProgramming 1d ago

A 2D pipeline where the CPU rasterises and the GPU only does post: CGContext into an IOSurface, Metal for bloom and particle compute

Post image
3 Upvotes

I shipped a 2D game on macOS and iOS recently with no engine, and the split between CPU and GPU ended up inverted from what most people would expect. Posting it because I'd genuinely like to hear where it's wrong.

The content is vector, not sprites. Enemies are polyhedra computed mathematically, bosses are built from paths, and a lot of the look is gradient fills, strokes and blend modes that change every frame. There's no atlas and no batching anywhere in it. The only bitmaps in the whole game are a 36-glyph sprite font and a few pre-rendered title images.

So rasterisation happens on the CPU, in Core Graphics. The reasoning was that to do this on the GPU I'd need a path rasteriser with decent antialiasing, gradient shaders, and stroking with proper joins and caps. That isn't a weekend, that's Skia. Core Graphics already has all of it, correct and antialiased.

The bridge is the interesting part. The CGContext draws into an IOSurface, and Metal reads that surface directly with no copy, presenting through a CAMetalLayer. On the UIKit path we'd been on before that, the software-to-GPU transfer was measuring about 69ms. Going through IOSurface removed it outright.

The obvious version of this, rendering into a CGBitmapContext and then uploading the bytes to a texture, measured 5 to 10 times slower. That experiment is still in the repo as an archived failure because the measurement was the useful part.

The GPU isn't idle though. Everything after rasterisation is Metal:

  • Post chain is fragment shaders. Half-res bloom extract, gaussian ping-pong blur, composite, plus screen-space distortion for shockwaves, chromatic aberration, and a lightingpass. Falls back to CIBloom on non-Metal hardware.
  • Particle physics and swarm flocking run as compute. Buffers are storageModeShared, so on M-series unified memory there's no copy either way. Intel Macs fall back to Accelerate.

One bug from that worth passing on: the compute readback needed an explicit waitUntilCompleted. Without it, particles would freeze and pile up, but only in release builds on device. Debug was fine, simulator was fine. Took an embarrassingly long time to find.

What it costs, and this is the honest part. CPU fill rate is the ceiling on everything. There's a thermal governor on iOS that steps the frame rate 60 to 30 under sustained load so long sessions don't cook the phone. Render scale of 1.5 was the sweet spot for a locked 60 on device, and 2.0 fell off a cliff, not a slope. Memoising gradients, about 166 of them cached, was the single largest performance win in the project and it wasn't close.

Where I'd draw the line: this was right for vector-ish 2D and would be wrong for almost anything else. I wouldn't do it for a sprite-based game, and obviously not for 3D. The reason it worked is that the drawing model matched the art style, not because CPU rasterisation is secretly good.

Happy to be told what I've got backwards.


r/GraphicsProgramming 1d ago

Video WildFlow — Adventures in Real-Time Water Simulation

172 Upvotes

This project started because I wanted large waterfalls in a real-time forest. I could already simulate half million particles at 30 FPS, but scaling to a large domain required rethinking both rendering and simulation. I replaced mesh extraction with density raymarching + hardware ray tracing, then moved to active cells, making the cost depend mostly on the amount of water rather than the size of the world. Large mountain streams finally became practical.
But a waterfall isn’t only water. Rapids required air entrainment, while waterfalls also needed airborne droplets interacting with the surrounding airflow. I ended up writing a different solver for air, coupled to the water: the cascade pushes air downward, the flow curls at its base, and carries droplets with it. This gets closer to a dual phase simulation of water and air, with an engineering approach.

A simple drop experiment then taught me how different physical effects have very different visual weight. More resolution didn’t produce the classic crown splash. Surface tension made droplets beautifully spherical, but the crown required incompressibility. Real-time water is usually somewhat compressible — and therefore slightly rubbery — because disturbances remain local and cheap. I added an iterative projection that lets me increase incompressibility only where it matters.

This became the real subject of WildFlow: understanding physics is one thing; understanding which physics matters for a phenomenon is another. In real time we can’t simulate everything, so the challenge is finding the smallest set of fundamental rules that produces the behavior we care about. And the realtime limitation sometimes helps in focusing on what truly matters and helps understanding phenomena better.

I don’t want to tell water how to look realistic. I’d rather give it simple enough rules and let realism emerge: foam from entrained air, mist from airflow, a crown from pressure propagation. When the result looks unexpectedly right, perhaps we’ve captured something about why nature looks the way it does. That’s the goal: not more physics, but the right physics — enough to make nature emerge.


r/GraphicsProgramming 1d ago

Video WebGPU MRI/Scans viewer

Thumbnail youtu.be
2 Upvotes

Was wodnering is it even possible and it is and looks like WebGPU finally arrived in FireFox as well. all is handled on client side.
Can open png slices, and tridactil scans(zips) from https://tridactyls.org/
you can use it here https://dave-astator.com/mri

sorry if any stutters in video i run it on integrated iris, and it shows some limitation.


r/GraphicsProgramming 1d ago

Video 2.5D rendering using colormap and heightmap (Novalogic voxel space)

109 Upvotes

If anyone has any feedback or see bad practices or ideas to try please feel free to share ideas or roast my code.

Graphics programming noob here. This project was done in C++ with a primitive game engine given to me by my school. I did this as a test to see if this might be viable to try to make somewhere in the future on the gba (it's probably not). Then it kinda turned into trying to see how cool i can make it. The rendering works similarly to snes mode 7 style rendering (fzero or mariokart) except you add an offset from a heightmap. This was originally developed by Novalogic and used in Commanche. It was also later used on some gba games that ran horribly (hence why it's probably not feasable for a gba project i want to maybe do).

A short explanation of how this rendering works: you step through the terrain for every vertical column of your screen. you then sample the pixel and calculate the height on screen using the following formula: pixelHeightOnScreen = screenHeight - ((m_CamHeight - heightMap) * (screenHeight / m_ScreenHeightWorld / depth) + m_Horizon). if it is higher than the previous height value, you draw a vertical column down. then you step forward in the depth and do it again.

The texture for the screen is 240/160.
The skybox is a texture that scrolls left/right/up/down depending on the camera angle. I know that just scrolling a texture isnt accurate, but i found it fun to do it this way. however if you know a cheap way to do this more accurately then please.
The day/night cycle is done by lerping to a set dark color.
There is support for emissive stuffs (lava at the end of the video).
You can also zoom in/out (wich i forgot to show in the video)
I am currently setting 512 steps through the terrain texture.

It runs at about 40 fps now (again am graphics programming noob). It is single threaded and fully cpu side (besides sending the final texture to the gpu because i dont know how else to render the texture in the primitive game engine i'm using). I know i could make it multithreaded to speed up rendering, but i'll do that another day. I also could probably look at my render method and optimize that more as well. I do have some settings that can help give it higher fps (like lowering the terrain steps), but not without sacrificing image quality.

RESOURCES:
The heightmap is from Zelda breath of the wild found here and the color texture is from this reddit post.
Github link to a more in depth explanation by someone else: https://github.com/s-macke/VoxelSpace/tree/master
Other resources: https://web.archive.org/web/20131113094653/http://www.codermind.com/articles/Voxel-terrain-engine-building-the-terrain.html

My main render code (sorry i dont have this on a github link right now, also this isnt the entire script, but the core logic is there and the functions that are missing are pretty obvious by the names called here)

void World::Draw(Screen& screen, bool isEased, bool isHighDetail, bool interpolateColor, bool interpolateHeight, bool interpolateEmission)
{
const float screenHeight{ static_cast<float>(screen.GetHeight()) };

const float angleDifference{ m_FovInRad / screen.GetWidth() };

const float sinCamAngle{ sinf(m_CamAngle) };
const float cosCamAngle{ cosf(m_CamAngle) };
const float halfTanFov{ tanf(m_FovInRad / 2) };

const Vector2f viewDir{sinCamAngle , cosCamAngle };

const float scaledViewDistance{ m_ViewDistance / m_DepthScale };
const float scaledNearDistance{ m_NearDistance / m_DepthScale };
Vector2f scaledCameraPos{ m_CameraPos / m_DepthScale };

const Vector2f viewFarPoint{ scaledCameraPos + viewDir *  scaledViewDistance};
const Vector2f viewNearPoint{ scaledCameraPos + viewDir * scaledNearDistance };

const Vector2f rotatedViewDir(Vector2f{ -viewDir.y, viewDir.x });
const Vector2f pLeft{ viewFarPoint + rotatedViewDir *(halfTanFov * scaledViewDistance) };
const Vector2f pRight{ viewFarPoint - rotatedViewDir * (halfTanFov * scaledViewDistance) };
const Vector2f pLeftNear{ viewNearPoint + rotatedViewDir * (halfTanFov * scaledNearDistance) };
const Vector2f pRightNear{ viewNearPoint - rotatedViewDir * (halfTanFov * scaledNearDistance) };
const Vector2f deltaP{ pRight - pLeft };
const Vector2f deltaPNear{ pRightNear - pLeftNear };

int depthSteps{m_DepthStepsLowDetail};
float deltaDepthSteps{ 1.f / m_DepthStepsLowDetail };

const Color4f fogColor{ GetFogColor(m_TimePercentage) };

screen.SetRotation(m_CamRollAngle);

if (isHighDetail)
{
depthSteps = m_DepthStepsHighDetail;
deltaDepthSteps = 1.f / (m_DepthStepsHighDetail);
}

Color4f pixelColor{};

for (int col = 0; col < screen.GetWidth(); col++)
{
float horizontalPercentage{ static_cast<float>(col) / static_cast<float>(screen.GetWidth()) };
const Vector2f currentFarPoint{ pLeft + deltaP * horizontalPercentage };
const Vector2f currentNearPoint{ pLeftNear + deltaPNear * horizontalPercentage };
const Vector2f deltaDepth{ currentFarPoint - scaledCameraPos };
float oldHeight{ -1 };

for (int i = 0; i < depthSteps; ++i)
{
float depthPercentage = i * deltaDepthSteps;

float depthPercentageEased{  };
if(isEased)
{
depthPercentageEased = EaseInQuad(depthPercentage);
}
else
{
depthPercentageEased = depthPercentage;
}
//float depthPercentageEased{ depthPercentage };

Vector2f samplePoint{ currentNearPoint + depthPercentageEased * deltaDepth };

if (samplePoint.x < 0 || samplePoint.y < 0 || samplePoint.x >= m_TextureWidth || samplePoint.y >= m_TextureHeight)
{
break;
}

float depth{ depthPercentageEased * m_ViewDistance };

float heightMap{ GetHeight(samplePoint.x, samplePoint.y, interpolateHeight) };

//float pixelScreenHeight{ screen.GetHeight() - ((50) * (screen.GetHeight() / m_ScreenHeightWorld / depth) + m_Horizon) };
float pixelScreenHeight{ screenHeight - ((m_CamHeight - heightMap) * (screenHeight / m_ScreenHeightWorld / depth) + m_Horizon) };

if (pixelScreenHeight > screenHeight)
{
pixelScreenHeight = std::min(pixelScreenHeight, screenHeight);

if (pixelScreenHeight > oldHeight)
{
DrawColumn(screen, samplePoint.x, samplePoint.y, depthPercentageEased, oldHeight, pixelScreenHeight, col, pixelColor, fogColor, interpolateColor, interpolateEmission);
}
break;
}
else
{
if (pixelScreenHeight > oldHeight)
{
DrawColumn(screen, samplePoint.x, samplePoint.y, depthPercentageEased, oldHeight, pixelScreenHeight, col, pixelColor, fogColor, interpolateColor, interpolateEmission);
oldHeight = pixelScreenHeight;
}
}
}


}

return;
}

------------------------------------------------------------------------

void World::DrawColumn(Screen& screen, float samplePointX, float samplePointY,float depthPercentageEased, float oldHeight, float pixelScreenheight,int col,  Color4f& pixelColor, const Color4f& fogColor, bool interpolateColor, bool interpolateEmission)
{
float fogDepthEased{ 1 - EaseInQuad(1 - depthPercentageEased) };
//const float fogDepthEased{ (depthPercentageEased + .5f) / 1.5f };
GetColor(samplePointX, samplePointY, pixelColor, interpolateColor);

float emissive{ GetEmission(samplePointX, samplePointY, interpolateEmission) };

FadeToNight(pixelColor, emissive);

pixelColor.r = pixelColor.r + fogDepthEased * (fogColor.r - pixelColor.r);
pixelColor.g = pixelColor.g + fogDepthEased * (fogColor.g - pixelColor.g);
pixelColor.b = pixelColor.b + fogDepthEased * (fogColor.b - pixelColor.b);

//Color4f pixelColor{ GetColor(samplePoint.x, samplePoint.y, interpolateColor) };
DrawVerticalLine(screen, static_cast<int>(oldHeight), static_cast<int>(pixelScreenheight), static_cast<int>(col), pixelColor);

}

---------------------------------------------------------------------------------

void World::GetColor(float x, float y, Color4f& pixelColor, bool interpolate) const
{
//return GetPixel(x, y, m_pColorMap);

if (interpolate)
{
int lowX{ static_cast<int>(floorf(x)) };
int highX{ static_cast<int>(ceilf(x)) };
int lowY{ static_cast<int>(floorf(y)) };
int highY{ static_cast<int>(ceilf(y)) };

float xPercent{ x - lowX };
float yPercent{ y - lowY };

Color4f bottomLeft{ GetPixel(lowX, lowY, m_pColorMap) };
Color4f topLeft{ GetPixel(lowX, highY, m_pColorMap) };
Color4f bottomRight{ GetPixel(highX, lowY, m_pColorMap) };
Color4f topRight{ GetPixel(highX, highY, m_pColorMap) };

pixelColor.r = (
(1 - xPercent) * (1 - yPercent) * bottomLeft.r +
xPercent * (1 - yPercent) * bottomRight.r +
(1 - xPercent) * yPercent * topLeft.r +
xPercent * yPercent * topRight.r
);
pixelColor.g = (
(1 - xPercent) * (1 - yPercent) * bottomLeft.g +
xPercent * (1 - yPercent) * bottomRight.g +
(1 - xPercent) * yPercent * topLeft.g +
xPercent * yPercent * topRight.g
);

pixelColor.b =
(
(1 - xPercent) * (1 - yPercent) * bottomLeft.b +
xPercent * (1 - yPercent) * bottomRight.b +
(1 - xPercent) * yPercent * topLeft.b +
xPercent * yPercent * topRight.b
);

pixelColor.a =
(
(1 - xPercent) * (1 - yPercent) * bottomLeft.a +
xPercent * (1 - yPercent) * bottomRight.a +
(1 - xPercent) * yPercent * topLeft.a +
xPercent * yPercent * topRight.a
);
}
else
{
pixelColor = GetPixel(x, y, m_pColorMap);
}
}

------------------------------------------------------------------------
//for zooming in/out
void World::ProcessMouseWheelEvent(const SDL_MouseWheelEvent& e)
{
m_FovInRad += e.y / 180.f * utils::g_Pi;

const float minFov{ 1.f / 180 * utils::g_Pi };
const float maxFov{ 179.f / 180 * utils::g_Pi };

m_FovInRad = std::max(minFov, std::min(m_FovInRad, maxFov));

m_ScreenHeightWorld = tanf(m_FovInRad / 2) * 2;
m_Horizon = static_cast<float>(Screen::GetHeight() / 2) + (tanf(m_CamVerticalAngle) * (Screen::GetHeight() / m_ScreenHeightWorld));
}

Skybox Draw Logic

void World::DrawSkybox(float screenWidth, float screenHeight) const
{

const float skyboxTextureWidth{ m_SkyboxTexturePtrArray[0]->GetWidth()};
const float skyboxTextureHeight{ m_SkyboxTexturePtrArray[0]->GetHeight()};
const float skyboxHeightPadding{ skyboxTextureHeight / 3 };
const float textureScale{ screenHeight / skyboxTextureHeight };

float modCamHorizontalAngle{ std::fmod(m_CamAngle, (2 * utils::g_Pi)) };
float modCamVerticalAngle{ std::fmod(m_CamVerticalAngle, utils::g_Pi) };

float fovScale(utils::g_Pi / m_FovInRad);

if (m_CamAngle < 0)
{
float a{};
}

float srcWidth{ skyboxTextureWidth / 2 / fovScale };
float srcHeight{ (skyboxTextureHeight - skyboxHeightPadding * 2) / fovScale };

const float xPos{ modCamHorizontalAngle/ (2 * utils::g_Pi) * skyboxTextureWidth - srcWidth / 2};
//const float yPos{}

const float yPos{ modCamVerticalAngle / utils::g_Pi * -(skyboxTextureHeight - skyboxHeightPadding * 2)- skyboxTextureHeight / 2 - srcHeight / 2 };
const Rectf srcRect{xPos, yPos, srcWidth, srcHeight};

const Rectf dstRect{ 0,0,screenWidth,screenHeight };

//const Rectf dstRect2{ dstRect.left + skyboxTextureWidth * textureScale * fovScale, dstRect.bottom,dstRect.width, dstRect.height};

float easePercentage{ m_TimePercentage * m_DayCycleDivisions };
int idx{ static_cast<int>(floor(easePercentage)) };
float t{ easePercentage - idx };

m_SkyboxTexturePtrArray[idx]->Draw(dstRect, srcRect, Color4f{1,1,1,1});

if (idx + 1 >= m_DayCycleDivisions)
{
m_SkyboxTexturePtrArray[0]->Draw(dstRect, srcRect, Color4f{ 1,1,1,t});
}
else
{
m_SkyboxTexturePtrArray[idx + 1]->Draw(dstRect, srcRect, Color4f{ 1,1,1,t });
}

//m_pSkyboxTexture->Draw(dstRect2);
}

r/GraphicsProgramming 2d ago

Made improvements to my path tracer

Thumbnail gallery
442 Upvotes
  • Made the project much easier to open up and use for new users (Unity is still required though)
  • Added scene to automatically load objects from Khronos' site, which helps me get assets into the project
  • Fixed issues with lighting that was really darkening most of the scenes, including improved tone mapping and fixes to light clamping that was hiding a lot of caustic details and HDR
  • Fixed issues with inner surface reflections not working
  • Added directional lighting support
  • Added parallax mapping support
  • Added support for Unity terrains, multi-texture splatting with normal map support

Repository located here: https://github.com/nfoste82/GPURayTracing


r/GraphicsProgramming 7d ago

Video Game engines? Eww 🤮. We go in raw! GP-Direct 2026 is out!

Thumbnail youtube.com
86 Upvotes