Materials (PBR, Specular, Normal maps)

Handy guides on how to do things, written by users for users.

Moderators: GZDoom Developers, Raze Developers

Forum rules
Please don't start threads here asking for help. This forum is not for requesting guides, only for posting them. If you need help, the Editing forum is for you.
User avatar
furyweb
Posts: 33
Joined: Thu Aug 30, 2018 3:23 pm
Location: UK

Re: Materials (PBR, Specular, Normal maps)

Post by furyweb »

Thanks for the response dpJudas. Could not get it working though. Maybe I am being stupid but I get the error

Unable to load shader parallax:
Init Shader 'parallax':
Fragment shader:
0(14) : error C1008: undefined variable "tex_gloss"

Linking:
Fragment info
-------------
0(14) : error C1008: undefined variable "tex_gloss"
(0) : error C2003: incompatible options for link

Code:

Code: Select all

mat3 GetTBN();
vec3 GetBumpedNormal(mat3 tbn, vec2 texcoord);
vec2 ParallaxMap(mat3 tbn);

Material ProcessMaterial()
{
    mat3 tbn = GetTBN();
    vec2 texCoord = ParallaxMap(tbn);

    Material material;
    material.Base = getTexel(texCoord);
    material.Normal = GetBumpedNormal(tbn, texCoord);
    material.Specular = texture(speculartexture, texCoord).rgb;
    vec4 glossSpec = texture(tex_gloss, texCoord);
	material.Glossiness = glossSpec.r * uSpecularMaterial.x;
	material.SpecularLevel = glossSpec.g * uSpecularMaterial.y;
#if defined(BRIGHTMAP)
    material.Bright = texture(brighttexture, texCoord);
#endif
    return material;
}

// Tangent/bitangent/normal space to world space transform matrix
mat3 GetTBN()
{
    vec3 n = normalize(vWorldNormal.xyz);
    vec3 p = pixelpos.xyz;
    vec2 uv = vTexCoord.st;

    // get edge vectors of the pixel triangle
    vec3 dp1 = dFdx(p);
    vec3 dp2 = dFdy(p);
    vec2 duv1 = dFdx(uv);
    vec2 duv2 = dFdy(uv);

    // solve the linear system
    vec3 dp2perp = cross(n, dp2); // cross(dp2, n);
    vec3 dp1perp = cross(dp1, n); // cross(n, dp1);
    vec3 t = dp2perp * duv1.x + dp1perp * duv2.x;
    vec3 b = dp2perp * duv1.y + dp1perp * duv2.y;

    // construct a scale-invariant frame
    float invmax = inversesqrt(max(dot(t,t), dot(b,b)));
    return mat3(t * invmax, b * invmax, n);
}

vec3 GetBumpedNormal(mat3 tbn, vec2 texcoord)
{
#if defined(NORMALMAP)
    vec3 map = texture(normaltexture, texcoord).xyz;
    map = map * 255./127. - 128./127.; // Math so "odd" because 0.5 cannot be precisely described in an unsigned format
    map.y = -map.y;
    return normalize(tbn * map);
#else
    return normalize(vWorldNormal.xyz);
#endif
}

vec2 ParallaxMap(mat3 tbn)
{
    const float parallaxScale = 0.050;
    const float minLayers = 16.0;
    const float maxLayers = 64.0;

    // Calculate fragment view direction in tangent space
    mat3 invTBN = transpose(tbn);
    vec3 V = normalize(invTBN * (uCameraPos.xyz - pixelpos.xyz));
    vec2 T = vTexCoord.st;

    float numLayers = mix(maxLayers, minLayers, clamp(abs(V.z), 0.0, 1.0)); // clamp is required due to precision loss

    // calculate the size of each layer
    float layerDepth = 1.0 / numLayers;

    // depth of current layer
    float currentLayerDepth = 0.0;

    // the amount to shift the texture coordinates per layer (from vector P)
    vec2 P = V.xy * parallaxScale; 
    vec2 deltaTexCoords = P / numLayers;
    vec2 currentTexCoords = T;
    float currentDepthMapValue = texture(tex_heightmap, currentTexCoords).r;

    while (currentLayerDepth < currentDepthMapValue)
    {
        // shift texture coordinates along direction of P
        currentTexCoords -= deltaTexCoords;

        // get depthmap value at current texture coordinates
        currentDepthMapValue = texture(tex_heightmap, currentTexCoords).r;  

        // get depth of next layer
        currentLayerDepth += layerDepth;  
    }

    // get texture coordinates before collision (reverse operations)
    vec2 prevTexCoords = currentTexCoords + deltaTexCoords;

    // get depth after and before collision for linear interpolation
    float afterDepth  = currentDepthMapValue - currentLayerDepth;
    float beforeDepth = texture(tex_heightmap, prevTexCoords).r - currentLayerDepth + layerDepth;
     
    // interpolation of texture coordinates
    float weight = afterDepth / (afterDepth - beforeDepth);
    vec2 finalTexCoords = prevTexCoords * weight + currentTexCoords * (1.0 - weight);

    return finalTexCoords;  
}
dpJudas
 
 
Posts: 3036
Joined: Sat May 28, 2016 1:01 pm

Re: Materials (PBR, Specular, Normal maps)

Post by dpJudas »

You have to declare a tex_gloss texture in the GLDEFS file as well:

Code: Select all

material texture "stargr1"
{
    normal "materials/normalmaps/stargr1.tga"
    specular "materials/specular/spec1.png"
    shader "shaders/texture/parallax.fp"
    texture tex_heightmap "materials/heightmaps/startan3.tga"
    texture tex_gloss "materials/glossmaps/startan3.tga"
    specularlevel 100
    glossiness 100
}
User avatar
furyweb
Posts: 33
Joined: Thu Aug 30, 2018 3:23 pm
Location: UK

Re: Materials (PBR, Specular, Normal maps)

Post by furyweb »

Yeah still nothing. Just downloaded newest dev build to see if that was the issue. Same thing.

Code: Select all

material texture "FLSO13A"
{
    normal "normalmaps/FLSO13A.png"
    specular "specular/FLSO13A.png"
    shader "shaders/texture/parallax.fp"
    texture tex_heightmap "heightmaps/FLSO13A.png"
    texture tex_gloss "glossmaps/FLSO13A.png"
    specularlevel 100
    glossiness 100
}
dpJudas
 
 
Posts: 3036
Joined: Sat May 28, 2016 1:01 pm

Re: Materials (PBR, Specular, Normal maps)

Post by dpJudas »

Hmm, must be some bug in the implementation in GZDoom. I didn't implement this custom texture feature myself - maybe it was only ever tested with one texture.
enderandrew
Posts: 108
Joined: Mon Dec 12, 2016 1:12 pm

Re: Materials (PBR, Specular, Normal maps)

Post by enderandrew »

When I attempt to use the parallax shader, this is the effect I'm seeing.

https://imgur.com/a/dguegO7
Reinchard2
Posts: 310
Joined: Fri Sep 21, 2007 1:08 am
Location: Poland - Bytom

Re: Materials (PBR, Specular, Normal maps)

Post by Reinchard2 »

You're the guy that make normals/specs/heightmaps for Hoover1974 pack, right? If so, I hate to say it, but I look at some of your normals and heightmaps and I see that you made it in incorrect way. In normals you must be carrefull with your Red/Green channels - green channel decides which part of Y "offset" illusion is bump, and red decides of "X" "offset" illusion. In heightmaps darker areas are deeper, and areas near white are close to the camera (in case of GZDoom shader this is actually flip, but the rule is the same). I'll show you an example:
It's normal map for my star texture:
https://imgur.com/iMy0pYf
Notice that yopu can clearly see the light direction - lighten areas from green channel are on top of bumped parts and dark are at the bottom.
And here is correct heightmap:
https://imgur.com/Be7EpKK
enderandrew
Posts: 108
Joined: Mon Dec 12, 2016 1:12 pm

Re: Materials (PBR, Specular, Normal maps)

Post by enderandrew »

I used Nvidia's Photoshop Plugin to generate the normal maps, but I'm noticing that normal maps generated with other tools are coming out completely differently. So I may recreate all the normal maps.

Nothing appears raised or elevated in game when I'm testing these.
Reinchard2
Posts: 310
Joined: Fri Sep 21, 2007 1:08 am
Location: Poland - Bytom

Re: Materials (PBR, Specular, Normal maps)

Post by Reinchard2 »

Don't use any filtered/auto-generated normal maps. That kind of software produce normal maps form pixel brightness and it's totally incorrect way. They are useful in some cases, but if you want to make normals in correct way, first you need to create some 3d model based on specific part of texture or draw normals by hand which can be difficult. https://www.youtube.com/watch?v=6_-NNKc4lrk
User avatar
Nash
 
 
Posts: 17433
Joined: Mon Oct 27, 2003 12:07 am
Location: Kuala Lumpur, Malaysia
Contact:

Re: Materials (PBR, Specular, Normal maps)

Post by Nash »

How to do proper normal maps (tl;dr do them by hand, or a combination of modelling and by hand):

Guest

Re: Materials (PBR, Specular, Normal maps)

Post by Guest »

How difficult would it be to optionally add the ability to warp a material (diffuse+normal+specular or pdr)? I suck at GLSL but am thinking of of making an attempt at it. I'm thinking it's probably not as simple as frankensteining these shaders from gzdoom.pk3 together:

func_spec.fp
func_pbr.fp
func_warp1.fp
User avatar
neoworm
Posts: 1740
Joined: Fri Sep 23, 2005 9:17 am
Location: Czech Republic

Re: Materials (PBR, Specular, Normal maps)

Post by neoworm »

I was playing with http://www.boundingboxsoftware.com/mate ... /index.php and tried to create pbr versions of some HeXen textures. But I have troubles with setting the various maps to replace the stock textures in HeXen. Would someone help me to setup the GLDEFS so it shows ingame?
User avatar
Gato303
Posts: 36
Joined: Wed Mar 30, 2016 6:14 pm
Location: Colombia
Contact:

Re: Materials (PBR, Specular, Normal maps)

Post by Gato303 »

Here is a demo for those interested.
Forgive my ignorance in the subject, but how do I load the demo file? is it loaded with the suffix "-file" the same way when you load mods?

I loaded the map "demo" but only the room with the floating light appears to have some PBR effects only on the floor and the sword's material shows pretty flat.

Using GZDoom G3.6.0 from the DRD Team on Linux Xubuntu, thank you
franksouza183
Posts: 1
Joined: Wed Nov 07, 2018 2:07 am

Re: Materials (PBR, Specular, Normal maps)

Post by franksouza183 »

dpJudas, can you make your parallax heightmap shader compatible with brightmaps?
User avatar
Gato303
Posts: 36
Joined: Wed Mar 30, 2016 6:14 pm
Location: Colombia
Contact:

Re: Materials (PBR, Specular, Normal maps)

Post by Gato303 »

Gato303 wrote:
Here is a demo for those interested.
Forgive my ignorance in the subject, but how do I load the demo file? is it loaded with the suffix "-file" the same way when you load mods?

I loaded the map "demo" but only the room with the floating light appears to have some PBR effects only on the floor and the sword's material shows pretty flat.

Using GZDoom G3.6.0 from the DRD Team on Linux Xubuntu, thank you
Never mind, I found out my "problem", the PBR materials are "invisible" unless you use a dynamic light on them. Loaded a mod that included a flashlight and whoa! There they were <3
User avatar
Gato303
Posts: 36
Joined: Wed Mar 30, 2016 6:14 pm
Location: Colombia
Contact:

Re: Materials (PBR, Specular, Normal maps)

Post by Gato303 »

GIMP also has a filter for creating normal maps, it can has its flaws too, but is also helpful if you need some quick nomal map for your projects.

Go to: Filters> Map> Normalmap
Post Reply

Return to “Tutorials”