Physically Based Rendering

Physically Based Rendering

Discuss the source code and development of Spring Engine in general from a technical point of view. Patches go here too.

Moderator: Moderators

Post Reply
User avatar
ivand
Posts: 82
Joined: 27 Jun 2007, 17:05

Physically Based Rendering

Post by ivand » 15 Sep 2018, 19:26

Hi folks!

I've put together an implementation of Physically Based Rendering for spring models.
It generally works ok it seems, but I kinda stuck with Image Based Lighting. I've tried to leverage built-in $specular and $reflection cubemaps, but I don't get how to use these textures to do IBL.

I've sampled both, but neither of them look like an environment reflection:
Image
Image

Can someone shed some light on the topic?

Some PBR teaser without IBL (IBL is replaced with white color): https://drive.google.com/file/d/1KkY_kg ... fQHV_/view
4 x

Kloot
Spring Developer
Posts: 1821
Joined: 08 Oct 2006, 16:58

Re: Physically Based Rendering

Post by Kloot » 15 Sep 2018, 20:29

Both screenshots look correct to me.

The specular cubemap (top image) basically just stores C * pow(dot(N, L), e), where C is the sun's model specular color, L the sun direction and e the specular exponent. This is going to be black for most N's.

Ravaged's skybox contains green near the horizon and blue-grey at its zenith, which are reflected by the model's vertical and horizontal surfaces respectively, although those two terrain reflection "arches" on its barrel don't seem 100% accurate for sky-facing geometry.

Increase CubeTexSizeReflection in springsettings.cfg to make reflections less downsampled.
3 x

User avatar
ivand
Posts: 82
Joined: 27 Jun 2007, 17:05

Re: Physically Based Rendering

Post by ivand » 15 Sep 2018, 21:02

Thx @Kloot.
So it's really $reflection tex I should use for IBL.

I've changed the PBR shader and now it looks so much better:
PBR shader on Coagulation Marsh
1 x

User avatar
ivand
Posts: 82
Joined: 27 Jun 2007, 17:05

Re: Physically Based Rendering

Post by ivand » 15 Sep 2018, 22:44

One more question to @Kloot.

I noticed that $reflection texture has GL_LINEAR minification filter. From the PBR effects perspective it's much better to have that equal to GL_LINEAR_MIPMAP_LINEAR instead. Can this be changed?

Generally I noticed that several textures have filters that don't fit my shaders.
One another example is heightmap "nearest" sampling. I either need to copy $heightmap to another texture with the filtering I want or introduce sampler on the shader side (where bilinear is easy to do, but mipmap emulation is hard or even impossible).

Unfortunately the current Lua API only allows to select sampling in two cases (AFAIK). When:
1. Texture is created from some file. E.g. gl.Texture(":iac:/LuaUI/images/image.png")
2. During the texture creation, i.e. gl.CreateTexture parameters.

Is it possible to add a Lua API that would allow for changing the texture filtering after the texture have been created?
0 x

MaDDoX
Posts: 48
Joined: 08 Jan 2006, 17:45

Re: Physically Based Rendering

Post by MaDDoX » 16 Sep 2018, 04:14

I've been collaborating with Ivand to get this working, mostly from a technical artist point of view - model & textures also provided, they're for a WIP new Spring game. Amazing job so far Ivand, I can't tell you how happy I am with what you accomplished! :) This is the #1 graphical breakthrough Spring needs for its graphics to be on par with most of the top engines out there. I hope we can get it working with Terrain and features, it'd be killer!

That said, there's one major thing left to get this looking perfect as we get in Substance, Sketchfab, Marmoset etc: HDR IBL (high dynamic range, image-based lighting). Many HDR images use a 16-bit per channel format, which Spring wouldn't be able to read and also would take too much disk + ram space. *But* there's the Radiance image format (.hdr), which manages to encode the HDR image's full dynamic range in a simple 32-bit image - meaning it can be stored as a DXT5 .DDS file, for fast reads and smaller file sizes. Link:
https://en.wikipedia.org/wiki/RGBE_image_format

Tell me if you want a couple samples of an HDR texture in .DDS format, I'll be glad to provide it to you.

So, this kind of image (optimally panoramic/equirectangular) could be read from an entry in mapinfo.lua and, if not provided, fallback to use the $reflection texture. Talking of $reflection, I'm not sure if the "e" (specular exponent) is being generated with floating point precision, the result you've shown looks a lot like SDR to me - but maybe it's just a poor cubemap defined in the map. Anyways, for the PBR shader you could try applying a curve remap to its strength, so the closer to the upper range of luminance you are, the stronger the actually applied lighting intensity would be.
2 x

User avatar
ivand
Posts: 82
Joined: 27 Jun 2007, 17:05

Re: Physically Based Rendering

Post by ivand » 16 Sep 2018, 12:08

Thanks for the praise, @MaDDox. I wouldn't have started PBR implementation, if no one had provided me a model and textures for PBR. Fortunately you did, so we've got a semi-complete implementation for now.

Features could be incorporated easily. As far as PBR map shader, It's likely doable with recent spring versions, but it requires completely separate Lua gadgetry and slight changes to the shader code. I might look into this later.

Yesterday I found and tested a piece of code that allows to sample the environment from the equirectangular image. https://www.shadertoy.com/view/4lycz3. See the vec3 getEnvironment(vec3 rayDirection) function.

It's also not hard to map an RGBE data to HDR linear(?) RGB in the shader.
If you could author an RGBE map image, it won't take me long to make it usable instead of $reflection.
0 x

User avatar
ivand
Posts: 82
Joined: 27 Jun 2007, 17:05

Re: Physically Based Rendering

Post by ivand » 17 Sep 2018, 01:51

Big thanks to @Kloot. He managed to resolve all issues/feature requests I raised in the previous post.

In case someone was wondering what kind of effect environment mipmaping has on reflections, see here

After I've managed to solve a couple of hidden issues (like the fact that normals stored in sRGB) I've come to the following result. Note sky is pitch black here, so model is also a bit dark.
2 x

User avatar
PicassoCT
Journeywar Developer & Mapper
Posts: 9896
Joined: 24 Jan 2006, 21:12

Re: Physically Based Rendering

Post by PicassoCT » 17 Sep 2018, 19:06

Fuck, every map- retune the sky for this :(
0 x

User avatar
ivand
Posts: 82
Joined: 27 Jun 2007, 17:05

Re: Physically Based Rendering

Post by ivand » 18 Sep 2018, 11:28

I was thinking about skybox problem and came up with several ideas:

1) MaDDox prefers usage of the custom HDR environment maps. Since Spring OpenGL API can't into cubemaps, they are going to be supplied in equirectangular projection. Pros: if I happen to handle them right, they should look gorgeous. Cons: bye-bye dynamic reflection of terrain.
2) There could be a way to combine static HDR environment map with $reflection. I don't yet know how, but might figure something out. This is essentially extension of the current implementation + (1) + some math to put them together.
3) Color hack: I can sample skydome in a few places and if average luminosity of the pixels is too low, I can tone map it to something brighter. The main issue here is same as in (2). I've got to find the way to tall apart sampling of terrain from sampling of the sky.

As far as PBR progress, it has slowed down a bit. Yesterday I was able to incorporate parallax mapping. Unfortunately it didn't look any good on the model I was using (jeffy). MaDDox told me that parallax should work better for the cases like terrain rendering. Today I've cleaned out bugs from my pet WebGL project and looks like MaDDox was right. In the certain scenarios it looks indeed as good as it's hard to guess displacements have no geometry behind them. See here
0 x

Kloot
Spring Developer
Posts: 1821
Joined: 08 Oct 2006, 16:58

Re: Physically Based Rendering

Post by Kloot » 18 Sep 2018, 12:10

2) extend gl.CreateTexture with cubemap support (easy-ish), then dynamically replace the skybox by your HDR environment cubemap via Spring.SetSkyBoxTexture (currently deadweight)
0 x

Post Reply

Return to “Engine”

cron