Is it possible to prepare a generic bump map shader to be used by any 3D game?

I found this bump map shader:

Shader "Custom/BumpedEnvironment" {
   Properties {
      _myDiffuse ("Diffuse Texture", 2D) = "white" {}
      _myBump ("Bump Texture", 2D) = "bump" {}
      _mySlider ("Bump Amount", Range(0,10)) = 1
      _myBright ("Brightness", Range(0,10)) = 1
      _myCube ("Cube Map", CUBE) = "white" {}
   SubShader {

      #pragma surface surf Lambert

        sampler2D _myDiffuse;
        sampler2D _myBump;
        half _mySlider;
        half _myBright;
        samplerCUBE _myCube;

      struct Input {
         float2 uv_myDiffuse;
         float2 uv_myBump;
         float3 worldRefl; INTERNAL_DATA  // <- THIS IS VERY IMPORTANT

      void surf (Input IN, inout SurfaceOutput o) {
          o.Albedo = tex2D(_myDiffuse, IN.uv_myDiffuse).rgb;
          o.Normal = UnpackNormal(tex2D(_myBump, IN.uv_myBump)) * _myBright;
          o.Normal *= float3(_mySlider, _mySlider, 1);
          o.Emission = texCUBE(_myCube, WorldReflectionVector(IN, o.Normal)).rgb;

   FallBack "Diffuse"

I want to let Arx Libertatis use that shader, but I would like also to let other 3D games that do not have it, to be able to use it too (see OpenSourcedGames.

Is the only way to adapt that shader inside the game engine, so the game engine itself send it to the GPU?

Or is it possible to compile a generic bump map shader like the above, load it into the GPU (while or before the game start to run) and force the GPU to apply that shader to specific 3D games? It would be like injecting a shader into a game I guess.

If it is possible, any tips how should I start doing it? the easiest way if possible, as I am very new to shaders.

I am not restricting the answer to Linux. If the answer can also work on Linux, it would be better though.

I just found about ENB, but it doesn't work on Linux. There is this that could work on Linux (there is a Linux instruction folder inside it; any newer version may have it too) but it requires Wine, and therefore a Windows compiled game binary, and I develop projects on Linux, compiled for Linux.
So, What I mean is, unless there is some equivalent to ENB that works on Linux (may be Mac) too, my main request/question is how can I do it myself instead of using some ready tool.


1 Answer 1


No, you won't be able to make a normal mapping shader that can be universally applied to any game that doesn't already use one. Even assuming you have a perfect injection system that can add your custom shader to specific draw calls, there are two main obstacles:

  1. Tangent space normal mapping requires the shader to receive tangent vector information, used to orient the bumps the right way along the object's surfaces. If the game was not already using normal mapping, it likely will not include this information in the vertex data it sends to the GPU. I have seen shaders try to approximate tangent space using screen space derivatives, but I suspect that would show artifacts.

    You could use object space normal mapping instead, but this would require you to create an object space normal map for each object in each game you want this to apply to. It would show artifacts for any objects that don't have a fully unique unwrap (i.e. the same part of the texture is used for multiple parts of the object).

    The bigger obstacle though is...

  2. For normal maps to apply shading to their bumps correctly, they need access to information about where the light is shining from or what colour it is. There is no standard way to convey this information to the GPU. Every game can implement lights in its own quirky way.

    You would need to write a custom version of this shader for every rendering engine, and possibly many variants for some rendering engines that switch between different versions of lighting shaders depending on the lighting conditions (e.g. spot vs directional vs point vs cube map vs spherical harmonics, distance/level of detail trade-offs, shadowing...).

You can still probably make a shader you can inject into a single game of interest, and it may even work on other games by the same studio/using the same engine. But making one that works with "any 3D game" is definitely off the table.

  • \$\begingroup\$ if I am not wrong, arx libertatis is sending normal data to the gpu, because exporting a blender model with smooth or sharp normals does look different, and they implemented a light shader (but I am not sure if it is a proper shader to the GPU), but the bump map shader was not implemented yet. I wish I had more knowledge on how to do that.. My goal was to have wet and shiny surfaces mainly, like we can see in doom 3, because that makes a huge difference to visual quality. There was an old bump map code that was removed, I think because it was too low quality or low performance, not sure. thx! \$\endgroup\$ Commented Dec 28, 2023 at 4:13
  • \$\begingroup\$ Note that I said tangent data, not normal data. These are separate vectors, both needed for tangent space normal mapping. If you want to make a mod for this one game, ask instead "How do I make wet and shiny surfaces in Arx Liberatis". Making the question too broad/general can prevent you from getting useful, targeted answers for the case you actually care about. \$\endgroup\$
    – DMGregory
    Commented Dec 28, 2023 at 11:02
  • \$\begingroup\$ I wrote it wrong on the above comment.My goal was bump,wet and shiny.But I wanted to ask bump separately because Arx Fatalis had bump map, and it was removed in Arx Libertatis because, if I am not wrong, it was not a shader and too low quality and made developing other things too complex, but as it was already there once,it could be less complex to properly implement it one day. If I am not wrong also, the lights are using something that could become a (?)shader(?) and is probably the first step towards bump maps, wet and shiny surfaces. Btw, I dont know how to code any of these things yet. \$\endgroup\$ Commented Dec 29, 2023 at 0:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .