Forum

[FTEQW]Fake reflections via cubemaps

Discuss the creation of various model formats for Quake engines, and related matters to modeling.

Moderator: InsideQC Admins

[FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Sun Feb 15, 2015 7:07 pm

Is it possible to use cubemaps in FTEQW? How? What kind of extension should have cubemap textures? Which is the shader property should I use?
Thanks guys
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby Spike » Sun Feb 15, 2015 7:23 pm

map $cube:foo

then write some glsl with samplerCube s_t0 (or 1 etc according to which 'pass' you listed it as) + textureCube function to read it.
there's meant to be some 'tcgen reflect' to go with cubemaps, but it never got implemented. fixed-function stuff sucks anyway.
Spike
 
Posts: 2881
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: [FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Sun Feb 15, 2015 7:33 pm

sorry Spike but I didn't understand a word! :lol:
Do you mean there's not a cook&eat method, ready to use like map $normalmap in shader, right? Because I can't write glsl code and probably I'll never be proficient to :(
There's some code I can use somewhere?
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Sun May 03, 2015 2:12 am

Ok, after a lots of trial and error I got ALMOST working.
I created a shader
Code: Select all
textures/world/wall_white
{
   program ton_cubemaps
   {
        map $cube:textures/cubes/sky
   }
   {
      map $diffuse
   }
   {
      map $normalmap
   }   
}

Then I created a glsl/ton_cubemaps.glsl file
Code: Select all
varying vec2 tc;
varying vec4 tf;
varying vec3 norm;
varying vec3 eye;
uniform samplerCube s_t0;   
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
attribute vec3 v_normal;
uniform vec3 e_eyepos;
void main (void)
{
tc = v_texcoord.st;
tf = ftetransform();
norm = v_normal;
eye = e_eyepos - v_position.xyz;
gl_Position = tf;
}
#endif


#ifdef FRAGMENT_SHADER
void main()
{
vec3 reflectedDirection = reflect(eye, normalize(norm));;
gl_FragColor = textureCube(s_t0, reflectedDirection);
}

#endif

Which it's a mix of altwater.glsl and this one from Unity community (I had to mix them because vertex shader from Unity didn't work).

and finally created a cubes texture folder with 6 .tgas: skynx.tga, skyny.tga, skynz.tga, skypx.tga, skypy.tga, skypz.tga
Now it shows a cubemap on the walls BUT:
1)diffuse and normal maps are hidden now and the only texture that it's visible is the cubemap one
2)a giant wireframe cube appears in the middle of the world

I tried also to add a second diffuse pass in fragment shader
Code: Select all
//#define diffusepass s_t1
//uniform sampler2D diffusepass; //diffuse

or to decrease gl_FragColor alpha
Code: Select all
gl_FragColor.a = 0.1
but nothing has effect, only the cubemap is visible.
Please Spike, can you please explain where I'm wrong? Thanks a lot for your great help!
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby Spike » Sun May 03, 2015 9:01 pm

I've updated fte's built-in defaultwall+rtlight programs to sample from 'reflectcube' and 'reflectmask' textures to provide cubemap reflections over a masked area (additive with diffuse+specular, and scaled by lightmaps/rtlights).
The following shader should generally do what you would expect (hopefully). Set up the textures as you see fit.
Code: Select all
textures/world/wall_foobar2000
{
    program defaultwall
    //diffusemap $blackimage   //default is textures/world/wall_foobar2000.tga of course
    normalmap $identitynormal   //identity ensures that we get a perfect reflection for this example (otherwise it'll default to something based upon the shader name, or possibly even generate one from the 8bit data in a q1bsp).
    //specularmap $blackimage
    //fullbrightmap $blackimage
    reflectcube textures/cubes/sky   //your cubemap image(s) to display
    reflectmask $whiteimage   //texture that says which parts of the texture should show the reflection. white for on, black for off. tint for various types of metal.
}


you can find the official version of the built-in glsl code here: http://sourceforge.net/p/fteqw/code/HEA ... ders/glsl/
the reflectcube term just provides the glsl with an s_reflectcube texture, and causes s_reflectmask is normally automatically loaded from a foo_reflect.tga file but can be specified explicitly as in my example above.
Spike
 
Posts: 2881
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: [FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Mon May 04, 2015 1:07 am

ok, first of all: THANKS a lot Spike for your help!
FTE crashes when loading your defaultwall.glsl. I tried loading also old defaultwall, eg_defaultwall, and eg_drawflat_wall and they all crash. The others work.
Now, after a lot of study, thanks to your files, I understood (hopefully!) how passes work in GLSL and FTE
when you declare a texture 2d
Code: Select all
uniform sampler2D   s_t0;

That will be the first in the shader block from the top, s_t1 will be the second, s_t2 the third and so on.

That's how I re-managed your file to make it work
Code: Select all
#include "sys/defs.h"
varying vec3 eyevector;
varying mat3 invsurface;
varying vec2 tc;

#ifdef VERTEX_SHADER
void main ()
{
   vec3 eyeminusvertex = e_eyepos - v_position.xyz;
   eyevector.x = dot(eyeminusvertex, v_svector.xyz);
   eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
   eyevector.z = dot(eyeminusvertex, v_normal.xyz);
   invsurface[0] = v_svector;
   invsurface[1] = v_tvector;
   invsurface[2] = v_normal;
   tc = v_texcoord;
   gl_Position = ftetransform();
}
#endif

#ifdef FRAGMENT_SHADER
//samplers
uniform sampler2D   s_t0;//diffuse pass
uniform sampler2D   s_t1;//cubemask pass - mask to choose which part cubemap affects
uniform samplerCube   s_t2;//cubemap pass
void main ()
{
   gl_FragColor = texture2D(s_t0, tc);//yay, regular texture!
   vec3 norm = vec3(0, 0, 1);   //specular lighting expects this to exist.
   vec3 rtc = reflect(-eyevector, norm);
   rtc = rtc.x*invsurface[0] + rtc.y*invsurface[1] + rtc.z*invsurface[2];
   rtc = (m_model * vec4(rtc.xyz,0.0)).xyz;
   gl_FragColor.rgb += texture2D(s_t1, tc).rgb * textureCube(s_t2, rtc).rgb;
   gl_FragColor = gl_FragColor * e_colourident;
}
#endif


Now, the shader
Code: Select all
textures/wall/wallfoo
{
   program ton_cubemaps
   {
      map textures/wall/wallfoo.tga //diffuse texture
   }
   {
      map textures/wall/wallfoo_reflect.tga //mask to choose which part cubemap affects
   }
   {
      map $cube:textures/cubes/sky //cubemap
   }
}

With your great shader now I can make very cool effect: you were right, cubemask (especially when colored) permits to simulate metal! Cool! :D
The only thing it doesn't work it's $lightmap. If I add:
Code: Select all
   {
      map $lightmap
   }
It removes cubemap. I tried to add another pass s_t3 copying from your glsl file
Code: Select all
varying vec2 lm0;
vec3 lightmaps = (texture2D(s_t3 , lm0) * e_lmscale).rgb;
gl_FragColor.rgb *= lightmaps.rgb;

But engine yells a warning that it can't find v_lmcoord and e_lmscale


The only thing I don't understand it's why earlier you wrote this shader like this
program defaultwall
//diffusemap $blackimage //default is textures/world/wall_foobar2000.tga of course
normalmap $identitynormal //identity ensures that we get a perfect reflection for this example (otherwise it'll default to something based upon the shader name, or possibly even generate one from the 8bit data in a q1bsp).
//specularmap $blackimage
//fullbrightmap $blackimage
reflectcube textures/cubes/sky //your cubemap image(s) to display
reflectmask $whiteimage //texture that says which parts of the texture should show the reflection. white for on, black for off. tint for various types of metal.

"normalmap" for example, doesn't not exist in FTE source code, "reflectcube" neither. In your defaultwall.glsl there were s_reflectcube and s_normalmap. Are they related to those directive you wrote in the shader?
Thanks again for your huge help!
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby Spike » Mon May 04, 2015 9:25 am

http://sourceforge.net/p/fteqw/code/HEA ... er.c#l2107

side note: using the word shader for both materials and glsl code is stupid. oh well.

the s_normalmap stuff comes from a reworking I made 1-2 months ago. the engine automatically inserts the map lines/blocks into your shader based upon the specially-named textures in your glsl. this means you don't need map $diffuse, map $normalmap, map $deluxemap, map $lightmap, map $fullbright, map $upper, map $lower... you get the idea. this separates the shader from the glsl a little more which can only be a good thing (the worst part was that the order needed to match).

internally the engine has a shader override system, this includes stuff like the rtlight shader. these shaders 'inherit' their named s_diffuse/$diffuse etc textures from the original shader that they are replacing, which is how fte uses one rtlight shader (with permutations based upon texture availability) for pretty much everything.
naturally you can use 'bemode rtlight othershader' to specify a different override for the rtlight passes. there's a few other backend modes that you can provide alternative shaders for like that. the terrain system does this too, of course (which uses the lightmap to mix 4 underlying textures, which means it can't use the regular rtlight logic as that assumes there is only a single diffusemap).

unfortunately not all surfaces define all texture maps (or might define them but fail to load them perhaps). unspecified texture maps often have some awkward default of 0,0,0,1 (which is why s_lightmap is meant to end up as 1,1,1,1).
note that certain bsp formats(rbsp+fbsp, but not q3bsp) have multiple lightmaps per face (now introducing the LIGHTSTYLED permutation!)
You should probably figure out the various permutations in order to avoid this from being an issue (as well as to avoid wasting gpu time on logic that just isn't relevant).
e_lmscale can end up as 0 if r_shadow_realtime_world_lightmap is 0.
v_lmcoord is a vertex attribute and is thus only valid in the vertex shader. e_lmscale is a uniform and should be usable in either (but usefully the fragment shader). both should be included in the "sys/defs.h" header
Spike
 
Posts: 2881
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: [FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Mon May 04, 2015 11:29 am

You're the best, man, seriously! :D
Now, with your new rtlight.glsl and this shader convention:
Code: Select all
textures/world/wall_white
{   
   program rtlight
   diffusemap textures/world/wall_white.tga
   reflectcube textures/cubes/sky
   reflectmask textures/world/wall_reflect.tga
   normalmap textures/world/wall_white_norm.tga
   specularmap textures/world/wall_spec.tga
}

It renders beautifully! The only (very subtle) problem is that, when player view changes pitch orientation, illumination changes abruptly. Don't know why but I'll study it

Justy few more question now that I'm starting understand something :)
1)You said in this post that "the !!permu thing at the start is another fteism. Each glsl file/block can optionally define multiple permutations, which means that certain steps can be skipped to avoid unneeded work. The shader knows which permutation it is based on #defines that the engine sets up before compiling the glsl."
So, basically, I could create anothere glsl file, copy the !!permu at the start of the rtlight.glsl (for example) to inherit all the properties of that shader without rewrite them, but just writing into the shader block #REFLECTCUBEMASK or #BUMP after glsl file?

2)what is r_glsl_pcf cvar? The engine doesn't say anything about that. Is it related to realtime shadows?

#EDIT 3) There'a way to "render" cubemaps inside the engine?

Thanks A LOT for your explanations, I'm learning so much thanks to you!
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby Spike » Mon May 04, 2015 2:00 pm

the rtlight glsl code assumes that there is an active rtlight. which can be stale if not used within the rtlight backend mode. as you look at different parts of the map, a different rtlight will be left selected, hence the illumination changes.
use defaultwall for a lightmapped wall. if its a q3bsp, you will likely need to include a {map $lightmap} block in order to get q3map2 to actually generate a lightmap for that surface.
Spike
 
Posts: 2881
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: [FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Mon May 04, 2015 4:58 pm

yep, that did the trick, thanks a lot Spike! I really cannot understand why FTE crashed yesterday.
Code: Select all
textures/world/wall_white
{   
   program spike_defaultwall
   diffusemap textures/world/wall_white.tga
   reflectcube textures/cubes/sky
   reflectmask textures/world/wall_reflect.tga
   normalmap textures/world/wall_white_norm.tga
   {
      map $lightmap
   }
}

I don't use lightmaps. Only dynamic lights. Is it $lightmap good for dynamic light too, isn't it?
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Thu May 07, 2015 1:34 am

Image
A simple test showing cubemaps in FTEQW. Model "BMW M6 2006" courtesy by Fred C. M'ule jr. ('tyrant monkey') on BlendSwap. Floor is realtime reflection, car is cubemapped. Every glsl used is available below.
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Wed May 27, 2015 11:18 am

rtlight glsl works great for static meshes but look what happens when it's applied to a skeletal mesh.
Image
The model is duplicated: one silhouette T-pose model is static and the animated cubemapped model is like 50% transparent. Why?
Thanks in advance Spike for any clarification
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby Spike » Wed May 27, 2015 7:17 pm

static world lighting and depth comes from the glsl code specified directly in the shader.
rtlights are an additive pass applied per-light, specified within a 'bemode rtlight' block. if omitted, the engine will use its own rtlight fallback (note that the default rtlight glsl code has lots of extra light uniforms to determine those per-light contributions, including shadowmapping logic).
Spike
 
Posts: 2881
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Re: [FTEQW]Fake reflections via cubemaps

Postby toneddu2000 » Wed May 27, 2015 8:00 pm

Yeah, that did the trick! Thanks a lot Spike!!

1)renamed glsl/rtlight.glsl to glsl/spike_rtlight.glsl (to avoid confusion with engine rtlight glsl file)
2)than, in the shader changed
Code: Select all
program rtlight
to
Code: Select all
bemode rtlight spike_rtlight

Image
Huge thanks man! :D
toneddu2000
 
Posts: 1305
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Postby xaGe » Sun May 31, 2015 12:34 am

Nice!
User avatar
xaGe
 
Posts: 461
Joined: Wed Mar 01, 2006 8:29 am
Location: Upstate, New York

Next

Return to Modeling

Who is online

Users browsing this forum: No registered users and 1 guest