DarkPlacesEngine / DarkPlaces

The official repo (replaces SVN). Branches `master` and `div0-stable` are synchronised with https://gitlab.com/xonotic/darkplaces. Merge requests should target the `master` branch.
https://icculus.org/twilight/darkplaces/
GNU General Public License v2.0
270 stars 39 forks source link

Extended texture loading capabilities in shaders #12

Open drwakey opened 2 years ago

drwakey commented 2 years ago

The idea is to be able to mix different diff, norm, spec etc. maps inside a shader, to create new materials without having tons of redundant texture files.

So in a shader this would look like that: diffusemap foo.tga normalmap foo_norm.tga specularmap foo_gloss.tga fullbrightmap foo_glow.tga reflectmask foo_reflect.tga

GremlinForester commented 2 years ago

This would be great to see, to add to this... shared image channels as texture inputs/overrides might be really useful to consider as well in further optimizing texture data, like RMAO in PBR or in DP's case maybe something more like GRBO with a 32bit TGA looking something like this maybe:

glossexponent = red reflect = green bump = blue opacity = alpha

Similar to an RMAO map in PBR, and for example if using that workflow you might have something like the following:

map textures/sometexture_color.tga (base color map/diffuse same as before used in stage)

These are overrides:

dpspecularmap textures/sometexture_color.tga (reuse RGB to tint gloss exponent/reflectmap) dpglossexponentmap textures/sometexture_rmao.tga 0 (use red channel as gloss exponent) dpreflectmap textures/sometexture_rmao.tga 1 (use green as reflectmap) dpoffsetmap textures/sometexture_rmao.tga 2 (use blue for offsetmapping) dpopacitymap textures/sometexture_rmao.tga 3 (used in stage to add to a 24bit or override the opacity of a 32bit) dpglowmap textures/somesharedtexture_add.tga (RGB glow map)

Or possibly: dpglowmap textures/sometexture_rmao.tga 3 (use alpha for white glow override?)

dpnormalmap textures/someothersubset/someothertexture_norm.tga (use any texture as normalmap/reuse same normalmap for multiple materials)

textures/somesubset/my_really_cool_opaque_lightmapped_material { dpGlossExponentMod 0.2 dpGlossIntensityMod 2.4 dpoffsetmapping - 3 match8 96 dpreflectcube cubemaps/generic //overrides dpspecularmap textures/sometexture_color.tga dpglossexponentmap textures/sometexture_rmao.tga 0 dpreflectmap textures/sometexture_rmao.tga 1 dpoffsetmap textures/sometexture_rmao.tga 2 dpnormalmap textures/someothersubset/someothertexture_norm.tga { map $lightmap rgbGen identity tcGen lightmap } { map textures/sometexture_color.tga rgbGen identity blendFunc GL_DST_COLOR GL_ZERO } }

Fun with opacity channel:

textures/somesubset/my_really_cool_dp_scrolling_lightmapped_material_with_opacity_override { dpGlossExponentMod 0.2 dpGlossIntensityMod 2.4 dpoffsetmapping - 3 match8 96 dpreflectcube cubemaps/generic //overrides dpspecularmap textures/sometexture_color.tga dpglossexponentmap textures/sometexture_rmao.tga 0 dpreflectmap textures/sometexture_rmao.tga 1 dpoffsetmap textures/sometexture_rmao.tga 2 dpnormalmap textures/someothersubset/someothertexture_norm.tga { map $lightmap rgbGen identity tcGen lightmap } { dpopacitymap textures/sometexture_rmao.tga 3 //add/override this as the material's alpha map textures/sometexture_color.tga blendfunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA tcMod scroll -0.3 -1.0 } }

If an override isn't specified it can still look for everything in the usual fashion, thus not breaking any compatibility with older mods/games (hopefully).

If you wanted to get REALLY fancy it would be neat to specify transforms or animated textures for specific blends, like an animated normalmap?

textures/somesubset/myreallycooldpmaterial { dpGlossExponentMod 0.2 dpGlossIntensityMod 2.4 dpoffsetmapping - 3 match8 96 dpreflectcube cubemaps/generic //overrides dpspecularmap textures/sometexture_color.tga dpglossexponentmap textures/sometexture_rmao.tga 0 dpreflectmap textures/sometexture_rmao.tga 1 dpoffsetmap textures/sometexture_rmao.tga 2 { map $lightmap rgbGen identity tcGen lightmap } { map textures/sometexture_color.tga rgbGen identity blendFunc GL_DST_COLOR GL_ZERO } { blend dpnormalmap //animated normal map frames animMap 30 textures/effects/rainywatersurface1.tga textures/effects/rainywatersurface2.tga textures/effects/rainywatersurface3.tga etc... } }

Sorry for going a bit overboard on this comment :D

Baker7 commented 4 months ago

The idea is to be able to mix different diff, norm, spec etc. maps inside a shader, to create new materials without having tons of redundant texture files.

So in a shader this would look like that: diffusemap foo.tga normalmap foo_norm.tga specularmap foo_gloss.tga fullbrightmap foo_glow.tga reflectmask foo_reflect.tga

Could you explain an example of use for this?

I am looking at the Q3 shader system and am looking to make some modifications.

Some examples: Quake 3 map format in DarkPlaces does not have a method to switch the textures on buttons that are pressed ("+" textures) .. I am also looking at automatic shader creation (if a cvar is enabled) for certain texture prefixes like "{" (alpha mask like Half-Life and what Quakespasm + derivatives do for textures with leading "{" ).

So while I am doing work in there, I want to see other ideas on the topic. Hemebond mentioned that fteqw does $diffuse support in shaders to use the Quake texture, for instance.

challenge4

chal

Baker7 commented 4 months ago

Sorry for going a bit overboard on this comment :D

This is a bit of a necrobump, but I am scouting out ideas while digging around in the Q3 shader system .. could you provide some insight into a practical application of this would be.

intermap_research

I made the above and although it is for Zircon Engine (my DarkPlaces fork), it renders just fine in DarkPlaces.

But while mapping in Quake 3, there are certain tedious things that get on my nerves like having to write a shader for every texture that needs a simple alpha mask (those shaders are so generic, they don't hardly ever vary except for the texture name) -- I'm looking to streamline and speedup the development of great looking maps that use DarkPlaces features by simplifying the process.

GremlinForester commented 4 months ago

Those are some nice looking materials and environments! Hopefully I won't go overboard on this again ;)

So one practical example would be red base, blue base textures that only need different diffuse but can share normalmaps. Or wet and dry material variants, damage? Basically more variety without redundant texture copies everywhere bloating up download size, or you could have a post install script that bloats things after the user downloads the mod/game/whatever. Or, how about no bloat at all?

In the end it's better to spend some extra dev time writing a shader than bloat up the textures folder imo. I'd personally also rather have control in the shader file for how I want to blend a material, like say you have 2 variants of the same grate texture, maybe there's a scenario where you don't want to mask, I think having that option is.. grate! :D

Baker7 commented 4 months ago

Hopefully I won't go overboard on this again ;)

I hope you do go overboard. Imagination in this world is in short supply, both you and Dr. Wakey have ideas, I've seen some of stuff you've made.

So one practical example would be red base, blue base textures that only need different diffuse but can share normalmaps.

Xonotic does this by making some of the .dds files a text file that names another texture. I'm not saying I like or dislike this method, I have no opinion either way.

I do get the bloat thing ... I made the Quake Retexturing Project + Normal Maps go on a diet from 1.2 GB to 0.12 GB ( https://www.moddb.com/mods/darkplaces-classic-set/downloads/quake-retexturing-project-and-normal-maps-1-00-baker-jpeg ) and I can't notice the difference.

Or wet and dry material variants, damage?

How would a map editor distinguish? I'm asking because I more spend time engine coding than anything else, if I spent more time mapping my thought process would be more balanced.

Note: The screenshot with the wood and the bricks ---> NO SHADERS. It's just _norm and _gloss. I'm a full open source guy and I'm here to share knowledge ...

Here is the wood ... https://www.texturecan.com/details/591/

I took the ambient occulsion and renamed it _gloss and the opengl_normalmap to _norm (obviously). This is not technically correct, but I am not sure how to completely make a gloss map, but one component is the ambient occulsion. It is in this tech demo https://www.moddb.com/mods/zircon-engine/downloads/2024-quake-omega-effects-challenge-series-1-of-20

I have been reading the comments on shaders in various threads and trying to collect information.

Then write the code to make it happen.

GremlinForester commented 4 months ago

I hope you do go overboard. Imagination in this world is in short supply, both you and Dr. Wakey have ideas, I've seen some of stuff you've made.

Ooh, thanks! I dig your work too! Also yay, figured out quotes!

Xonotic does this by making some of the .dds files a text file that names another texture. I'm not saying I like or dislike this method, I have no opinion either way.

Interesting alternative, same idea as it's just a reference to some data, I'm still on team shader though heh I just think they're great for organization, searchability, especially for those of us who constantly have notepad++ open :D Also damn that's some crazy difference in size eh?

How would a map editor distinguish? I'm asking because I more spend time engine coding than anything else, if I spent more time mapping my thought process would be more balanced.

So, in this case I'm imagining hypothetical level where maybe the sprinklers of a building have been going off for a while, water is pooling in some areas and there's water running down the walls, maybe cascading down stairs etc... I would make a dedicated shader for level designers to use called something like e#m#_wet and likely use a lot of custom qer_editorimage's with some transparent information denoting that the surface is a wet texture and whether there's a flow direction (assuming I can scroll individual stages). So at a glance in say NRC, you'll know just what surfaces are going to be wet, the direction of the scroll etc...

Hmm, it's been a little bit since I played with _gloss but iirc RGB is used to tint the specular and the alpha channel is your exponent mask and I think you can control in the shader with something like:

dpGlossExponentMod 0.4 dpGlossIntensityMod 0.7

https://omnicide.razorwind.ru/wiki/index.php/Darkplaces_material_system/General_Keywords#dpGlossIntensityMod_.3Cvalue.3E

I hope some of my ramblings made sense heh and that mod looks cool, I'll check it out!

Looking forward to seeing how things turn out, keep up the great work!

Baker7 commented 4 months ago

So, in this case I'm imagining hypothetical level where maybe the sprinklers of a building have been going off for a while, water is pooling in some areas and there's water running down the walls, maybe cascading down stairs etc... I would make a dedicated shader for level designers to use called something like e#m#_wet and likely use a lot of custom qer_editorimage's with some transparent information denoting that the surface is a wet texture and whether there's a flow direction (assuming I can scroll individual stages). So at a glance in say NRC, you'll know just what surfaces are going to be wet, the direction of the scroll etc...

That extends a little beyond my imagination in the sense I myself don't know how to make such a map off-hand --

If you could make a sample map with .map source code and textures that is only missing what you would need engine-side with extra shader support, I will see if I can make it work if you can tell me when I "get it right".

dpGlossExponentMod 0.4 dpGlossIntensityMod 0.7

I might meditate on that and see if I can think of the right way to make it so I change those in real-time with a console command so I can understand them better. I have read that wiki page before, Blood Omnicide DarkPlaces is where the waving water effect above comes from, I added it to the engine.

Considering Vortex -- whom I do not know and do not think I've ever interacted with -- did Blood Omnicide DarkPlaces (and BloodOmnicide is very ambitious to say the least) and wrote quite a bit in DarkPlaces, I'm slightly surprised that one and couple of others that don't require much code aren't in main DarkPlaces, but I understand that things like that can happen, especially in free projects.

GremlinForester commented 4 months ago

That extends a little beyond my imagination in the sense I myself don't know how to make such a map off-hand --

If you could make a sample map with .map source code and textures that is only missing what you would need engine-side with extra shader support, I will see if I can make it work if you can tell me when I "get it right".

Yea I don't know why I just didn't say a waterfall scene heh. Sure, I'll try to put something to test with together when I get a little extra time (unless someone beats me to it). But before things go off the rails into Doom3 materials or PBR stuff, it would be amazing to get skinframes referenced in the shader file as mentioned by drwakey.

diffusemap foo.tga
normalmap foo_norm.tga
specularmap foo_gloss.tga
fullbrightmap foo_glow.tga
reflectmask foo_reflect.tga

Just being able to do this would be amazing!

image

Baker7 commented 4 months ago

diffusemap foo.tga normalmap foo_norm.tga specularmap foo_gloss.tga fullbrightmap foo_glow.tga reflectmask foo_reflect.tga

I don't view that as hard, the plumbing will be a moderately annoying, but compared to some of the other texture rewiring I've done in the Q3 shader area (I made .dpv DarkPlaces video work-- and DarkPlaces Beta does not have a method to dynamic textures -- and then decided to I'd like animated gif and jpeg stream too).

I'll simply trust that it is useful and do it. Probably will be done no later than Tuesday.

Baker7 commented 4 months ago

This is what I am coding ...

There also probably needs to be a "none" keyword like "reflectmask none" or maybe "disable"

// Baker: I add "_sh" to the folder name to use a texture in shader form
// This allows me to use the real texture as-is or use a shader for it.
// Hence "texturescan_sh"
textures/texturescan_sh/bricks_0018
{
    qer_editorimage textures/texturecan/bricks_0018.tga 
    {
        // Baker: This is the diffusemap
        map textures/texturecan/bricks_0018.tga

        // normalmap, the traditional _norm so normmap
        normmap textures/texturecan/bricks_0018_norm2.tga

        // specularmap, the traditional _gloss so glossmap
        glossmap textures/texturecan/bricks_0018_gloss2.tga

        // fullbrightmap, the traditional _glow so glowmap
        glowmap textures/texturecan/bricks_0018_glow2.tga

        reflectmask textures/texturecan/bricks_0018_reflect2.tga
    }
}
Baker7 commented 4 months ago

An observation about current code

There is code like this ..

It is going to take the diffuse name found in

    {
        // Baker: This is the diffusemap
        map textures/texturecan/bricks_0018.tga
        }

And use that as the name of skinframe.

    for (j = 0; j < layer->numframes; j++)
        shaderpass->skinframes[j] = R_SkinFrame_LoadExternal(layer->texturename[j], texflags, false, true);

That will effectively block any alternate ways of using a texture. The diffuse texture name is used as the unique name of skinframe.

The skinframe then indicates the glossmap and normalmap and glowmap and reflect map.

I'm trying to think of the appropriate way to not lock the skinframe to the name of the diffuse map. One way would be to make a new name using the "shadername" and layer number.

However, that would spam a bit. Currently any instance of a diffusename is 1 skinframe. That would change. And I'm not sure how this would interact with purging a texture.

It seems the more appropriate solution would be to add support for more than 1 shader layer -- a current limitation of DarkPlaces.

Baker7 commented 4 months ago

An alternate approach ...

R_GetCurrentTexture sets t->nmaptexture = t->currentskinframe->nmap;

Then read by ... if (r_glsl_permutation->tex_Texture_Normal >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Normal , t->nmaptexture );

drwakey commented 4 months ago

Hoi, seems a lot is happening here :D So to catch up...

and DarkPlaces Beta does not have a method to dynamic textures Do you mean animated textures by that? Was the animMap keyword dropped from the DarkPlaces Beta?

If you wanted to get REALLY fancy it would be neat to specify transforms or animated textures for specific blends, like an animated normalmap?

Animated normalmaps can be done with animMap, with the drawback that one has to have as much useless (redundant) diffuse maps.

Quake 3 map format in DarkPlaces does not have a method to switch the textures on buttons that are pressed ("+" textures)

DarkPlaces has the dpShaderKillIfCvar keyword that could be abused for such a case, a dedicated keyword for changing materials would be very useful.

Beeing able to us multiple shader stages (or layers) would also prove very useful.

Baker7 commented 4 months ago

Welcome back, Dr. Wakey!

and DarkPlaces Beta does not have a method to dynamic textures Do you mean animated textures by that? Was the animMap keyword dropped from the DarkPlaces Beta?

No, animmap works fine. DarkPlaces video (.dpv) and the player setup menu if you change player colors --- basically by dynamic textures, ones where the pixels change -- like "playvideo" constantly updates the video image <-- that kind of dynamic texture.

Baker7 commented 4 months ago

DarkPlaces has the dpShaderKillIfCvar keyword that could be abused for such a case, a dedicated keyword for changing materials would be very useful.

I made "framemap". A button's natural state is frame 0, press it and becomes frame 1.

"framemap textures/blah.tga textures/blah2.tga"

hit_it

World's ugliest button, for sure, but I used the first 2 texture names I could find and they go together very poorly.

Beeing able to us multiple shader stages (or layers) would also prove very useful.

In time, it seems likely I will be doing that.

GremlinForester commented 4 months ago

Dr.Wakey!! :)

@Baker7 Framemap sounds fantastic and not just as a solution for buttons on q3bsp! A lot can be done with that! I'm just about to head to bed so this might be a dumb question but would that also work if I wanted to point to shaders as well?

Baker7 commented 4 months ago

Dr.Wakey!! :)

@Baker7 Framemap sounds fantastic and not just as a solution for buttons on q3bsp! A lot can be done with that! I'm just about to head to bed so this might be a dumb question but would that also work if I wanted to point to shaders as well?

It works exactly like animmap, so whatever animmap does. You have far more Q3 mapping experience than myself, so whatever animmap supports.

This is available in Zircon Beta #47 https://www.moddb.com/mods/zircon-engine/downloads/zircon-beta-release-47-win64-linux-binaries-source

GremlinForester commented 4 months ago

So I managed to get around to getting something together to try and make more sense of my "wet ramblings", so in the editor you would have a bunch of editor textures (see below) which help convey more info on what the surface may be doing, and make it more subtle if the level designer complains about your giant arrows :D

Actually this turned out to be another of of those few times where you can actually reuse textures in DP but in a very limited way by basically cranking up the shine.

editor_textures editor_textures2 editor_textures2_ingame

So, just using the gloss keywords in the shader there's a _wet variant. Also I thought the following pack may be useful to build off of and test with as sort of a before/after/comparison as things progress. idk?

There's a lot of brush layering and such, it would be cool if eventually stuff like the ripples could be done as a separate shader stage.

Map test_mat2, includes info_player_start and info_player_deathmatch.

download test_mat2.pk3

Note: hopefully the above works!

Baker7 commented 4 months ago

Oh wow! Need to download that.

270 MB, haha

On a related note, I gave the Quake Retexture Project 1.2 GB a massive diet a few weeks ago ... became 0.18 GB

https://www.moddb.com/mods/darkplaces-classic-set/downloads/quake-retexturing-project-and-normal-maps-1-00-baker-jpeg

Baker7 commented 4 months ago

So I managed to get around to getting something together to try and make more sense of my "wet ramblings", so in the editor you would have a bunch of editor textures (see below) which help convey more info on what the surface may be doing, and make it more subtle if the level designer complains about your giant arrows :D

Actually this turned out to be another of of those few times where you can actually reuse textures in DP but in a very limited way by basically cranking up the shine.

editor_textures editor_textures2 editor_textures2_ingame

So, just using the gloss keywords in the shader there's a _wet variant. Also I thought the following pack may be useful to build off of and test with as sort of a before/after/comparison as things progress. idk?

There's a lot of brush layering and such, it would be cool if eventually stuff like the ripples could be done as a separate shader stage.

Map test_mat2, includes info_player_start and info_player_deathmatch.

download test_mat2.pk3

Note: hopefully the above works!

Wow! That is NICE!!!!!!!!!

Is it ok if I mirror this and share it and do it as a news thingy on the Zircon Engine page?

I'm laughing because that is 10x times awesome. I'm rather solid at making nice stuff, but your stuff is 10x nicer than mine, haha!

ADD: OMG the sprinklers!!! 🙂

GremlinForester commented 4 months ago

Yea I saw your diet pack, awesome example of how different formats can make all the difference! This could probably be much smaller as well if it wasn't all TGA but meh, those textures are so nice it would be a crime to save them out in a lossy format!

Is it ok if I mirror this and share it and do it as a news thingy on the Zircon Engine page?

Sure, it's there for all. It's just a converted texture set and a bunch of crap pulled from the internet. https://www.evillair.net/v4/gametextures/ there's also another set https://forums.xonotic.org/showthread.php?tid=8477 which I probably should have done some googling beforehand but hey all part of the experience.

Yea the water turned out pretty good, I hope it helps demonstrate how creating many more variations could lead to more rich environments without having to add more textures. It would be neat to expand on this and see if we can make the download size smaller while doubling the amount of variations and effects and such using your code fixes/implementations and such!

Baker7 commented 4 months ago

Sure, it's there for all. It's just a converted texture set and a bunch of crap pulled from the internet. https://www.evillair.net/v4/gametextures/ there's also another set https://forums.xonotic.org/showthread.php?tid=8477 which I probably should have done some googling beforehand but hey all part of the experience.

Great!

Yea the water turned out pretty good, I hope it helps demonstrate how creating many more variations could lead to more rich environments without having to add more textures.

I need hit the specular/diffuse thing in attempt #2 (first attempt, it became clear I was using wrong approach, I need to take the approach that dpreflect uses internally, I looked at the glsl and I think that is a more workable approach inside the engine), I've been a little bit bogged down hammering some other issues I found.

I found a crash in renderer restart that DarkPlaces Classic had and finally fixed a few hours ago .. which would crash with ALT-ENTER fullscreen switch ... with the following ...

(Which comes in open source flavor or by adding a Pac-Man graphics .pk3, becomes Pac-Man).

packardman

packardman2

Baker7 commented 4 months ago

mattest2_sprinkler2'

mattest2_move

mattest2_rain1

drwakey commented 4 months ago

Another very useful keyword which could use some love is "deformVertexes". It can be used to animate things like grasblades and other foliage, flags, water surfaces or anything that should "wave around".

Problem is, (afaik) for now it is calculated on the cpu, which limits is usage to a few objects. If the vertex transform function cannot be easily ported to the gpu, may be a "distance" paramater could be implemented, so that a mapper could limit how many vertex tranforms are calculated at once?

8mn6ew

Also another thing i noticed is, that if "deformVertexes" is used in conjunction with "dpWater", the the reflections glitch. Not a surprise, as dpwater was propably written with planar surfaces in mind.

To further enhance the usefulness of maybe new wavefroms could be added, something like some pre defined fast fourier transforms?

Baker7 commented 4 months ago

Wakey, if you drag and drop a gif file into the text area it uploads it, fyi.

On Sat, Apr 13, 2024 at 7:14 AM drwakey @.***> wrote:

Another very useful keyword which could use some love is "deformVertexes". It can be used to animate things like grasblades and other foliage, flags, water surfaces or anything that should "wave around".

Problem is, (afaik) for now it is calculated on the cpu, which limits is usage to a few objects. If the vertex transform function cannot be easily ported to the gpu, may be a "distance" paramater could be implemented, so that a mapper could limit how many vertex tranforms are calculated at once?

8mn6ew.gif (view on web) https://github.com/DarkPlacesEngine/darkplaces/assets/91730449/6b480143-fb1c-47d9-a934-345fc76b93f0

Also another thing i noticed is, that if "deformVertexes" is used in conjunction with "dpWater", the the reflections glitch. Not a surprise, as dpwater was propably written with planar surfaces in mind.

To further enhance the usefulness of maybe new wavefroms could be added, something like some pre defined fast fourier transforms?

— Reply to this email directly, view it on GitHub https://github.com/DarkPlacesEngine/darkplaces/issues/12#issuecomment-2053616151, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABHD7I345AMBANKHHE3GSDY5EHRDAVCNFSM5FELZBFKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMBVGM3DCNRRGUYQ . You are receiving this because you were mentioned.Message ID: @.***>

drwakey commented 4 months ago

Sorry i wasnt aware, thanks for the info! Can the gif be removed then?

Baker7 commented 4 months ago

Sure, no problem.

On Sun, Apr 14, 2024 at 4:14 AM drwakey @.***> wrote:

Sorry i wasnt aware, thanks for the info! Can the gif be removed then?

— Reply to this email directly, view it on GitHub https://github.com/DarkPlacesEngine/darkplaces/issues/12#issuecomment-2053958653, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABHD7OMEV6YBHNZLIAFNCLY5I3G7AVCNFSM5FELZBFKU5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TEMBVGM4TKOBWGUZQ . You are receiving this because you were mentioned.Message ID: @.***>