Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
Stealth Frag

Doom with PBR materials

Recommended Posts

Can you use this to make only specific parts of a texture pop?

I can imagine that a few PBR'ed textures among a load of vanilla textures can help bring out things like switches or secret walls.

Share this post


Link to post
3 minutes ago, FractalBeast said:

Can you use this to make only specific parts of a texture pop?

I can imagine that a few PBR'ed textures among a load of vanilla textures can help bring out things like switches or secret walls.

Afaik yes you can by leaving the parts you don't want to pop up empty when making the materials.

Share this post


Link to post
On 11/17/2018 at 5:24 PM, Bauul said:

 

Amazingly no. From what I understand (and I'm really no expert) it's all done through a shader, basically a graphical effect that utilizes native OpenGL rendering methods. As long as you have a modern enough GPU to support it, the process is a breeze for your GPU to understand and render. It's pretty damn efficient.  

It is amazing. I guess that's why I push for supporting the artists. These video cards are churning literally billions of calculations per frame. Rendering 3D is very hard. Or, at least it used to be. The capabilities of these cards make it a lot easier. The "fake depth" you see in the previous screenshots is an incredibly neat trick. The word "amazing" is an understatement, I think.

Share this post


Link to post
On 11/17/2018 at 10:37 PM, DooM_RO said:

@Reinchard

 

One thing I've just noticed is that it is a bit obvious that the panels of the STAR texture were put onto a flat surface. They look a bit like two different objects. I recommend giving the edge a bevel in the high poly and make it a normal map detail. And again, it seems like the panels are a bit too deep.

 

Sorry for long absence, Im little busy last time. But thanks for opinion. I'll try fix few things you pointed out in another version. 

 

Share this post


Link to post
1 hour ago, Reinchard said:

It's a separate texture and you can use them together with normal map. 

 

Does the zdoom wiki hav any information? On the GLdefs page I see instructions on how to use the other maps but no mentioning on displacement maps.

 

EDIT: Are you 90% sure that displacement maps aren't expensive on performance? I am 90% sure that I have read it somewhere that displacement maps are suppose to be used carefully because of how taxing they are compared to mere normal maps.

Share this post


Link to post

The classic maps just don't do these textures justice. The geometry is much too simple. I hope @Reinchard has plans for an official WAD too! I would be happy to join if I have time.

Share this post


Link to post
30 minutes ago, hardcore_gamer said:

 

Does the zdoom wiki hav any information? On the GLdefs page I see instructions on how to use the other maps but no mentioning on displacement maps.

 

EDIT: Are you 90% sure that displacement maps aren't expensive on performance? I am 90% sure that I have read it somewhere that displacement maps are suppose to be used carefully because of how taxing they are compared to mere normal maps.

 

You won't find any information on the ZDoom wiki because displacement maps aren't a native feature. Shaders are the native feature, and dpJudas (IIRC) wrote a shader that implemented parallax mapping, using a height map (or displacement map by another name).

 

And, genuinely, they're not that heavy on processing. There's some minimal impact, but a room of dynamic lights will probably cause more slow down. 

 

This is a work in progress shot from an Elementalism map that applies a high resolution normal map, specular map and displacement map to the entire scene and happily runs at over 100fps on my laptop (compared to about 160fps when loading E1M1). Most of what slow-down there is is caused by the dynamic lights and alpha transparent sprites, not the parallax mapping.

 

D1hKp2f.png

Share this post


Link to post

No one asked for it, but I strangely bothered to write this about the heightmaps just in case, so I'll post it anyway. I guess I wrote it for @hardcore_gamer!

Spoiler

To use these heightmaps on your own textures in your own mods, create a text file in a PK3 file with these contents from dpJudas:

Spoiler

This is big in the preview, hence the spoiler.



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);
#if defined(SPECULAR)
	material.Specular = texture(speculartexture, texCoord).rgb;
	material.Glossiness = uSpecularMaterial.x;
	material.SpecularLevel = uSpecularMaterial.y;
#endif
#if defined(PBR)
	material.Metallic = texture(metallictexture, texCoord).r;
	material.Roughness = texture(roughnesstexture, texCoord).r;
	material.AO = texture(aotexture, texCoord).r;
#endif
#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.045;
	const float minLayers = 8.0;
	const float maxLayers = 16.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
	const 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; 
}

 

Afterward, return to the root folder of the PK3 and add a folder named "materials" then "heightmaps" inside that. Heightmaps themselves can be any size, like other GLDEFS textures. In these greyscale textures, black represents being level with the surface, and lighter shades make that part of the texture appear to dip down. These can be generated using a program like Substance Designer but you can also make them by hand.

Import your heightmaps into that folder, then return to the root folder and add something like this:


material texture "HEIGHTMP" (texture name)
{
	Shader "shaders/textures/heightmap.fp" (shader location)
	Texture tex_heightmap "materials/heightmaps/heightmap.png" (heightmap location)
}

If everything was done correctly, the texture should now appear more 3D with indented areas in-game.

Share this post


Link to post

Here is an example, Diffuse (Far left) Normal (Left) Specular (Right) Heightmap (Far right). 

 

lxi4LNw.png

 

(Just one texture from my doom3 texture pack in progress)

Share this post


Link to post
34 minutes ago, Xane123 said:

No one asked for it, but I strangely bothered to write this about the heightmaps just in case, so I'll post it anyway. I guess I wrote it for @hardcore_gamer!

  Hide contents

To use these heightmaps on your own textures in your own mods, create a text file in a PK3 file with these contents from dpJudas:

  Reveal hidden contents

This is big in the preview, hence the spoiler.




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);
#if defined(SPECULAR)
	material.Specular = texture(speculartexture, texCoord).rgb;
	material.Glossiness = uSpecularMaterial.x;
	material.SpecularLevel = uSpecularMaterial.y;
#endif
#if defined(PBR)
	material.Metallic = texture(metallictexture, texCoord).r;
	material.Roughness = texture(roughnesstexture, texCoord).r;
	material.AO = texture(aotexture, texCoord).r;
#endif
#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.045;
	const float minLayers = 8.0;
	const float maxLayers = 16.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
	const 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; 
}

 

Afterward, return to the root folder of the PK3 and add a folder named "materials" then "heightmaps" inside that. Heightmaps themselves can be any size, like other GLDEFS textures. In these greyscale textures, black represents being level with the surface, and lighter shades make that part of the texture appear to dip down. These can be generated using a program like Substance Designer but you can also make them by hand.

Import your heightmaps into that folder, then return to the root folder and add something like this:



material texture "HEIGHTMP" (texture name)
{
	Shader "shaders/textures/heightmap.fp" (shader location)
	Texture tex_heightmap "materials/heightmaps/heightmap.png" (heightmap location)
}

If everything was done correctly, the texture should now appear more 3D with indented areas in-game.

 

How come this stuff isn't mentioned in the GLDEFS section at the zdoom wiki? Somebody should add this shit since it looks useful.

 

EDIT: Oh it's a custom thing that only you created? Yea I guess that explains it. Still this kind of displacement map support should become officially supported since it looks pretty awesome. Furryweb I assume this also works with a metal&roughness workflow?

Share this post


Link to post
21 hours ago, hardcore_gamer said:

 

How come this stuff isn't mentioned in the GLDEFS section at the zdoom wiki? Somebody should add this shit since it looks useful.

 

EDIT: Oh it's a custom thing that only you created?

Actually, this is a custom shader by dpJudas. Yeah, it isn't officially in GZDoom but should be because heightmaps add nice depth to textures, when combined with pre-baked lighting where the dips are. (I know, it's said to never do that with PBR but GZDoom needs "global light sources".)

Share this post


Link to post
21 hours ago, hardcore_gamer said:

Still this kind of displacement map support should become officially supported since it looks pretty awesome.

 

Shaders are officially supported, and this is just a shader, one of any number of shaders that you can apply.  To try to make it "more official" would just confuse how it and other shaders get applied.  I think it's much neater to just have all shaders applied in the same way.

Share this post


Link to post
On 11/22/2018 at 12:15 PM, Bauul said:

 

You won't find any information on the ZDoom wiki because displacement maps aren't a native feature. Shaders are the native feature, and dpJudas (IIRC) wrote a shader that implemented parallax mapping, using a height map (or displacement map by another name).

 

And, genuinely, they're not that heavy on processing. There's some minimal impact, but a room of dynamic lights will probably cause more slow down. 

 

This is a work in progress shot from an Elementalism map that applies a high resolution normal map, specular map and displacement map to the entire scene and happily runs at over 100fps on my laptop (compared to about 160fps when loading E1M1). Most of what slow-down there is is caused by the dynamic lights and alpha transparent sprites, not the parallax mapping.

 

D1hKp2f.png

That is amazing!

Share this post


Link to post

I'm loving your work there Reinchard. Looking at your examples, I think the height map does add a lot of extra presence to textures with a lot of depth such as the door textures. It makes them really pop.  

 

To anyone who wants to make textures, and can't afford either Quixel or Designer, there is a good looking bit of free software here: http://www.boundingboxsoftware.com/materialize/index.php. I don't know if anyone mentioned it before in the thread. 

 

 

Share this post


Link to post
On 12/7/2018 at 7:07 AM, Tea Monster said:

I'm loving your work there Reinchard. Looking at your examples, I think the height map does add a lot of extra presence to textures with a lot of depth such as the door textures. It makes them really pop.  

 

To anyone who wants to make textures, and can't afford either Quixel or Designer, there is a good looking bit of free software here: http://www.boundingboxsoftware.com/materialize/index.php. I don't know if anyone mentioned it before in the thread. 

 

 

I know I mentioned it, though not in this thread.

 

Still, damn excellent tool. Might help these guys out quite a bit.

Share this post


Link to post

Still very nice! Personally, I would use more geo on cylinder parts and find some more uv space for screw normal, but these are details. Good job :)

Share this post


Link to post

I would as well for a HUD item. It looks pretty good in game and it's much smaller as per percentage of screen area, so it all works out. 

Share this post


Link to post

I think I'm going to take a little break from E1 textures, so I switched to gothic/metal theme this time. I have bigdoor6, metal and midgrate so far. I'll do some tweaks and I think it would be a good idea if I release all that stuff for tests.

wS5CNdS.jpg

kLVQs7W.jpg

cUnPDwN.jpg

titaMS2.jpg

 

A bit of tesselation:

P9g6fKT.jpg

 

metal:

zZOHjB3.jpg

Shh4lOM.jpg

2auFzDW.jpg

 

midgrate:

ycn2g66.jpg

jQ2hFpG.jpg

1aIRAO2.jpg

 

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×