[FTEQW]Fake reflections via cubemaps

Discuss the creation of various model formats for Quake engines, and related matters to modeling.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

[FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [FTEQW]Fake reflections via cubemaps

Post by Spike »

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.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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!
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [FTEQW]Fake reflections via cubemaps

Post by Spike »

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.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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!
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [FTEQW]Fake reflections via cubemaps

Post by Spike »

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
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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!
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [FTEQW]Fake reflections via cubemaps

Post by Spike »

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.
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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.
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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
Meadow Fun!! - my first commercial game, made with FTEQW game engine
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: [FTEQW]Fake reflections via cubemaps

Post by Spike »

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).
toneddu2000
Posts: 1395
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: [FTEQW]Fake reflections via cubemaps

Post by toneddu2000 »

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
Meadow Fun!! - my first commercial game, made with FTEQW game engine
xaGe
Posts: 465
Joined: Wed Mar 01, 2006 8:29 am
Location: Upstate, New York
Contact:

Re: [FTEQW]Fake reflections via cubemaps

Post by xaGe »

Nice!
Post Reply