Jump to content
The Dark Mod Forums

TDM Engine Development Page


zergrush

Recommended Posts

Thanks m8 :)

i allways said give people time and they will figure out vanilla's inner workings,

Seems i was not wrong. Still many things that could need an overhaul like implementing FBO's,

and removing the ancient OpenGL 1.4 calls which according to gDebugger are the worst offenders

resource wise. I have faith that it will come if not ill do it myself :P but im no ace when it comes to C++

so it may take a while :).

Link to comment
Share on other sites

So...

 

May I propose another possibly small feature addition?

 

Add "CubicLight" as a Light material keyword and make it into it's own light type like Rebb did with Ambient light.

 

An example demo that renders lights with cubemaps instead of two 2d images can be found here:

 

https://dl.dropboxusercontent.com/u/17706561/ambientcube_test.rar

 

Apparently there is even some native code for this in Doom 3 GPL code but it was never enabled according to Serpentine.

 

This would allow much better looking light projections. :)

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

What does it do? I'm stuck in a crappy hotel this week for work with crappy Wi-Fi so I can't use the laptop and my phone won't open a rar. Plus Google is no help, "cubic light" brings up lamp shades and sculptures. Is it the cubemap equivalent of light textures?

Link to comment
Share on other sites

Yes, what is does is allow you to use a cubemap as the input textures for a light. The falloffImage is replaced with a spherical falloff.

 

This allows you to make fairly accurate light projections by rendering the light results from any light type in blender to a neutral surfaced

cubic room. Make your light in blender, raytrace, bake. Then take the textures and make a cubemap with them. On re-projection the spherical

convolve should restore the original light shape.

 

Lamps and shaded lights would benefit the most but almost all lights would look better. Even with artist drawn approximations. Heck you could

even photograph a wall with a lamp pointed at it in different directions for each cubemap image.

 

And if you could also add some function to invert the falloff so that it gets darker towards the center... boom easy image-based lighting approximation

for GI.

 

Looks like only draw_exp tangentally references the cubemap light idea so I'm not sure where Serpentine found it. Nonetheless, the attached package is

a working example. We just need a new light type for it so we wouldn't need to break existing maps.

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

Yeah, that's where Sikkpin went full-on cubemap lights pretty much everywhere.

(and made a shed-load of new interactions)

 

If I read the glprogs correctly, the lights all sample from a global SSAO buffer.

 

And this might be that improved fog that folks were looking for:

 

https://github.com/R...h_texturefog.fp

 

So a lot of goalposts are present here but it's a huge zoo of stuff to digest.

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

Yeah i newer got his engine to run but i know why now atleast.

Some of the shaders in there need material support that vanilla Doom3 does not have (yet) unfortunatly without asking him directly

it will be a pile of guesswork and take quite some luck to get it all running.

A few of the things in his feedback engine has been moved to revelation,

mostly small fixes like saving the alpha channel to the normalmap instead of just assuming its full alpha and increasing the number of interactions vanilla can run.

Also a small piece of code in there to run gamma normalization on the diffuse maps but it makes the game really dark so i removed it again for now,

untill i can boost lightlevels a bit without breaking everything else. If you want to try its in tr_render.cpp and it makes colored light really stand out :) but again its to dark to really be fun to play.

increasing the max number of interactions was not even noticeable on performance so it seem safe.

atleast he allways comments his code so its easy to follow the various parts :)

Link to comment
Share on other sites

The zip package I attached has example cubemap light materials. How much you wanna bet these work with feedback? But, yeah, there are other material types that are left to guesswork. Though some of those might be in his breadcrumbs demo. Seriously though, I just want those cubelights for now. Anything else we can scavage is gravy.

 

Edit: here's a link to breadcrumbs assets

 

https://dl.dropboxusercontent.com/u/17706561/sikk_pak000.zip

 


https://dl.dropboxusercontent.com/u/17706561/sikk_pak000.zip

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

Actually, you might be able to reverse engineer the materials by looking at the token parser in the material loader and looking at Prey's material definitions. (His design was strongly influenced by Prey's changes to id tech 4)

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

What does it do? I'm stuck in a crappy hotel this week for work with crappy Wi-Fi so I can't use the laptop and my phone won't open a rar. Plus Google is no help, "cubic light" brings up lamp shades and sculptures. Is it the cubemap equivalent of light textures?

 

Ahh, brainfart... It would help if I pasted some code eh?

 

# note:   lightFallTC = fragment.texcoord[2]
#         lightProjTC = fragment.texcoord[3]

# calculate point light tc
MOV    R1, lightProjTC;
MOV    R1.z, lightFallTC.x;
MAD    R1.xyz, R1, 2.0, -1.0;

# calculate projected light tc
MOV    R2, lightProjTC;
MOV    R2.z, -1.0;
RCP    R2.w, lightProjTC.w;
MUL    R2.xy, R2, R2.w;
MAD    R2.xy, R2, 2.0, -1.0;

# sample projection cube map
TEX    lightCube, R1, texture[3], CUBE;
TEX    lightProj, R2, texture[3], CUBE;

# calculate attenuation (x = point, y = projected)
DP3    R1.x, R1, R1;
POW    R1.x, R1.x, 0.5.x;
MOV    R1.y, lightFallTC.x;
ADD_SAT R1.xy, 1.0, -R1;
MUL    R1.xy, R1, R1;
MUL    lightCube, lightCube, R1.x;
MUL    lightProj, lightProj, R1.y;

# if w > 1.0, light = projected, else light = point
SLT    R1.x, 1.0, lightProjTC.w;
CMP    atten, -R1.x, lightProj, lightCube;

 

Obviously you'd need to modify the above with all our fancy interactions.

 

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

Yeah, looks like he's got a new blend mode called "blend shader" that accepts "program program_name.vfp" as the input. Just like his Sikkmod

for Prey materials:

 

shaderLevel3

blend shader

program skin.vfp

 

fragmentparm 0 1, 0, 0, 0 // mask channel

// fragmentparm 1 0.4, 0.0, .0 // sss color

fragmentparm 1 0.75, 0.3, 0.3 // sss color

fragmentparm 2 0.5, 0.5 // wrap around

fragmentparm 3 1.5 // rim

fragmentparm 4 0.18, 0.18, 0.22, 12 // specular color, power

fragmentparm 5 0.5, 0.5, 0.55, 8 // glancing specular color, power

fragmentparm 6 0.15

 

//fragmentmap 0 uncompressed clamp textures/common/orenmap

fragmentmap 1 highres addnormals(models/characters/girlfriend/girlfriend_liquid_local.tga, heightmap(models/characters/girlfriend/girlfriend_liquid_h.tga, 7 ) )

fragmentmap 4 models/characters/girlfriend/girlfriend_liquid.tga

fragmentmap 5 models/characters/girlfriend/girlfriend_liquid_s_skin.tga

fragmentmap 6 models/characters/girlfriend/girlfriend_liquid_sg_skin.tga

fragmentmap 7 models/characters/girlfriend/girlfriend_liquid_mask.tga

}

{

shaderLevel3

blend shader

program cloth.vfp

 

http://www.moddb.com/mods/sikkmod-prey

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

That makes sense actually, since you need a way to use new image map types. Rather than hard code everything just use blend program and now you can use gloss map, SSS map, glow map, etc.

 

I guess it's time to buy Prey now since the assets probably work out of the box.

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

Basically, you'd need to take an AI model from Prey's asset base pack and place it into a Doom 3 map then use the materials from

Sikkmod for Prey.

 

Otherwise you'd need to create your own Doom 3 model or map object and use the materials and textures from the Prey mod plus

your own base textures to act as a substrate to be modulated.

 

Either is possible but the former will be quicker to test.

 

It's practically certain that this is how he did it since his branch has "blend program" and his mod materials also have this and there's

no way the Prey SDK would be flexible enough for him to add that new blend mode. I'll bet good money that a bunch of native Prey materials

use "blend program" too so he liked the idea so much he added it to his branch thus you see the token in his material parser.

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

Morning guys. I'm keeping an eye on what you're finding out here even though i haven't been able to join in this week. A basic question to help me understand the shader prog above: how are the coordinates mapped for a cubemap? It's not specified in the assembly spec. Actually, scrub that, it'll be the same for glsl and other shader languages won't it? So lookup-able.

I have one more (precision) test to do for depth capture, which I've already coded up on paper, then can start to look at other stuff. I'll be trying to come up with a single solution for all sizes of soft particles as first job. The cubemap for lights certainly sounds quite doable. And I've been reading up on fog. I haven't checked out your links yet, but I think we could do a lot just using a table or 1d texture to specify what fog should look like at a given distance. And I want to test fixing the caulk problem by letting the mapper specify a max distance after which no fog is drawn.

Link to comment
Share on other sites

Yeah, Doom 3 uses two different mappings for cubemap orientation (not counting cameraCubemap). One for sky and one for objects. That was infurriating to Sikkpin as I recall because he had to keep fussing with the alignment when he made his HL2 style ambient cubemap demo. As to where the orientations are defined? I'll try to track that from the material parser. That said, all the work is done for you there. The lights automatically presume volume attributes and geometry and the material parser automatically passes cubemap data to the shader inputs in a predefined orientation. Though it's probably a good idea for you to get familiar with those parts of the light code anyway which is something I also hoped to accomplish here since some brilliance seems to crop up everytime you learn more about the engine ;) .

  • Like 1

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

OK, here's a little info on Cubmap loading from image_files.cpp

 


R_LoadCubeImages
Loads six files with proper extensions
=======================
*/
bool R_LoadCubeImages( const char *imgName, cubeFiles_t extensions, byte *pics[6], int *outSize, ID_TIME_T *timestamp ) {
int	i, j;
char	*cameraSides[6] = { "_forward.tga", "_back.tga", "_left.tga", "_right.tga",
"_up.tga", "_down.tga" };
char	*axisSides[6] = { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga",
"_pz.tga", "_nz.tga" };
char	**sides;
char	fullName[MAX_IMAGE_NAME];
int	width, height, size = 0;
if ( extensions == CF_CAMERA ) {
sides = cameraSides;
} else {
sides = axisSides;
}
// FIXME: precompressed cube map files
if ( pics ) {
memset( pics, 0, 6*sizeof(pics[0]) );
}
if ( timestamp ) {
*timestamp = 0;
}
for ( i = 0 ; i < 6 ; i++ ) {
idStr::snPrintf( fullName, sizeof( fullName ), "%s%s", imgName, sides[i] );
ID_TIME_T thisTime;
if ( !pics ) {
// just checking timestamps
R_LoadImageProgram( fullName, NULL, &width, &height, &thisTime );
} else {
R_LoadImageProgram( fullName, &pics[i], &width, &height, &thisTime );
}
if ( thisTime == FILE_NOT_FOUND_TIMESTAMP ) {
break;
}
if ( i == 0 ) {
size = width;
}
if ( width != size || height != size ) {
common->Warning( "Mismatched sizes on cube map '%s'", imgName );
break;
}
if ( timestamp ) {
if ( thisTime > *timestamp ) {
*timestamp = thisTime;
}
}
if ( pics && extensions == CF_CAMERA ) {
// convert from "camera" images to native cube map images
switch( i ) {
case 0:	// forward
R_RotatePic( pics[i], width);
break;
case 1:	// back
R_RotatePic( pics[i], width);
R_HorizontalFlip( pics[i], width, height );
R_VerticalFlip( pics[i], width, height );
break;
case 2:	// left
R_VerticalFlip( pics[i], width, height );
break;
case 3:	// right
R_HorizontalFlip( pics[i], width, height );
break;
case 4:	// up
R_RotatePic( pics[i], width);
break;
case 5: // down
R_RotatePic( pics[i], width);
break;
}
}
}
if ( i != 6 ) {
// we had an error, so free everything
if ( pics ) {
for ( j = 0 ; j < i ; j++ ) {
R_StaticFree( pics[j] );
}
}
if ( timestamp ) {
*timestamp = 0;
}
return false;
}
if ( outSize ) {
*outSize = size;
}
return true;
}

 

https://github.com/T...Image_files.cpp

 

and the corresponding h has reference to CF_NATIVE

 

https://github.com/T...enderer/Image.h

 

I think that R_DeriveLightData in tr_lightrun.cp has the orientation details for the volume:

 

https://github.com/TTimo/doom3.gpl/blob/8047099afdfc5c973faa67a04f601a014de0fa73/neo/renderer/tr_lightrun.cpp

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

Aye vanilla could use cubemaps instead of math to normalize specular.

 

# instead of using math, normalize with the normalization cube map

TEX specular, fragment.texcoord[6], texture[0], CUBE;

MAD specular, specular, scaleTwo, subOne;

 

found these two in sikkpins feedback engine, might help a bit with soft particles :)

 

 

 

 

softparticles_alpha.vfp

 

!!ARBvp1.0

OPTION ARB_position_invariant;

 

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

DP4 result.texcoord[1].z, vertex.position, state.matrix.modelview.row[2];

DP4 result.texcoord[1].w, vertex.position, state.matrix.modelview.row[3];

RCP result.texcoord[2].x, program.local[0].x;

MOV result.texcoord[2].y, program.local[0].x;

MOV result.texcoord[3], program.local[0].y;

MOV result.color, vertex.color;

 

END

 

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

 

!!ARBfp1.0

OPTION ARB_precision_hint_nicest;

 

# texture 0 = sprite color texture

# texture 1 = _depth texture

 

OUTPUT oColor = result.color;

OUTPUT oDepth = result.depth;

 

ATTRIB vColor = fragment.color;

ATTRIB fPos = fragment.position;

ATTRIB TC = fragment.texcoord[0];

ATTRIB vDepth = fragment.texcoord[1];

ATTRIB scale = fragment.texcoord[2];

ATTRIB contrast= fragment.texcoord[3];

 

PARAM nonPoT = program.env[0];

PARAM invRes = program.env[1];

PARAM proj2view = program.env[20];

 

PARAM near = { -3.0, 3.0 };

PARAM near2 = 6.0;

PARAM far = 131072.0;

 

TEMP color, depth, alpha, R0, R1;

 

# calculate the screen texcoord in the 0.0 to 1.0 range

MUL R0, fPos, invRes;

 

# The color is the texture color modulated by the vertex color

TEX color, TC, texture[0], 2D;

TEX depth, R0, texture[1], 2D;

 

# calculate the view space z by deriving w from depth. This will be negative.

MAD depth, depth.z, 2.0, -1.0;

SUB depth.z, -depth.z, proj2view.x;

RCP depth.z, depth.z;

MUL depth, depth.z, proj2view.y;

 

# calculate the view space z by deriving w from depth. This will be negative.

MAD R1, fPos.z, 2.0, -1.0;

SUB R1.x, -R1.z, proj2view.x;

RCP R1.x, R1.x;

MUL R1.z, R1.x, proj2view.y;

 

# basically, we start the fade when depth difference is scale input

# value and fade to 0 using the contrast function below

ADD alpha, R1.z, -depth.z;

MUL_SAT alpha.x, alpha, scale.x;

 

# contrast function (from nVidia's "Soft Particles" paper by Tristan Lorach)

SGE alpha.w, alpha.x, 0.5;

ADD alpha.x, alpha.w, -alpha.x;

ABS alpha.x, alpha.x;

ADD_SAT alpha.x, alpha.x, alpha.x;

POW alpha.x, alpha.x, contrast.x;

MAD alpha.x, alpha.x, -0.5, alpha.w;

ABS_SAT alpha.x, alpha.x;

 

MUL oColor.xyz, color, vColor;

MUL oColor.w, color.w, alpha.x;

 

END

 

softparticles_rgb.vfp

 

!!ARBvp1.0

OPTION ARB_position_invariant;

 

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

DP4 result.texcoord[1].z, vertex.position, state.matrix.modelview.row[2];

DP4 result.texcoord[1].w, vertex.position, state.matrix.modelview.row[3];

RCP result.texcoord[2].x, program.local[0].x;

MOV result.texcoord[2].y, program.local[0].x;

MOV result.texcoord[3], program.local[0].y;

MOV result.color, vertex.color;

 

END

 

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

 

!!ARBfp1.0

OPTION ARB_precision_hint_nicest;

 

# texture 0 = sprite color texture

# texture 1 = _depth texture

 

OUTPUT oColor = result.color;

OUTPUT oDepth = result.depth;

 

ATTRIB vColor = fragment.color;

ATTRIB fPos = fragment.position;

ATTRIB TC = fragment.texcoord[0];

ATTRIB vDepth = fragment.texcoord[1];

ATTRIB scale = fragment.texcoord[2];

ATTRIB contrast= fragment.texcoord[3];

 

PARAM nonPoT = program.env[0];

PARAM invRes = program.env[1];

PARAM proj2view = program.env[20];

 

PARAM near = { -3.0, 3.0 };

PARAM near2 = 6.0;

PARAM far = 131072.0;

 

TEMP color, depth, alpha, R0, R1;

 

# calculate the screen texcoord in the 0.0 to 1.0 range

MUL R0, fPos, invRes;

 

# The color is the texture color modulated by the vertex color

TEX color, TC, texture[0], 2D;

TEX depth, R0, texture[1], 2D;

 

MAD depth, depth.z, 2.0, -1.0;

SUB depth.z, -depth.z, proj2view.x;

RCP depth.z, depth.z;

MUL depth, depth.z, proj2view.y;

 

# calculate the view space z by deriving w from depth. This will be negative.

MAD R1, fPos.z, 2.0, -1.0;

SUB R1.x, -R1.z, proj2view.x;

RCP R1.x, R1.x;

MUL R1.z, R1.x, proj2view.y;

 

# basically, we start the fade when depth difference is scale input

# value and fade to 0 using the contrast function below

ADD alpha, R1.z, -depth.z;

MUL_SAT alpha.x, alpha, scale.x;

 

# contrast function (from nVidia's "Soft Particles" paper by Tristan Lorach)

SGE alpha.w, alpha.x, 0.5;

ADD alpha.x, alpha.w, -alpha.x;

ABS alpha.x, alpha.x;

ADD_SAT alpha.x, alpha.x, alpha.x;

POW alpha.x, alpha.x, contrast.x;

MAD alpha.x, alpha.x, -0.5, alpha.w;

ABS_SAT alpha.x, alpha.x;

 

MUL color, color, alpha.x;

MUL oColor, color, vColor;

 

END

 

also the real deal SSAO shaders in there without the hacking :)

 

ssao_24_PBAO.vfp

 

!!ARBvp1.0

OPTION ARB_position_invariant;

 

# input:

#--------------------------------

# texcoord[0] = TEX0 texcoords

#

# local[0] = sample radius, angle bias, amount, self occlusion factor

# local[1] = field of view

 

PARAM DEG2RAD = 0.017453292519943295769236907684886;

PARAM HALFDEG2RAD = 0.0087266462599716478846184538424431;

PARAM inv12 = 0.08333333;

PARAM inv3 = 0.33333333;

 

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

MUL result.texcoord[1].x, program.local[0].x, inv3;

MUL result.texcoord[1].y, program.local[0].x, 1.0;

MUL result.texcoord[2], program.local[0].y, HALFDEG2RAD;

MUL result.texcoord[3], program.local[0].z, inv12;

MOV result.texcoord[4], program.local[0].w;

MUL result.texcoord[5], program.local[1], HALFDEG2RAD;

 

END

 

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

 

!!ARBfp1.0

OPTION ARB_precision_hint_nicest;

 

# texture 0 = _depth

#

# env[0] = 1.0 to _currentRender conversion

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

 

OUTPUT oColor = result.color;

 

ATTRIB fPos = fragment.position;

ATTRIB TC = fragment.texcoord[0];

ATTRIB Radius = fragment.texcoord[1];

ATTRIB Bias = fragment.texcoord[2];

ATTRIB Amount = fragment.texcoord[3];

ATTRIB SelfOcc = fragment.texcoord[4];

ATTRIB FOV = fragment.texcoord[5];

 

PARAM nonPoT = program.env[0];

PARAM invRes = program.env[1];

 

PARAM dcode24 = { 1.0, 0.003921568627450980392156862745098, 0.000015259021896696421759365224689097 };

PARAM radOff = { 0.0, 0.78539816339744830961566084581988, 1.57079632679489661923132169156, 2.356194490192344928846982537457 }; # 45 deg

PARAM DEG2RAD = 0.017453292519943295769236907684886;

PARAM PI = 3.1415926535897932384626433832795;

PARAM halfPI = 1.5707963267948966192313216916398;

PARAM near = 3.0;

# PARAM farClip = 8192.0;

PARAM farClip = 131072.0;

# PARAM farClip = 32768.0;

# PARAM farClip = 65536.0;

# PARAM farClip = 131072.0;

PARAM randUV = 0.0625; # 0.25 = 4x4; 0.0625 = 16x16; 0.015625 = 64x64

PARAM uvScale = { 2.0, 2.0, 0.0 };

PARAM uvBias = { -1.0, -1.0, 1.0 };

 

TEMP depthEnc, depth, normal, pos, random, ssao, focalLen, invFocalLen, invres, aspect;

TEMP angle, radius, dist, contrast, res, uv, invNPoT;

TEMP D0, D1, D2, D3, D4, D5, D6, D7, D8;

TEMP R0, R1, R2, R3, R4, R5, R6, R7, R8;

TEMP P0, P1, P2, P3, P4, P5, P6, P7, P8;

 

 

# calculate the screen texcoord in the 0.0 to 1.0 range

MUL uv, fPos.xyxy, invRes.xyxy;

# MUL uv.xy, uv, nonPoT;

 

# calculate screen width/height

MOV invres, invRes;

# MUL invres, invRes, nonPoT.xyxy;

MOV invres.zw, -invres.xyxy;

# RCP invNPoT.x, nonPoT.x;

# RCP invNPoT.y, nonPoT.y;

# MOV invNPoT.zw, invNPoT.xyxy;

 

# RCP res.x, invres.x;

# RCP res.y, invres.y;

MOV res.xy, invRes.zwzw;

MUL aspect.z, res.x, invRes.y;

 

# calculate fov focal length

SCS R0.xy, FOV.x;

RCP R0.x, R0.x;

MUL invFocalLen.y, R0.y, R0.x;

MUL invFocalLen.x, invFocalLen.y, aspect.z;

RCP focalLen.x, invFocalLen.x;

RCP focalLen.y, invFocalLen.y;

 

# load the depth render

TEX depthEnc, uv, texture[0], 2D;

 

DP3 depth, depthEnc, dcode24;

MUL depth.x, depth, farClip;

# ADD depth, 1.0, -depthEnc;

# RCP depth.x, depth.x;

# MUL depth, near, depth.x;

 

RCP depth.w, depth.x;

 

# calculate pixel view-space position

MAD pos.xyz, uv.zwzw, uvScale, uvBias;

MUL pos.xy, pos, invFocalLen;

MUL pos.xyz, pos, depth.x;

 

# load the depth render

# TEX normal, uv, texture[1], 2D;

 

# calculate face normal

# MAD normal.xyz, normal, 2.0, -1.0;

# DP3 normal.w, normal, normal;

# RSQ normal.w, normal.w;

# MUL normal.xyz, normal, normal.w;

 

# calculate face normal

MOV P1.xy, uv;

MOV P2.xy, uv;

MOV P3.xy, uv;

MOV P4.xy, uv;

# ADD P1.x, P1, nonPoT.z;

# ADD P2.x, P2, -nonPoT.z;

# ADD P3.y, P3, nonPoT.w;

# ADD P4.y, P4, -nonPoT.w;

ADD P1.x, P1, invRes.x;

ADD P2.x, P2, -invRes.x;

ADD P3.y, P3, invRes.y;

ADD P4.y, P4, -invRes.y;

 

TEX D1, P1, texture[0], 2D;

TEX D2, P2, texture[0], 2D;

TEX D3, P3, texture[0], 2D;

TEX D4, P4, texture[0], 2D;

DP3 D0.x, D1, dcode24;

DP3 D0.y, D2, dcode24;

DP3 D0.z, D3, dcode24;

DP3 D0.w, D4, dcode24;

MUL D0, D0, farClip;

 

# MOV P1.xy, uv.zwzw;

# MOV P2.xy, uv.zwzw;

# MOV P3.xy, uv.zwzw;

# MOV P4.xy, uv.zwzw;

# ADD P1.x, P1, invres.x;

# ADD P2.x, P2, -invres.x;

# ADD P3.y, P3, invres.y;

# ADD P4.y, P4, -invres.y;

 

MAD P1.xyz, P1, uvScale, uvBias;

MAD P2.xyz, P2, uvScale, uvBias;

MAD P3.xyz, P3, uvScale, uvBias;

MAD P4.xyz, P4, uvScale, uvBias;

MUL P1.xy, P1, invFocalLen;

MUL P2.xy, P2, invFocalLen;

MUL P3.xy, P3, invFocalLen;

MUL P4.xy, P4, invFocalLen;

MUL P1.xyz, P1, D0.x;

MUL P2.xyz, P2, D0.y;

MUL P3.xyz, P3, D0.z;

MUL P4.xyz, P4, D0.w;

 

ADD P1, P1, -pos;

ADD P2, pos, -P2;

ADD P3, P3, -pos;

ADD P4, pos, -P4;

DP3 P1.w, P1, P1;

DP3 P2.w, P2, P2;

DP3 P3.w, P3, P3;

DP3 P4.w, P4, P4;

SLT P1.w, P1.w, P2.w;

SLT P3.w, P3.w, P4.w;

CMP P1, -P1.w, P1, P2;

CMP P2, -P3.w, P3, P4;

 

XPD normal.xyz, P1, P2;

DP3 normal.w, normal, normal;

RSQ normal.w, normal.w;

MUL normal.xyz, normal, normal.w;

 

# load random vector map

MUL R0.xy, fPos, randUV;

TEX random, R0, texture[2], 2D;

MAD random.w, random.w, 0.9, 0.1;

 

# calculate radius

MUL_SAT radius.x, depth.x, 0.0078125; # make area smaller if distance is less than 128 units

MAD radius.y, depth.x, 0.001953125, 1.0; # make area larger if distance is more than 512 units

MUL radius.w, radius.x, radius.y;

MUL radius, Radius.xxyy, radius.w;

RCP radius.w, radius.w;

MUL radius.xy, radius, random.w;

MUL radius.xy, radius, focalLen;

MUL radius.xy, radius, depth.w;

 

# calculate contrast

MUL R0.x, Bias, 2.0;

SIN_SAT R0.x, R0.x;

ADD R0.x, 1.0, -R0.x;

RCP R0.x, R0.x;

MUL contrast, Amount, R0.x;

 

# calculate starting angle

MUL angle.xyz, random, radOff.y;

 

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

 

# calculate offsets (Ring 1 = 8 samples)

ADD R0, angle.x, radOff;

SCS R1, R0.x;

SCS R2, R0.y;

SCS R3, R0.z;

SCS R4, R0.w;

 

ADD R0.x, R1.x, -R1.y;

ADD R0.y, R1.x, R1.y;

ADD R0.z, R2.x, -R2.y;

ADD R0.w, R2.x, R2.y;

MUL R0, R0, radius.xyxy;

MAD R0, R0, res.xyxy, 0.5;

FLR R0, R0;

MAD_SAT R1, R0.xyxy, invres, uv.xyxy;

MAD_SAT R2, R0.zwzw, invres, uv.xyxy;

# MAD_SAT R1, R0.xyxy, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

# MAD_SAT R2, R0.zwzw, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

 

ADD R0.x, R3.x, -R3.y;

ADD R0.y, R3.x, R3.y;

ADD R0.z, R4.x, -R4.y;

ADD R0.w, R4.x, R4.y;

MUL R0, R0, radius.xyxy;

MAD R0, R0, res.xyxy, 0.5;

FLR R0, R0;

MAD_SAT R3, R0.xyxy, invres, uv.xyxy;

MAD_SAT R4, R0.zwzw, invres, uv.xyxy;

# MAD_SAT R3, R0.xyxy, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

# MAD_SAT R4, R0.zwzw, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

 

# get sample depth

TEX D1, R1.xyxy, texture[0], 2D;

TEX D2, R1.zwzw, texture[0], 2D;

TEX D3, R2.xyxy, texture[0], 2D;

TEX D4, R2.zwzw, texture[0], 2D;

TEX D5, R3.xyxy, texture[0], 2D;

TEX D6, R3.zwzw, texture[0], 2D;

TEX D7, R4.xyxy, texture[0], 2D;

TEX D8, R4.zwzw, texture[0], 2D;

 

# decode 24-bit depth

DP3 D1.x, D1, dcode24;

DP3 D1.y, D2, dcode24;

DP3 D1.z, D3, dcode24;

DP3 D1.w, D4, dcode24;

DP3 D2.x, D5, dcode24;

DP3 D2.y, D6, dcode24;

DP3 D2.z, D7, dcode24;

DP3 D2.w, D8, dcode24;

 

# scale by far-clip

MUL D1, D1, farClip;

MUL D2, D2, farClip;

 

# TEX D1.x, R1.xyxy, texture[0], 2D;

# TEX D1.y, R1.zwzw, texture[0], 2D;

# TEX D1.z, R2.xyxy, texture[0], 2D;

# TEX D1.w, R2.zwzw, texture[0], 2D;

# TEX D2.x, R3.xyxy, texture[0], 2D;

# TEX D2.y, R3.zwzw, texture[0], 2D;

# TEX D2.z, R4.xyxy, texture[0], 2D;

# TEX D2.w, R4.zwzw, texture[0], 2D;

# ADD D1, 1.0, -D1;

# RCP D1.x, D1.x;

# RCP D1.y, D1.y;

# RCP D1.z, D1.z;

# RCP D1.w, D1.w;

# MUL D1, near, D1;

# ADD D2, 1.0, -D2;

# RCP D2.x, D2.x;

# RCP D2.y, D2.y;

# RCP D2.z, D2.z;

# RCP D2.w, D2.w;

# MUL D2, near, D2;

 

# MUL R1, R1, invNPoT.xyxy;

# MUL R2, R2, invNPoT.xyxy;

# MUL R3, R3, invNPoT.xyxy;

# MUL R4, R4, invNPoT.xyxy;

 

# calculate sample view-space position

MAD P1.xyz, R1.xyxy, uvScale, uvBias;

MAD P2.xyz, R1.zwzw, uvScale, uvBias;

MAD P3.xyz, R2.xyxy, uvScale, uvBias;

MAD P4.xyz, R2.zwzw, uvScale, uvBias;

MAD P5.xyz, R3.xyxy, uvScale, uvBias;

MAD P6.xyz, R3.zwzw, uvScale, uvBias;

MAD P7.xyz, R4.xyxy, uvScale, uvBias;

MAD P8.xyz, R4.zwzw, uvScale, uvBias;

MUL P1.xy, P1, invFocalLen;

MUL P2.xy, P2, invFocalLen;

MUL P3.xy, P3, invFocalLen;

MUL P4.xy, P4, invFocalLen;

MUL P5.xy, P5, invFocalLen;

MUL P6.xy, P6, invFocalLen;

MUL P7.xy, P7, invFocalLen;

MUL P8.xy, P8, invFocalLen;

MUL P1.xyz, P1, D1.x;

MUL P2.xyz, P2, D1.y;

MUL P3.xyz, P3, D1.z;

MUL P4.xyz, P4, D1.w;

MUL P5.xyz, P5, D2.x;

MUL P6.xyz, P6, D2.y;

MUL P7.xyz, P7, D2.z;

MUL P8.xyz, P8, D2.w;

 

# calculate occlusion

ADD dist, P1, -pos;

DP3 D1.x, dist, dist;

RSQ D1.x, D1.x;

MUL dist.xyz, dist, D1.x;

DP3 R1.x, normal, -dist;

ADD dist, P2, -pos;

DP3 D1.y, dist, dist;

RSQ D1.y, D1.y;

MUL dist.xyz, dist, D1.y;

DP3 R1.y, normal, -dist;

ADD dist, P3, -pos;

DP3 D1.z, dist, dist;

RSQ D1.z, D1.z;

MUL dist.xyz, dist, D1.z;

DP3 R1.z, normal, -dist;

ADD dist, P4, -pos;

DP3 D1.w, dist, dist;

RSQ D1.w, D1.w;

MUL dist.xyz, dist, D1.w;

DP3 R1.w, normal, -dist;

ADD dist, P5, -pos;

DP3 D2.x, dist, dist;

RSQ D2.x, D2.x;

MUL dist.xyz, dist, D2.x;

DP3 R2.x, normal, -dist;

ADD dist, P6, -pos;

DP3 D2.y, dist, dist;

RSQ D2.y, D2.y;

MUL dist.xyz, dist, D2.y;

DP3 R2.y, normal, -dist;

ADD dist, P7, -pos;

DP3 D2.z, dist, dist;

RSQ D2.z, D2.z;

MUL dist.xyz, dist, D2.z;

DP3 R2.z, normal, -dist;

ADD dist, P8, -pos;

DP3 D2.w, dist, dist;

RSQ D2.w, D2.w;

MUL dist.xyz, dist, D2.w;

DP3 R2.w, normal, -dist;

 

RCP D1.x, D1.x;

RCP D1.y, D1.y;

RCP D1.z, D1.z;

RCP D1.w, D1.w;

RCP D2.x, D2.x;

RCP D2.y, D2.y;

RCP D2.z, D2.z;

RCP D2.w, D2.w;

MUL D1, D1, radius.w;

MUL D2, D2, radius.w;

MAD D1, D1, D1, 1.0;

MAD D2, D2, D2, 1.0;

RCP D1.x, D1.x;

RCP D1.y, D1.y;

RCP D1.z, D1.z;

RCP D1.w, D1.w;

RCP D2.x, D2.x;

RCP D2.y, D2.y;

RCP D2.z, D2.z;

RCP D2.w, D2.w;

 

ADD R1, R1, -Bias;

ADD R2, R2, -Bias;

MAX R1, R1, -SelfOcc;

MAX R2, R2, -SelfOcc;

MAD ssao, R1, D1, ssao;

MAD ssao, R2, D2, ssao;

 

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

 

# calculate offsets (Ring 2 = 8 samples)

ADD radius.xy, radius, radius;

 

ADD R0, angle.y, radOff;

SCS R1, R0.x;

SCS R2, R0.y;

SCS R3, R0.z;

SCS R4, R0.w;

 

ADD R0.x, R1.x, -R1.y;

ADD R0.y, R1.x, R1.y;

ADD R0.z, R2.x, -R2.y;

ADD R0.w, R2.x, R2.y;

MUL R0, R0, radius.xyxy;

MAD R0, R0, res.xyxy, 0.5;

FLR R0, R0;

MAD_SAT R1, R0.xyxy, invres, uv.xyxy;

MAD_SAT R2, R0.zwzw, invres, uv.xyxy;

# MAD_SAT R1, R0.xyxy, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

# MAD_SAT R2, R0.zwzw, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

 

ADD R0.x, R3.x, -R3.y;

ADD R0.y, R3.x, R3.y;

ADD R0.z, R4.x, -R4.y;

ADD R0.w, R4.x, R4.y;

MUL R0, R0, radius.xyxy;

MAD R0, R0, res.xyxy, 0.5;

FLR R0, R0;

MAD_SAT R3, R0.xyxy, invres, uv.xyxy;

MAD_SAT R4, R0.zwzw, invres, uv.xyxy;

# MAD_SAT R3, R0.xyxy, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

# MAD_SAT R4, R0.zwzw, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

 

# get sample depth

TEX D1, R1.xyxy, texture[0], 2D;

TEX D2, R1.zwzw, texture[0], 2D;

TEX D3, R2.xyxy, texture[0], 2D;

TEX D4, R2.zwzw, texture[0], 2D;

TEX D5, R3.xyxy, texture[0], 2D;

TEX D6, R3.zwzw, texture[0], 2D;

TEX D7, R4.xyxy, texture[0], 2D;

TEX D8, R4.zwzw, texture[0], 2D;

 

# decode 24-bit depth

DP3 D1.x, D1, dcode24;

DP3 D1.y, D2, dcode24;

DP3 D1.z, D3, dcode24;

DP3 D1.w, D4, dcode24;

DP3 D2.x, D5, dcode24;

DP3 D2.y, D6, dcode24;

DP3 D2.z, D7, dcode24;

DP3 D2.w, D8, dcode24;

 

# scale by far-clip

MUL D1, D1, farClip;

MUL D2, D2, farClip;

 

# TEX D1.x, R1.xyxy, texture[0], 2D;

# TEX D1.y, R1.zwzw, texture[0], 2D;

# TEX D1.z, R2.xyxy, texture[0], 2D;

# TEX D1.w, R2.zwzw, texture[0], 2D;

# TEX D2.x, R3.xyxy, texture[0], 2D;

# TEX D2.y, R3.zwzw, texture[0], 2D;

# TEX D2.z, R4.xyxy, texture[0], 2D;

# TEX D2.w, R4.zwzw, texture[0], 2D;

# ADD D1, 1.0, -D1;

# RCP D1.x, D1.x;

# RCP D1.y, D1.y;

# RCP D1.z, D1.z;

# RCP D1.w, D1.w;

# MUL D1, near, D1;

# ADD D2, 1.0, -D2;

# RCP D2.x, D2.x;

# RCP D2.y, D2.y;

# RCP D2.z, D2.z;

# RCP D2.w, D2.w;

# MUL D2, near, D2;

 

# MUL R1, R1, invNPoT.xyxy;

# MUL R2, R2, invNPoT.xyxy;

# MUL R3, R3, invNPoT.xyxy;

# MUL R4, R4, invNPoT.xyxy;

 

# calculate sample view-space position

MAD P1.xyz, R1.xyxy, uvScale, uvBias;

MAD P2.xyz, R1.zwzw, uvScale, uvBias;

MAD P3.xyz, R2.xyxy, uvScale, uvBias;

MAD P4.xyz, R2.zwzw, uvScale, uvBias;

MAD P5.xyz, R3.xyxy, uvScale, uvBias;

MAD P6.xyz, R3.zwzw, uvScale, uvBias;

MAD P7.xyz, R4.xyxy, uvScale, uvBias;

MAD P8.xyz, R4.zwzw, uvScale, uvBias;

MUL P1.xy, P1, invFocalLen;

MUL P2.xy, P2, invFocalLen;

MUL P3.xy, P3, invFocalLen;

MUL P4.xy, P4, invFocalLen;

MUL P5.xy, P5, invFocalLen;

MUL P6.xy, P6, invFocalLen;

MUL P7.xy, P7, invFocalLen;

MUL P8.xy, P8, invFocalLen;

MUL P1.xyz, P1, D1.x;

MUL P2.xyz, P2, D1.y;

MUL P3.xyz, P3, D1.z;

MUL P4.xyz, P4, D1.w;

MUL P5.xyz, P5, D2.x;

MUL P6.xyz, P6, D2.y;

MUL P7.xyz, P7, D2.z;

MUL P8.xyz, P8, D2.w;

 

# calculate occlusion

ADD dist, P1, -pos;

DP3 D1.x, dist, dist;

RSQ D1.x, D1.x;

MUL dist.xyz, dist, D1.x;

DP3 R1.x, normal, -dist;

ADD dist, P2, -pos;

DP3 D1.y, dist, dist;

RSQ D1.y, D1.y;

MUL dist.xyz, dist, D1.y;

DP3 R1.y, normal, -dist;

ADD dist, P3, -pos;

DP3 D1.z, dist, dist;

RSQ D1.z, D1.z;

MUL dist.xyz, dist, D1.z;

DP3 R1.z, normal, -dist;

ADD dist, P4, -pos;

DP3 D1.w, dist, dist;

RSQ D1.w, D1.w;

MUL dist.xyz, dist, D1.w;

DP3 R1.w, normal, -dist;

ADD dist, P5, -pos;

DP3 D2.x, dist, dist;

RSQ D2.x, D2.x;

MUL dist.xyz, dist, D2.x;

DP3 R2.x, normal, -dist;

ADD dist, P6, -pos;

DP3 D2.y, dist, dist;

RSQ D2.y, D2.y;

MUL dist.xyz, dist, D2.y;

DP3 R2.y, normal, -dist;

ADD dist, P7, -pos;

DP3 D2.z, dist, dist;

RSQ D2.z, D2.z;

MUL dist.xyz, dist, D2.z;

DP3 R2.z, normal, -dist;

ADD dist, P8, -pos;

DP3 D2.w, dist, dist;

RSQ D2.w, D2.w;

MUL dist.xyz, dist, D2.w;

DP3 R2.w, normal, -dist;

 

RCP D1.x, D1.x;

RCP D1.y, D1.y;

RCP D1.z, D1.z;

RCP D1.w, D1.w;

RCP D2.x, D2.x;

RCP D2.y, D2.y;

RCP D2.z, D2.z;

RCP D2.w, D2.w;

MUL D1, D1, radius.w;

MUL D2, D2, radius.w;

MAD D1, D1, D1, 1.0;

MAD D2, D2, D2, 1.0;

RCP D1.x, D1.x;

RCP D1.y, D1.y;

RCP D1.z, D1.z;

RCP D1.w, D1.w;

RCP D2.x, D2.x;

RCP D2.y, D2.y;

RCP D2.z, D2.z;

RCP D2.w, D2.w;

 

ADD R1, R1, -Bias;

ADD R2, R2, -Bias;

MAX R1, R1, -SelfOcc;

MAX R2, R2, -SelfOcc;

MAD ssao, R1, D1, ssao;

MAD ssao, R2, D2, ssao;

 

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

 

# calculate offsets (Ring 3 = 8 samples)

MAD radius.xy, radius, 0.5, radius;

 

ADD R0, angle.z, radOff;

SCS R1, R0.x;

SCS R2, R0.y;

SCS R3, R0.z;

SCS R4, R0.w;

 

ADD R0.x, R1.x, -R1.y;

ADD R0.y, R1.x, R1.y;

ADD R0.z, R2.x, -R2.y;

ADD R0.w, R2.x, R2.y;

MUL R0, R0, radius.xyxy;

MAD R0, R0, res.xyxy, 0.5;

FLR R0, R0;

MAD_SAT R1, R0.xyxy, invres, uv.xyxy;

MAD_SAT R2, R0.zwzw, invres, uv.xyxy;

# MAD_SAT R1, R0.xyxy, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

# MAD_SAT R2, R0.zwzw, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

 

ADD R0.x, R3.x, -R3.y;

ADD R0.y, R3.x, R3.y;

ADD R0.z, R4.x, -R4.y;

ADD R0.w, R4.x, R4.y;

MUL R0, R0, radius.xyxy;

MAD R0, R0, res.xyxy, 0.5;

FLR R0, R0;

MAD_SAT R3, R0.xyxy, invres, uv.xyxy;

MAD_SAT R4, R0.zwzw, invres, uv.xyxy;

# MAD_SAT R3, R0.xyxy, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

# MAD_SAT R4, R0.zwzw, { 1.0, 1.0, -1.0, -1.0 }, uv.xyxy;

 

# get sample depth

TEX D1, R1.xyxy, texture[0], 2D;

TEX D2, R1.zwzw, texture[0], 2D;

TEX D3, R2.xyxy, texture[0], 2D;

TEX D4, R2.zwzw, texture[0], 2D;

TEX D5, R3.xyxy, texture[0], 2D;

TEX D6, R3.zwzw, texture[0], 2D;

TEX D7, R4.xyxy, texture[0], 2D;

TEX D8, R4.zwzw, texture[0], 2D;

 

# decode 24-bit depth

DP3 D1.x, D1, dcode24;

DP3 D1.y, D2, dcode24;

DP3 D1.z, D3, dcode24;

DP3 D1.w, D4, dcode24;

DP3 D2.x, D5, dcode24;

DP3 D2.y, D6, dcode24;

DP3 D2.z, D7, dcode24;

DP3 D2.w, D8, dcode24;

 

# scale by far-clip

MUL D1, D1, farClip;

MUL D2, D2, farClip;

 

# TEX D1.x, R1.xyxy, texture[0], 2D;

# TEX D1.y, R1.zwzw, texture[0], 2D;

# TEX D1.z, R2.xyxy, texture[0], 2D;

# TEX D1.w, R2.zwzw, texture[0], 2D;

# TEX D2.x, R3.xyxy, texture[0], 2D;

# TEX D2.y, R3.zwzw, texture[0], 2D;

# TEX D2.z, R4.xyxy, texture[0], 2D;

# TEX D2.w, R4.zwzw, texture[0], 2D;

# ADD D1, 1.0, -D1;

# RCP D1.x, D1.x;

# RCP D1.y, D1.y;

# RCP D1.z, D1.z;

# RCP D1.w, D1.w;

# MUL D1, near, D1;

# ADD D2, 1.0, -D2;

# RCP D2.x, D2.x;

# RCP D2.y, D2.y;

# RCP D2.z, D2.z;

# RCP D2.w, D2.w;

# MUL D2, near, D2;

 

# MUL R1, R1, invNPoT.xyxy;

# MUL R2, R2, invNPoT.xyxy;

# MUL R3, R3, invNPoT.xyxy;

# MUL R4, R4, invNPoT.xyxy;

 

# calculate sample view-space position

MAD P1.xyz, R1.xyxy, uvScale, uvBias;

MAD P2.xyz, R1.zwzw, uvScale, uvBias;

MAD P3.xyz, R2.xyxy, uvScale, uvBias;

MAD P4.xyz, R2.zwzw, uvScale, uvBias;

MAD P5.xyz, R3.xyxy, uvScale, uvBias;

MAD P6.xyz, R3.zwzw, uvScale, uvBias;

MAD P7.xyz, R4.xyxy, uvScale, uvBias;

MAD P8.xyz, R4.zwzw, uvScale, uvBias;

MUL P1.xy, P1, invFocalLen;

MUL P2.xy, P2, invFocalLen;

MUL P3.xy, P3, invFocalLen;

MUL P4.xy, P4, invFocalLen;

MUL P5.xy, P5, invFocalLen;

MUL P6.xy, P6, invFocalLen;

MUL P7.xy, P7, invFocalLen;

MUL P8.xy, P8, invFocalLen;

MUL P1.xyz, P1, D1.x;

MUL P2.xyz, P2, D1.y;

MUL P3.xyz, P3, D1.z;

MUL P4.xyz, P4, D1.w;

MUL P5.xyz, P5, D2.x;

MUL P6.xyz, P6, D2.y;

MUL P7.xyz, P7, D2.z;

MUL P8.xyz, P8, D2.w;

 

# calculate occlusion

ADD dist, P1, -pos;

DP3 D1.x, dist, dist;

RSQ D1.x, D1.x;

MUL dist.xyz, dist, D1.x;

DP3 R1.x, normal, -dist;

ADD dist, P2, -pos;

DP3 D1.y, dist, dist;

RSQ D1.y, D1.y;

MUL dist.xyz, dist, D1.y;

DP3 R1.y, normal, -dist;

ADD dist, P3, -pos;

DP3 D1.z, dist, dist;

RSQ D1.z, D1.z;

MUL dist.xyz, dist, D1.z;

DP3 R1.z, normal, -dist;

ADD dist, P4, -pos;

DP3 D1.w, dist, dist;

RSQ D1.w, D1.w;

MUL dist.xyz, dist, D1.w;

DP3 R1.w, normal, -dist;

ADD dist, P5, -pos;

DP3 D2.x, dist, dist;

RSQ D2.x, D2.x;

MUL dist.xyz, dist, D2.x;

DP3 R2.x, normal, -dist;

ADD dist, P6, -pos;

DP3 D2.y, dist, dist;

RSQ D2.y, D2.y;

MUL dist.xyz, dist, D2.y;

DP3 R2.y, normal, -dist;

ADD dist, P7, -pos;

DP3 D2.z, dist, dist;

RSQ D2.z, D2.z;

MUL dist.xyz, dist, D2.z;

DP3 R2.z, normal, -dist;

ADD dist, P8, -pos;

DP3 D2.w, dist, dist;

RSQ D2.w, D2.w;

MUL dist.xyz, dist, D2.w;

DP3 R2.w, normal, -dist;

 

RCP D1.x, D1.x;

RCP D1.y, D1.y;

RCP D1.z, D1.z;

RCP D1.w, D1.w;

RCP D2.x, D2.x;

RCP D2.y, D2.y;

RCP D2.z, D2.z;

RCP D2.w, D2.w;

MUL D1, D1, radius.w;

MUL D2, D2, radius.w;

MAD D1, D1, D1, 1.0;

MAD D2, D2, D2, 1.0;

RCP D1.x, D1.x;

RCP D1.y, D1.y;

RCP D1.z, D1.z;

RCP D1.w, D1.w;

RCP D2.x, D2.x;

RCP D2.y, D2.y;

RCP D2.z, D2.z;

RCP D2.w, D2.w;

 

ADD R1, R1, -Bias;

ADD R2, R2, -Bias;

MAX R1, R1, -SelfOcc;

MAX R2, R2, -SelfOcc;

MAD ssao, R1, D1, ssao;

MAD ssao, R2, D2, ssao;

 

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

 

# scale occlusion and add self occlusion factor

DP4 ssao.x, ssao, 1.0;

MAD ssao.x, ssao, contrast, SelfOcc;

 

# invert and ouput

MOV oColor, depthEnc;

ADD oColor.w, 1.0, -ssao.x;

# MOV oColor, depthEnc;

MOV oColor, normal;

 

END

 

ssao_blur.vfp

 

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

# Feedback SSAO Blur Fragment Program

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

#

# input:

#--------------------------------

# texture 0 = _ssao (xyz = depth (24-bit encoded), w = ssao)

#

# local[0] = blur scale

# local[1] = depth threshold

#

# env[0] = 1.0 to _currentRender conversion

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

#

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

 

!!ARBfp1.0

OPTION ARB_precision_hint_nicest;

 

OUTPUT oColor = result.color;

 

ATTRIB fPos = fragment.position;

ATTRIB TC = fragment.texcoord[0];

 

PARAM nonPoT = program.env[0];

PARAM invRes = program.env[1];

 

PARAM Scale = program.local[0];

PARAM Thresh = program.local[1];

 

# sample offsets

PARAM off1 = { 0.5, 1.0, 1.0, -0.5 };

PARAM off2 = { -0.5, -1.0, -1.0, 0.5 };

# PARAM off1 = { 0.0, 1.0 };

# PARAM off2 = { 1.0, 0.0 };

# PARAM off3 = { 0.0, -1.0 };

# PARAM off4 = { -1.0, 0.0 };

 

PARAM const = { 0.25, 0.5, 0.75, 1.0 };

PARAM dcode24 = { 1.0, 0.003921568627450980392156862745098, 0.000015259021896696421759365224689097 };

PARAM farClip = 8192.0;

 

TEMP uv, color, diff, weight, sumWeight, scale;

TEMP R0, R1, R2, R3, R4;

TEMP S0, S1, S2, S3, S4;

TEMP D0, D1, D2;

 

 

# calculate the screen texcoord in the 0.0 to 1.0 range

MUL uv, fPos.xyxy, invRes.xyxy;

 

MUL scale, Scale, invRes.xyxy;

 

MAD_SAT R1, off1, scale, uv.xyxy;

MAD_SAT R2, off2, scale, uv.xyxy;

 

TEX S0, uv, texture[0], 2D;

TEX S1, R1.xyxy, texture[0], 2D;

TEX S2, R1.zwzw, texture[0], 2D;

TEX S3, R2.xyxy, texture[0], 2D;

TEX S4, R2.zwzw, texture[0], 2D;

 

DP4 D0, S0, dcode24;

DP4 D1.x, S1, dcode24;

DP4 D1.y, S2, dcode24;

DP4 D1.z, S3, dcode24;

DP4 D1.w, S4, dcode24;

 

MOV S1.x, S1.w;

MOV S1.y, S2.w;

MOV S1.z, S3.w;

MOV S1.w, S4.w;

MOV sumWeight.x, 0.0125;

 

RCP D0.x, D0.x;

MUL D1, D1, D0.x;

ADD D1, 1.0, -D1;

MUL diff, D1, Thresh;

ABS D1, diff;

MAD D1, D1, -const.z, const.y;

MUL D2, diff, const.x;

ADD_SAT weight, D1, -D2;

 

DP4 color.x, S1, weight;

MAD color.x, S0.x, sumWeight.x, color.x;

 

DP4 weight.x, weight, const.w;

ADD sumWeight.x, sumWeight, weight;

RCP sumWeight.x, sumWeight.x;

 

MOV oColor, S0;

MUL oColor.w, color.x, sumWeight.x;

 

END

 

ssao_view.vfp

 

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

# Feedback SSAO View Fragment Program

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

#

# input:

#--------------------------------

# texture 0 = _ssao (xyz = depth (24-bit encoded), w = ssao)

#

# env[0] = 1.0 to _currentRender conversion

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

#

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

 

!!ARBfp1.0

OPTION ARB_precision_hint_fastest;

 

# texture 0 = x = _ssao (ssao buffer), yz = depth (16-bit ecoded)

#

# env[0] = 1.0 to _currentRender conversion

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

 

OUTPUT oColor = result.color;

 

ATTRIB fPos = fragment.position;

ATTRIB TC = fragment.texcoord[0];

 

PARAM nonPoT = program.env[0];

PARAM invRes = program.env[1];

 

TEMP R0;

 

 

# calculate the screen texcoord in the 0.0 to 1.0 range

MUL R0, fPos.xyxy, nonPoT;

 

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

# MUL R0, R0, nonPoT;

# RCP R0.z, nonPoT.x;

# RCP R0.w, nonPoT.y;

# MUL R0, R0, R0.zwzw;

 

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

# MUL R0, TC, nonPoT;

 

TEX R0, R0.zwzw, texture[0], 2D;

 

# MOV oColor.xyz, R0.w;

MOV oColor.xyz, R0;

# MOV oColor.z, 0;

 

END

 

 

 

 

the PBAO version seems rather large ? seems to use self occlusion maybe thats why , its one of the larger bits of code in that shader.

Link to comment
Share on other sites

Back home at last! And I checked the precision of the depth capture. It's got full precision, so cool. The banding in the depth renders above was just because the same number is in all color channels, so it gets limited to displaying 256 shades of grey. But the captured number is precise.

 

You guys will have to give me a day or two to catch up on all the bedtime reading you've provided!

 

@revelator. That's a hell of a lot of shader for SSAO! I'm just taking a look at the "soft particles alpha" shader. It's the method from the nvidia paper that he cites in one of the comments, that always comes up high on google results. I'll try the fadeout function to see if it's better than my linear one, but we won't want to use that method overall. It gets rid of the hard lines but it doesn't continue to draw the particle over the top of the solid surface at all, so you lose half the illusion. It's the "overdraw" for a few units (depth-wise) that stops the eye getting a fix on where the 2d particle is. It's easy to come up examples where the difference is obvious: if you have something solid poking out of the dust cloud, the hard line will be gone but the particle will still wrap round the sticky-out bits in a neat and clear vertical plane. A bit of overdraw fixes that.

 

An example I found on google images. This is one that doesn't do any overdraw. I do have overdraw in my shader (which is why I put those pipes in the test map. They make the shortcomings of the other method obvious too):

small_StateOfDX10_BS_SoftP1.jpg

  • Like 2
Link to comment
Share on other sites

OK here's the meat of how Rebb split Ambient light into it's own type:

 

draw_arb2.cpp

 

 

 


=============
RB_ARB2_CreateDrawInteractions

=============
*/
void RB_ARB2_CreateDrawInteractions( const drawSurf_t *surf ) {
if ( !surf ) {
	return;
}

// perform setup here that will be constant for all interactions
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc );

// bind the vertex program
// rebb: support dedicated ambient - CVar and direct interactions can probably be removed, they're there mainly for performance testing
if( r_dedicatedAmbient.GetBool() ) {
	if( backEnd.vLight->lightShader->IsAmbientLight() ) {
		qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_AMBIENT );
		qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_AMBIENT );
	} else {
		if ( r_testARBProgram.GetBool() ) {
			qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_TEST_DIRECT );
			qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST_DIRECT );
		} else {
			qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION_DIRECT );
			qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION_DIRECT );
		}
	}
} else {
	if ( r_testARBProgram.GetBool() ) {
		qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_TEST );
		qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST );
	} else {
		qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION );
		qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION );
	}
}

qglEnable(GL_VERTEX_PROGRAM_ARB);
qglEnable(GL_FRAGMENT_PROGRAM_ARB);

 

 

 

and this too, I missed:

 

 

 


#define MAX_GLPROGS            200

// a single file can have both a vertex program and a fragment program
static progDef_t    progs[MAX_GLPROGS] = {
   { GL_VERTEX_PROGRAM_ARB, VPROG_TEST, "test.vfp" },
   { GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST, "test.vfp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION, "interaction.vfp" },
   { GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION, "interaction.vfp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp" },
   { GL_FRAGMENT_PROGRAM_ARB, FPROG_BUMPY_ENVIRONMENT, "bumpyEnvironment.vfp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_AMBIENT, "ambientLight.vfp" },
   { GL_FRAGMENT_PROGRAM_ARB, FPROG_AMBIENT, "ambientLight.vfp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW, "shadow.vp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_R200_INTERACTION, "R200_interaction.vp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_BUMP_AND_LIGHT, "nv20_bumpAndLight.vp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_COLOR, "nv20_diffuseColor.vp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_SPECULAR_COLOR, "nv20_specularColor.vp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR, "nv20_diffuseAndSpecularColor.vp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_ENVIRONMENT, "environment.vfp" },
   { GL_FRAGMENT_PROGRAM_ARB, FPROG_ENVIRONMENT, "environment.vfp" },

   // rebb: direct light interaction files for performance testing
   { GL_VERTEX_PROGRAM_ARB, VPROG_TEST_DIRECT, "test_direct.vfp" },
   { GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST_DIRECT, "test_direct.vfp" },
   { GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION_DIRECT, "interaction_direct.vfp" },
   { GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION_DIRECT, "interaction_direct.vfp" },

   // additional programs can be dynamically specified in materials
};

 

 

 

 

 

I hope that helps you complete the picture :)

 

Edit: We also need to increase the max glprogs number we already have errors about that...

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

Hey steve. Well here in denmark its quite late hehe so good evening.

Sikkpins shaders are more of a test i presume so it might not fit all purposes but its a good start :).

And to nbor1more looks a bit like the same method sikkpin used to split out parts of the interaction shaders,

making it possible to have different ones for say POM (parallax mapping does not fit all image types, banding problem on some texture types. Need a perfectly flat image or it fucks up majorly).

You should have a look at the changes he made to the editor for supporting ambient lights natively :) allthough the static version in his mod works it has the same level all through the game, but with the changes to the editor code its possible to code in different levels and colors pr map.

 

Probably a lot of work left even if his code is a good start.

Link to comment
Share on other sites

OK, I went ahead and made the changes against the files in public SVN access.

 

It looks like these are the only changes needed to make new light types that use the

existing light geometry and available image map types.

 

You would merge these changes and rename the example shader code I posted to cubic_light.vfp

and place it into glprogs then make a light material with the cubicLight keyword added.

 

I'm gonna look at what it would take to make the material parser load a 3D texture for possible light-mapping

purposes next...

draw_arb2.cpp.txt

Material.cpp.txt

Material.h.txt

Edited by nbohr1more
  • Like 1

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

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

    • Petike the Taffer  »  DeTeEff

      I've updated the articles for your FMs and your author category at the wiki. Your newer nickname (DeTeEff) now comes first, and the one in parentheses is your older nickname (Fieldmedic). Just to avoid confusing people who played your FMs years ago and remember your older nickname. I've added a wiki article for your latest FM, Who Watches the Watcher?, as part of my current updating efforts. Unless I overlooked something, you have five different FMs so far.
      · 0 replies
    • Petike the Taffer

      I've finally managed to log in to The Dark Mod Wiki. I'm back in the saddle and before the holidays start in full, I'll be adding a few new FM articles and doing other updates. Written in Stone is already done.
      · 4 replies
    • nbohr1more

      TDM 15th Anniversary Contest is now active! Please declare your participation: https://forums.thedarkmod.com/index.php?/topic/22413-the-dark-mod-15th-anniversary-contest-entry-thread/
       
      · 0 replies
    • JackFarmer

      @TheUnbeholden
      You cannot receive PMs. Could you please be so kind and check your mailbox if it is full (or maybe you switched off the function)?
      · 1 reply
    • OrbWeaver

      I like the new frob highlight but it would nice if it was less "flickery" while moving over objects (especially barred metal doors).
      · 4 replies
×
×
  • Create New...