Jump to content
The Dark Mod Forums

vertex/fragment programs


ungoliant

Recommended Posts

alright i've done enough experimentation and research into this crap that I'm sufficiently sick of it. What is the deal with vp and vfp files? I know they are written for OpenGL in assembly, and D3 has specific keywords built to call the programs and pass parameters to them inside of shaders, but thats about it. I cannot gleam anything from the files themselves as to the context of any of the damn parameters they are talking about, particularly with heathaze, which is of great interest to me.

 

D3 and TDM seem to make use of 3 heathazes,

 

heatHaze.vfp

heatHazeWithMask.vfp

heatHazeWithMaskAndVertex.vfp

 

no idea what mask or vertex they are talking about, wth?

 

What is the difference between fragmentMap and vertexParm???? what is the difference between fragmentProgram and vertexProgram, and program, and why can you reference heathaze from any? what do those damn parameters do in the first place?

 

what is the difference between

 

vertexProgram heatHazeWithMask.vfp
vertexParm 0 time * 0.1 , time * 0.5
vertexParm 1 1.5
fragmentProgram heatHazeWithMask.vfp
fragmentMap 0 _currentRender
fragmentMap 1 textures/sfx/vp1
fragmentMap 2 textures/water_source/vp_water

 

and

 

program heatHaze.vfp
vertexParm 0 time * 0.1 , time * 0.1 // scroll
vertexParm 1 0.5 //magnitude
fragmentMap 0 _currentRender
fragmentMap 1 textures/water/refraction_local.tga

Link to comment
Share on other sites

they create that wobbly effect on the surface of liquids, and the wobbly effect under the water.

 

according to doom3 base vp_materials file

 

textures/sfx/vp1

{

deform sprite

nonsolid

translucent

{

vertexProgram heatHazeWithMask.vfp

vertexParm 0 time * 0.1 , time * 0.5 // texture scrolling

vertexParm 1 0.9 // magnitude of the distortion

fragmentProgram heatHazeWithMask.vfp

fragmentMap 0 _currentRender

fragmentMap 1 textures/sfx/vp1.tga // the normal map for distortion

fragmentMap 2 textures/sfx/vp1_alpha.tga // the distortion blend map

}

 

 

}

 

kind of explains each line

 

and this is whats in the heatHazeWithMask.vfp

 

!!ARBvp1.0 OPTION ARB_position_invariant ;

 

# input:

#

# texcoord[0] TEX0 texcoords

# color vertex color for particle fading, will be multiplied by the mask texture

#

# local[0] scroll

# local[1] deform magnitude (1.0 is reasonable, 2.0 is twice as wavy, 0.5 is half as wavy, etc)

#

# output:

#

# texture 0 is _currentRender

# texture 1 is a normal map that we will use to deform texture 0

# texture 2 is a mask texture

#

# texCoord[0] is the model surface texture coords unmodified for the mask

# texCoord[1] is the model surface texture coords with a scroll

# texCoord[2] is the copied deform magnitude

# color is the copied vertex color

 

TEMP R0, R1, R2;

 

# texture 0 takes the texture coordinates unmodified

MOV result.texcoord[0], vertex.texcoord[0];

 

# texture 1 takes the texture coordinates and adds a scroll

ADD result.texcoord[1], vertex.texcoord[0], program.local[0];

 

# texture 2 takes the deform magnitude and scales it by the projection distance

PARAM vec = { 1, 0, 0, 1 };

 

MOV R0, vec;

DP4 R0.z, vertex.position, state.matrix.modelview.row[2];

 

DP4 R1, R0, state.matrix.projection.row[0];

DP4 R2, R0, state.matrix.projection.row[3];

 

# don't let the recip get near zero for polygons that cross the view plane

MAX R2, R2, 1;

 

RCP R2, R2.w;

MUL R1, R1, R2;

 

# clamp the distance so the the deformations don't get too wacky near the view

MIN R1, R1, 0.02;

 

MUL result.texcoord[2], R1, program.local[1];

 

MOV result.color, vertex.color;

 

END

 

#======================================================================

 

!!ARBfp1.0

OPTION ARB_precision_hint_fastest;

 

# texture 0 is _currentRender

# texture 1 is a normal map that we will use to deform texture 0

# texture 2 is a mask texture

#

# env[0] is the 1.0 to _currentRender conversion

# env[1] is the fragment.position to 0.0 - 1.0 conversion

 

TEMP localNormal, mask, R0;

 

PARAM subOne = { -1, -1, -1, -1 };

PARAM scaleTwo = { 2, 2, 2, 2 };

 

# load the distortion map

TEX mask, fragment.texcoord[0], texture[2], 2D;

 

# kill the pixel if the distortion wound up being very small

MUL mask.xy, mask, fragment.color;

SUB mask.xy, mask, 0.01;

KIL mask;

 

# load the filtered normal map and convert to -1 to 1 range

TEX localNormal, fragment.texcoord[1], texture[1], 2D;

MOV localNormal.x, localNormal.a;

MAD localNormal, localNormal, scaleTwo, subOne;

MUL localNormal, localNormal, mask;

 

# calculate the screen texcoord in the 0.0 to 1.0 range

MUL R0, fragment.position, program.env[1];

 

# offset by the scaled localNormal and clamp it to 0.0 - 1.0

MAD_SAT R0, localNormal, fragment.texcoord[2], R0;

 

# scale by the screen non-power-of-two-adjust

MUL R0, R0, program.env[0];

 

# load the screen render

TEX result.color.xyz, R0, texture[0], 2D;

 

END

 

thats whhats in doom3 base pak000.pk4 /glprogs

Edited by stumpy
Link to comment
Share on other sites

yeah i've seen all this before. It kind of says what each line is in a cryptic way that is totally greek to me. Still doesn't explain why the fragmentMap parms seem to match up with the output section of the program. Is the vfp actually constantly writing to those .tga files during the game or something? still clueless

Link to comment
Share on other sites

The Vertex and Fragment Programs are the actual instructions as performed by your GPU. It allows you to do more complicated blend operations or looking up neighbouring fragments (via the bound fragmentMap) - the "blur" and "heat haze with blur" fragment programs are doing that, if you need an example to look at.

 

Though to be honest, it doesn't really sound like this is a topic for you, as a mapper. It's a highly specialised area and you'll need to know exactly what result you want to achieve before diving into GPU assembly.

Link to comment
Share on other sites

Vertex programs and fragment programs are two different stages in the rendering pipeline.

 

Vertex programs take vertices as input (points in space, with 3D coordinates, UV coordinates, vertex colours and various other attributes) and output possibly-transformed vertex information to the fragment processing stage. A vertex program could change the colour of vertices, for example, or displace them in 3D space.

 

Fragment programs take the output of the vertex program as input, along with textures and other attributes provided by the main program, and rasterise the geometry into coloured pixels (actually "fragments", which are similar but not identical to screen pixels). A fragment program would be responsible for performing bump mapping, and any other operation which affects the conversion of geometry into pixels.

 

The fragmentProgram and vertexProgram keywords allow a material stage to supply a custom program for either the vertex processing or the fragment processing stage. For convenience, the Doom 3 .vfp file format contains both a vertex program and a fragment program (although in many cases the vertex program does nothing and simply passes through unchanged vertex data to the fragment program), and the program keyword is a shorthand form for specifying that both vertex and fragment programs from the same .vfp file should be used.

Link to comment
Share on other sites

  • 2 months later...

I have been pouring over the vfp's with my scant free-time and see that there are some digestible operations.

 

I think with that, unlike other engines, the material definition and blend design process is a good stepping-stone to "shader understanding" as it is a close parallel to the way that hardware actually processes these operations.

 

While I doubt that many members would ever come close to mastering the existing material blend system enough where they would need to "move-on" to the GPU level, (I don't think anyone has actually fully mastered it anyway...) it might be helpful to understand (to some degree) how a vfp affects the results of a material blend (for example).

 

It would be cool if we had a simple explanatory example for ARB vfp syntax example in a similar manor that this modwiki article shows explicit blend syntax:

 

http://www.modwiki.net/wiki/OpenGL_Blendmode_%28Materials%29

 

It obviously won't help for shaders that are like:

 

"See this complex 20 variable equation? I'm approximating it by multiplying two registers and subtracting the following decimal value."

 

...but perhaps some degree of what is "under the hood" can be de-mystified and that may (at least) lead to better material designs.

 

I personally would love to know how Doom transmits cubemap samples to a material stage and whether a vfp can inherit custom cubemap data or be coerced to perform a cubemap sample operation from the six tga textures it is made of?

 

Any takers for a layman's ARB shader wiki?

 

(please :) )

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Link to comment
Share on other sites

Good luck ungoliant!

 

I wonder if you could just call each vfp in a separate stage in the same material definition?

 

I know that even sikkpin uses the material definitions to pull-off tricks that cannot be done entirely in one vfp.

 

Another sikkpin trick is to place an invisible patch in front of the viewer so that post processing effects can be rendered to that surface and look like they are being applied to the whole scene.

 

(you should check out the Test 5 pk4's at D3W...)

 

I will do so again as well to see if I can fathom anything relevant...

Edited by nbohr1more

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Link to comment
Share on other sites

I wonder if you could just call each vfp in a separate stage in the same material definition?

 

to the best of my knowledge, it is impossible to use 2 vfps in one shader. Thats the whole purpose of the undertaking. Believe me i've tried.

 

Haven't heard of these Test 5 pk4s i'll probably look into that.

Edited by ungoliant
Link to comment
Share on other sites

Yep, sikkpin's definitions show many vfp's in one material definition. It appears that he is using conditional "If" shaderparms for each vfp invoke.

 

Just following by example you could probably combine the two vfp's with a meaningless conditional (one that always satisfies the "If")?

 

postProcess/softShadows
{
sort	postProcess

// soft shadow sample
{
	if ( Parm3 == 0.0 )
	Program		ss_sample.vfp
	fragmentMap	0		_ssRender
	fragmentMap	1		_currentRender
}

// shadow mask blur
{
	if ( Parm0 == 1.0 && Parm3 == 1.0 )
	Program		ss_blur_box.vfp
	vertexParm	0		Parm1		// offset scale
	vertexParm	1		Parm2		// epsilon
	fragmentMap	0		_ssMask
	fragmentMap	1		_ssDepth
	fragmentMap	2		_currentRender
}
{
	if ( Parm0 == 2.0 && Parm3 == 1.0 )
	Program		ss_blur_poisson.vfp
	vertexParm	0		Parm1		// offset scale
	vertexParm	1		Parm2		// epsilon
	fragmentMap	0		_ssMask
	fragmentMap	1		_ssDepth
	fragmentMap	2		_currentRender
}
{
	if ( Parm0 == 3.0 && Parm3 == 1.0 )
	Program		ss_blur_x.vfp
	vertexParm	0		Parm1		// offset scale
	vertexParm	1		Parm2		// epsilon
	fragmentMap	0		_ssMask
	fragmentMap	1		_ssDepth
}
{
	if ( Parm0 == 4.0 && Parm3 == 1.0 )
	Program		ss_blur_y.vfp
	vertexParm	0		Parm1		// offset scale
	vertexParm	1		Parm2		// epsilon
	fragmentMap	0		_ssMask
	fragmentMap	1		_ssDepth
	fragmentMap	2		_currentRender
}


// final blend for unblurred shadow mask
{
	if ( Parm3 == 2.0 )
	Program		ss_blend.vfp
	fragmentMap	0		_currentRender
	fragmentMap	1		_ssMask
}
}

_ssRender { { 
map		_ssRender
} }
_ssMask { { 
map		_ssMask
} }
_ssDepth { { 
map		_ssDepth
} }

ssRender
{
sort	postProcess
{
	map			_ssRender
	scale		1, -1
	translate 	0, -1
} 
}
ssMask
{
sort	postProcess
{
	map			_ssMask
	scale		1, -1
	translate 	0, -1
} 
}
ssDepth
{
sort	postProcess
{
	map			_ssDepth
	scale		1, -1
	translate 	0, -1
} 
}

Edited by nbohr1more

Please visit TDM's IndieDB site and help promote the mod:

 

http://www.indiedb.com/mods/the-dark-mod

 

(Yeah, shameless promotion... but traffic is traffic folks...)

Link to comment
Share on other sites

ah.. allow me to re-iterate.

to the best of my knowledge, it is impossible to run 2 vfps simultaneously in one shader.

 

looks like according to that shader, those if's are exclusive.

 

edit: then again with multiple calls, maybe they dont need to. actually, I'm not really sure wth is going on in that thing.

Edited by ungoliant
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recent Status Updates

    • nbohr1more

      The FAQ wiki is almost a proper FAQ now. Probably need to spin-off a bunch of the "remedies" for playing older TDM versions into their own article.
      · 1 reply
    • nbohr1more

      Was checking out old translation packs and decided to fire up TDM 1.07. Rightful Property with sub-20 FPS areas yay! ( same areas run at 180FPS with cranked eye candy on 2.12 )
      · 3 replies
    • taffernicus

      i am so euphoric to see new FMs keep coming out and I am keen to try it out in my leisure time, then suddenly my PC is spouting a couple of S.M.A.R.T errors...
      tbf i cannot afford myself to miss my network emulator image file&progress, important ebooks, hyper-v checkpoint & hyper-v export and the precious thief & TDM gamesaves. Don't fall yourself into & lay your hands on crappy SSD
       
      · 7 replies
    • OrbWeaver

      Does anyone actually use the Normalise button in the Surface inspector? Even after looking at the code I'm not quite sure what it's for.
      · 7 replies
    • Ansome

      Turns out my 15th anniversary mission idea has already been done once or twice before! I've been beaten to the punch once again, but I suppose that's to be expected when there's over 170 FMs out there, eh? I'm not complaining though, I love learning new tricks and taking inspiration from past FMs. Best of luck on your own fan missions!
      · 4 replies
×
×
  • Create New...