https://wiki.bo3b.net/api.php?action=feedcontributions&user=Bo3b+admin&feedformat=atomBo3b's School for Shaderhackers - User contributions [en]2024-03-29T08:34:06ZUser contributionsMediaWiki 1.22.6https://wiki.bo3b.net/index.php?title=Canonical_Stereo_CodeCanonical Stereo Code2023-12-25T01:31:14Z<p>Bo3b admin: /* Prime Directive */</p>
<hr />
<div>=== Prime Directive ===<br />
<br />
This is the ''prime directive'' code in ASM for DX9 and HelixMod. And the HLSL version for 3Dmigoto. In all cases, we are implementing the NVidia specified formula of: <br><br><br />
<code>clipPos.x += EyeSign * Separation * ( clipPos.w – Convergence )</code><br />
<br />
<br />
''''' ASM (both HelixMod and 3Dmigoto ASM) '''''<br />
<br />
This is the wordy version with extra comments to make it more clear what is happening.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// The required constant for txldl in c200.z<br />
def c200, 1.0, 600, 0.0625, 0<br />
// Sampler used to fetch stereo params, <br />
// s0 sampler is default for VS<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
// Fetch the Separation (r30.x) and Convergence (r30.y) <br />
// using the Helix NVapi trick<br />
texldl r30, c200.z, s0<br />
<br />
// (W - Convergence)<br />
add r30.w, r0.w, -r30.y<br />
<br />
// multiply that times Separation for:<br />
// Separation * (W - Convergence)<br />
mul r30.z, r30.x, r30.w<br />
<br />
// Add that to Xold for the complete:<br />
// Xold + Separation * (W - Convergence)<br />
add r0.x, r0.x, r30.z<br />
<br />
</syntaxhighlight><br />
<br />
<br />
Another variant that is more concise, but less clear. As you get more accustomed to seeing this sequence of code, or are sharing with an expert crowd, it's less necessary to fully document this part, as it is always the same sequence and easy to recognize because of the texldl of 0.0625.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mad r0.x, r30.x, r30.w, r0.x<br />
</syntaxhighlight><br />
<br />
<br />
Another very common variant you'll see in HelixMod fixes is the four line version, with no comments. This is less optimal than the two above, but is worth seeing to be able to recognize it.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mul r30.z, r30.x, r30.w<br />
add r0.x, r0.x, r30.z<br />
</syntaxhighlight><br />
<br />
<br />
Slightly different variant needed for SM 4 and SM 5 shaders.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// 3DMigoto StereoParams in dcl section<br />
dcl_resource_texture2d (float,float,float,float) t125<br />
...<br />
<br />
// Load r10 with stereo params<br />
ld_indexable(texture2d)(float,float,float,float) r10.xyzw, l(0, 0, 0, 0), t125.xyzw<br />
<br />
// Temp output because we cannot use o0 as a register here<br />
//add o0.xyzw, r0.xyzw, cb0[19].xyzw example shader output<br />
add r9.xyzw, r0.xyzw, cb0[19].xyzw<br />
<br />
// (W - Convergence)<br />
add r10.w, r9.w, -r10.y<br />
<br />
// multiply that times Separation for:<br />
// Separation * (W - Convergence)<br />
mul r10.z, r10.x, r10.w<br />
<br />
// Add that to Xold for the complete:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
add r9.x, r9.x, r10.z<br />
<br />
// Assign temp to output<br />
mov o0.xyzw, r9.xyzw<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The HLSL version is very similar, but since it's a compile language there is no need to be terse when writing the code. We can make it "self-documenting" by using good variable names.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
float separation = StereoParams.Load(0).x;<br />
float convergence = StereoParams.Load(0).y;<br />
<br />
// At this point, "location" is the output position, but missing stereo.<br />
<br />
location.x += separation * (location.w - convergence);<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
=== Matrix Inversion ===<br />
<br />
We often need to invert a ViewProjectionMatrix, in order to be able to stereo correct a location in the proper viewspace (usually projection space for deferred rendering).<br />
<br />
We only need to do this in cases where the inverted matrix is not available. A lot of games have both matrices available, and can be used directly. <br />
<br />
We have code samples for both ASM, and for HLSL. It's worth noting that for HelixMod fixes in DX9, that HelixMod already supports [[HelixMod_Feature_List#InverseMatrix.2C_InverseMatrix1|inverted matrices]] directly, and this code should not be used there, because all this extra code will impact performance. Try to avoid using it in PS in particular, because inverting a matrix for every pixel is very costly.<br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The '''best''' way to invert a matrix is to use the runtime shader feature from d3dx.ini. This is best because it runs once per frame, which keeps a performance impact low. This was created by ''DarkStarSword''.<br />
<br />
[https://github.com/bo3b/3Dmigoto/wiki/Injecting-custom-shaders Described here] The actual shader is found [https://github.com/DarkStarSword/3d-fixes/blob/e0f67a3bed5fa90d8823a31b014e607f51c4fefc/inverse-cs.hlsl here] And, how to use it, described [https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4909267/#4909267 here]<br />
<br />
<br />
If that doesn't work for some reason (not all games are compatible), it's possible to do it in HLSL directly. This example is backwards in that it starts with an inverted matrix, then creates the forward matrix from that. Used in an example [https://github.com/DarkStarSword/3d-fixes/blob/master/Mad%20Max/ShaderFixes/01037617f0200a5c-ps_replace.txt here] Again, it's worth noting that doing this in a PS shader is sub-optimal.<br />
<br />
<br />
This version is found in matrix.hlsl, created by ''DarkStarSword''. It can be added into the header of any HLSL file, or #included.<br />
<br />
An original can be found [https://github.com/DarkStarSword/3d-fixes/blob/master/ABZU/ShaderFixes/matrix.hlsl here]<br />
<syntaxhighlight lang="c"><br />
matrix inverse(matrix m)<br />
{<br />
matrix inv;<br />
<br />
float det = determinant(m);<br />
inv[0].x = m[1].y*(m[2].z*m[3].w - m[2].w*m[3].z) + m[1].z*(m[2].w*m[3].y - m[2].y*m[3].w) + m[1].w*(m[2].y*m[3].z - m[2].z*m[3].y);<br />
inv[0].y = m[0].y*(m[2].w*m[3].z - m[2].z*m[3].w) + m[0].z*(m[2].y*m[3].w - m[2].w*m[3].y) + m[0].w*(m[2].z*m[3].y - m[2].y*m[3].z);<br />
inv[0].z = m[0].y*(m[1].z*m[3].w - m[1].w*m[3].z) + m[0].z*(m[1].w*m[3].y - m[1].y*m[3].w) + m[0].w*(m[1].y*m[3].z - m[1].z*m[3].y);<br />
inv[0].w = m[0].y*(m[1].w*m[2].z - m[1].z*m[2].w) + m[0].z*(m[1].y*m[2].w - m[1].w*m[2].y) + m[0].w*(m[1].z*m[2].y - m[1].y*m[2].z);<br />
inv[1].x = m[1].x*(m[2].w*m[3].z - m[2].z*m[3].w) + m[1].z*(m[2].x*m[3].w - m[2].w*m[3].x) + m[1].w*(m[2].z*m[3].x - m[2].x*m[3].z);<br />
inv[1].y = m[0].x*(m[2].z*m[3].w - m[2].w*m[3].z) + m[0].z*(m[2].w*m[3].x - m[2].x*m[3].w) + m[0].w*(m[2].x*m[3].z - m[2].z*m[3].x);<br />
inv[1].z = m[0].x*(m[1].w*m[3].z - m[1].z*m[3].w) + m[0].z*(m[1].x*m[3].w - m[1].w*m[3].x) + m[0].w*(m[1].z*m[3].x - m[1].x*m[3].z);<br />
inv[1].w = m[0].x*(m[1].z*m[2].w - m[1].w*m[2].z) + m[0].z*(m[1].w*m[2].x - m[1].x*m[2].w) + m[0].w*(m[1].x*m[2].z - m[1].z*m[2].x);<br />
inv[2].x = m[1].x*(m[2].y*m[3].w - m[2].w*m[3].y) + m[1].y*(m[2].w*m[3].x - m[2].x*m[3].w) + m[1].w*(m[2].x*m[3].y - m[2].y*m[3].x);<br />
inv[2].y = m[0].x*(m[2].w*m[3].y - m[2].y*m[3].w) + m[0].y*(m[2].x*m[3].w - m[2].w*m[3].x) + m[0].w*(m[2].y*m[3].x - m[2].x*m[3].y);<br />
inv[2].z = m[0].x*(m[1].y*m[3].w - m[1].w*m[3].y) + m[0].y*(m[1].w*m[3].x - m[1].x*m[3].w) + m[0].w*(m[1].x*m[3].y - m[1].y*m[3].x);<br />
inv[2].w = m[0].x*(m[1].w*m[2].y - m[1].y*m[2].w) + m[0].y*(m[1].x*m[2].w - m[1].w*m[2].x) + m[0].w*(m[1].y*m[2].x - m[1].x*m[2].y);<br />
inv[3].x = m[1].x*(m[2].z*m[3].y - m[2].y*m[3].z) + m[1].y*(m[2].x*m[3].z - m[2].z*m[3].x) + m[1].z*(m[2].y*m[3].x - m[2].x*m[3].y);<br />
inv[3].y = m[0].x*(m[2].y*m[3].z - m[2].z*m[3].y) + m[0].y*(m[2].z*m[3].x - m[2].x*m[3].z) + m[0].z*(m[2].x*m[3].y - m[2].y*m[3].x);<br />
inv[3].z = m[0].x*(m[1].z*m[3].y - m[1].y*m[3].z) + m[0].y*(m[1].x*m[3].z - m[1].z*m[3].x) + m[0].z*(m[1].y*m[3].x - m[1].x*m[3].y);<br />
inv[3].w = m[0].x*(m[1].y*m[2].z - m[1].z*m[2].y) + m[0].y*(m[1].z*m[2].x - m[1].x*m[2].z) + m[0].z*(m[1].x*m[2].y - m[1].y*m[2].x);<br />
inv /= det;<br />
<br />
return inv;<br />
}<br />
<br />
matrix inverse(float4 m0, float4 m1, float4 m2, float4 m3)<br />
{<br />
return inverse(matrix(m0, m1, m2, m3));<br />
}<br />
<br />
#define MATRIX(cb, idx) matrix(cb[idx], cb[idx+1], cb[idx+2], cb[idx+3])<br />
</syntaxhighlight><br />
<br />
<br />
<br />
<br />
The original version of this came from ''Mike_ar69''.<br />
<syntaxhighlight lang="c"><br />
...<br />
matrix ivp, vp;<br />
ivp = matrix(InstanceConsts[1], InstanceConsts[2], InstanceConsts[3], InstanceConsts[4]);<br />
<br />
// Work out the view-projection matrix from it's inverse:<br />
vp[0].x = ivp[1].y*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[1].z*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[1].w*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y);<br />
vp[0].y = ivp[0].y*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[0].z*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[0].w*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z);<br />
vp[0].z = ivp[0].y*(ivp[1].z*ivp[3].w - ivp[1].w*ivp[3].z) + ivp[0].z*(ivp[1].w*ivp[3].y - ivp[1].y*ivp[3].w) + ivp[0].w*(ivp[1].y*ivp[3].z - ivp[1].z*ivp[3].y);<br />
vp[0].w = ivp[0].y*(ivp[1].w*ivp[2].z - ivp[1].z*ivp[2].w) + ivp[0].z*(ivp[1].y*ivp[2].w - ivp[1].w*ivp[2].y) + ivp[0].w*(ivp[1].z*ivp[2].y - ivp[1].y*ivp[2].z);<br />
vp[1].x = ivp[1].x*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[1].z*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[1].w*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z);<br />
vp[1].y = ivp[0].x*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[0].z*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[0].w*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x);<br />
vp[1].z = ivp[0].x*(ivp[1].w*ivp[3].z - ivp[1].z*ivp[3].w) + ivp[0].z*(ivp[1].x*ivp[3].w - ivp[1].w*ivp[3].x) + ivp[0].w*(ivp[1].z*ivp[3].x - ivp[1].x*ivp[3].z);<br />
vp[1].w = ivp[0].x*(ivp[1].z*ivp[2].w - ivp[1].w*ivp[2].z) + ivp[0].z*(ivp[1].w*ivp[2].x - ivp[1].x*ivp[2].w) + ivp[0].w*(ivp[1].x*ivp[2].z - ivp[1].z*ivp[2].x);<br />
vp[2].x = ivp[1].x*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[1].y*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[1].w*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[2].y = ivp[0].x*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[0].y*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[0].w*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[2].z = ivp[0].x*(ivp[1].y*ivp[3].w - ivp[1].w*ivp[3].y) + ivp[0].y*(ivp[1].w*ivp[3].x - ivp[1].x*ivp[3].w) + ivp[0].w*(ivp[1].x*ivp[3].y - ivp[1].y*ivp[3].x);<br />
vp[2].w = ivp[0].x*(ivp[1].w*ivp[2].y - ivp[1].y*ivp[2].w) + ivp[0].y*(ivp[1].x*ivp[2].w - ivp[1].w*ivp[2].x) + ivp[0].w*(ivp[1].y*ivp[2].x - ivp[1].x*ivp[2].y);<br />
vp[3].x = ivp[1].x*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z) + ivp[1].y*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x) + ivp[1].z*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[3].y = ivp[0].x*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y) + ivp[0].y*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z) + ivp[0].z*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[3].z = ivp[0].x*(ivp[1].z*ivp[3].y - ivp[1].y*ivp[3].z) + ivp[0].y*(ivp[1].x*ivp[3].z - ivp[1].z*ivp[3].x) + ivp[0].z*(ivp[1].y*ivp[3].x - ivp[1].x*ivp[3].y);<br />
vp[3].w = ivp[0].x*(ivp[1].y*ivp[2].z - ivp[1].z*ivp[2].y) + ivp[0].y*(ivp[1].z*ivp[2].x - ivp[1].x*ivp[2].z) + ivp[0].z*(ivp[1].x*ivp[2].y - ivp[1].y*ivp[2].x);<br />
vp /= determinant(ivp);<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM (DX9 ASM) '''''<br />
<br />
This one hasn't been fully tested, but should work. This is created by ''mx-2'' and found on his [https://github.com/mx-2/3d-fix/blob/master/_tools_/inverseMatrix.asm GitHub]<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
//<br />
// inverseMatrix.asm<br />
//<br />
// Matrix inversion with Gauss-Jordan elimination<br />
// algorithm on GPU.<br />
//<br />
// This algorithm uses 128 instructions, from which<br />
// 83 (best case) to 110 (worst case) are executed.<br />
//<br />
// input matrix is in r0-r3<br />
// output will be in r4-r7<br />
// r8, r9 are used as temporary registers<br />
// c200 = (1,0,0,0) is required<br />
//<br />
// r0.x r0.y r0.z r0.w | r4.x, r4.y, r4.z, r4.w<br />
// r1.x r1.y r1.z r1.w | r5.x, r5.y, r5.z, r5.w<br />
// r2.x r2.y r2.z r2.w | r6.x, r6.y, r6.z, r6.w<br />
// r3.x r3.y r3.z r3.w | r7.x, r7.y, r7.z, r7.w<br />
//<br />
// Test:<br />
// SETR r0, 0, 2, 3, 4<br />
// SETR r1, 1, 0, 5, 4<br />
// SETR r2,-1, 2, 3, 4<br />
// SETR r3, 0, 2, 3, 5<br />
//<br />
// Should produce<br />
// r4 = 1.0, 0.0, -1.0, 0.0<br />
// r5 = 1.6, -0.3, -0.3, -0.8<br />
// r6 = 0.6, 0.2, 0.2, -0.8<br />
// r7 = -1.0, 0.0, 0.0, 1.0<br />
//<br />
<br />
// Init registers<br />
def c200, 1, 0, 0, 0<br />
mov r4, c200.xyzw<br />
mov r5, c200.wxyz<br />
mov r6, c200.zwxy<br />
mov r7, c200.yzwx<br />
<br />
// Pivot first column<br />
mov r8, c200<br />
if_eq r0.x, r8.y<br />
if_eq r1.x, r8.y<br />
if_eq r2.x, r8.y<br />
mov r9, r0<br />
mov r0, r3<br />
mov r3, r9<br />
mov r9, r4<br />
mov r4, r7<br />
mov r7, r9<br />
else<br />
mov r9, r0<br />
mov r0, r2<br />
mov r2, r9<br />
mov r9, r4<br />
mov r4, r6<br />
mov r6, r9<br />
endif<br />
else<br />
mov r9, r0<br />
mov r0, r1<br />
mov r1, r9<br />
mov r9, r4<br />
mov r4, r5<br />
mov r5, r9<br />
endif<br />
endif<br />
<br />
// First column<br />
rcp r8.x, r0.x<br />
mul r8.y, r8.x, r1.x<br />
mul r9, r0, r8.y<br />
add r1, r1, -r9<br />
mul r9, r4, r8.y<br />
add r5, r5, -r9<br />
<br />
mul r8.y, r8.x, r2.x<br />
mul r9, r0, r8.y<br />
add r2, r2, -r9<br />
mul r9, r4, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.x<br />
mul r9, r0, r8.y<br />
add r3, r3, -r9<br />
mul r9, r4, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot second column<br />
mov r8, c200<br />
if_eq r1.y, r8.y<br />
if_eq r2.y, r8.y<br />
mov r9, r1<br />
mov r1, r3<br />
mov r3, r9<br />
mov r9, r5<br />
mov r5, r7<br />
mov r7, r9<br />
else<br />
mov r9, r1<br />
mov r1, r2<br />
mov r2, r9<br />
mov r9, r5<br />
mov r5, r6<br />
mov r6, r9<br />
endif<br />
endif<br />
<br />
// Second column<br />
rcp r8.x, r1.y<br />
mul r8.y, r8.x, r2.y<br />
mul r9, r1, r8.y<br />
add r2, r2, -r9<br />
mul r9, r5, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.y<br />
mul r9, r1, r8.y<br />
add r3, r3, -r9<br />
mul r9, r5, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot third column<br />
mov r8, c200<br />
if_eq r2.z, r8.y<br />
mov r9, r2<br />
mov r2, r3<br />
mov r3, r9<br />
mov r9, r6<br />
mov r6, r7<br />
mov r7, r9<br />
endif<br />
<br />
// Third column<br />
rcp r8.x, r2.z<br />
mul r8.y, r8.x, r3.z<br />
mul r9, r2, r8.y<br />
add r3, r3, -r9<br />
mul r9, r6, r8.y<br />
add r7, r7, -r9<br />
<br />
// Normalize r3.w<br />
rcp r8.x, r3.w<br />
mul r3, r3, r8.x<br />
mul r7, r7, r8.x<br />
<br />
// Fourth column<br />
mul r8, r3, r2.w<br />
mul r9, r7, r2.w<br />
add r2, r2, -r8<br />
add r6, r6, -r9<br />
<br />
mul r8, r3, r1.w<br />
mul r9, r7, r1.w<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r3, r0.w<br />
mul r9, r7, r0.w<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r2.z<br />
rcp r8.x, r2.z<br />
mul r2, r2, r8.x<br />
mul r6, r6, r8.x<br />
<br />
// Third column (upper part)<br />
mul r8, r2, r1.z<br />
mul r9, r6, r1.z<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r2, r0.z<br />
mul r9, r6, r0.z<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r1.y<br />
rcp r8.x, r1.y<br />
mul r1, r1, r8.x<br />
mul r5, r5, r8.x<br />
<br />
// Second column (upper part)<br />
mul r8, r1, r0.y<br />
mul r9, r5, r0.y<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize first column<br />
rcp r8.x, r0.x<br />
mul r0, r0, r8.x<br />
mul r4, r4, r8.x<br />
...<br />
</syntaxhighlight><br />
<br />
----<br />
<br />
''''' DX9 ASM (Euclidean Matrices Only) '''''<br />
<br />
A hand-optimised DX9 asm version for column-major "euclidean" matrices that only uses 21 instructions. Note that it cannot be used for matrices that include a projection matrix and assumes that the 4th column is 0,0,0,1 - this is suitable to inverse a view or world-view matrix, but will not work for a projection or view-projection matrix - if you are not sure what kind of matrix you are inversing, do not use this version. Also note that the resulting matrix will be transposed to row-major order, so you may need to switch to mul/mad/mad/add type matrix multiply when you use this rather than dp4/dp4/dp4/dp4.<br />
<br />
Source matrix is in r20-r23, destination is in r26-r29. r31.x must be 0. r25 and r30 are used for temporary values and will be clobbered.<br />
<br />
<syntaxhighlight lang="c"><br />
// Do some multiplications & subtractions in parallel with SIMD instructions:<br />
mul r25.xyz, r20.zxy, r21.yzx // m0.z*m1.y, m0.x*m1.z, m0.y*m1.x<br />
mad r25.xyz, r20.yzx, r21.zxy, -r25.xyz // m0.y*m1.z - m0.z*m1.y, m0.z*m1.x - m0.x*m1.z, m0.x*m1.y - m0.y*m1.x<br />
// Now the multiplications:<br />
mul r25.xyz, r25.xyz, r22.xyz<br />
// Sum it together to get the determinant:<br />
add r30.x, r25.x, r25.y<br />
add r30.x, r30.x, r25.z<br />
<br />
// 1st row, simplifying by assuimg the 4th column 0,0,0,1<br />
// dst0.x = (m1.y*m2.z - m1.z*m2.y)<br />
// dst0.y = (m1.z*m2.x - m1.x*m2.z)<br />
// dst0.z = (m1.x*m2.y - m1.y*m2.x)<br />
// dst0.w = 0<br />
<br />
mul r26.xyz, r21.zxy, r22.yzx<br />
mad r26.xyz, r21.yzx, r22.zxy, -r26.xyz<br />
<br />
// 2nd row<br />
// dst1.x = (col0.z*m2.y - col0.y*m2.z)<br />
// dst1.y = (col0.x*m2.z - col0.z*m2.x)<br />
// dst1.z = (col0.y*m2.x - col0.x*m2.y)<br />
// dst1.w = 0<br />
<br />
mul r27.xyz, r20.yzx, r22.zxy<br />
mad r27.xyz, r20.zxy, r22.yzx, -r27.xyz<br />
<br />
// 3nd row<br />
// dst2.x = (col0.y*m1.z - col0.z*m1.y)<br />
// dst2.y = (col0.z*m1.x - col0.x*m1.z)<br />
// dst2.z = (col0.x*m1.y - col0.y*m1.x)<br />
// dst2.w = 0<br />
<br />
mul r28.xyz, r20.zxy, r21.yzx<br />
mad r28.xyz, r20.yzx, r21.zxy, -r28.xyz<br />
<br />
// 4th row<br />
// dst3.x = - col0.w*dst0.x - col1.w*dst1.x - col2.w*dst2.x<br />
// dst3.y = - col0.w*dst0.y - col1.w*dst1.y - col2.w*dst2.y<br />
// dst3.z = - col0.w*dst0.z - col1.w*dst1.z - col2.w*dst2.z<br />
// dst3.w = col0.x*dst0.x + col1.x*dst1.x + col2.x*dst2.x (always 1?)<br />
<br />
mul r29.xyzw, r20.wwwx, r26.xyzx<br />
mad r29.xyzw, r21.wwwx, r27.xyzx, r29.xyzw<br />
mad r29.xyzw, r22.wwwx, r28.xyzx, r29.xyzw<br />
mov r29.xyz, -r29<br />
<br />
// Multiply against 1/determinant (and zero out 4th column):<br />
rcp r25.x, r30.x<br />
mov r25.y, r31.x<br />
mul r26, r26, r25.xxxy<br />
mul r27, r27, r25.xxxy<br />
mul r28, r28, r25.xxxy<br />
mul r29, r29, r25.xxxx<br />
<br />
// Note that this matrix has been transposed and is now in ROW major order!<br />
</syntaxhighlight><br />
<br />
The above code is generated by DarkStarSword's pyasm.py and matrix.py (both of which are available in my [https://github.com/DarkStarSword/3d-fixes 3d-fixes] repository), which can be used to generate variants of the above using whichever registers are needed. I never quite got around to making this easy to use, but the above code was created with these commands:<br />
<br />
<syntaxhighlight lang="c"><br />
$ python3<br />
>>> import pyasm<br />
>>> import matrix<br />
>>> pyasm.py_to_asm(matrix._determinant_euclidean_asm_col_major, col0='r20', col1='r21', col2='r22', det='r30', tmp0='r25')<br />
>>> pyasm.py_to_asm(matrix._inverse_euclidean_asm_col_major, col0='r20', col1='r21', col2='r22', det='r30', dst0='r26', dst1='r27', dst2='r28', dst3='r29', inv_det='r25', std_consts='r31')<br />
</syntaxhighlight><br />
<br />
----<br />
<br />
Two more variants, both from Helifax. In case those previous ones don't seem quite right.<br />
<br />
''''' HLSL '''''<br />
<br />
<syntaxhighlight lang="c"><br />
//Work out Inverse<br />
//...Variables<br />
float4 a1, a2, a3, a4;<br />
float4 b1, b2, b3, b4;<br />
float det;<br />
//...Original Matrix<br />
a1 = g_invViewProjMatrix._m00_m10_m20_m30;<br />
a2 = g_invViewProjMatrix._m01_m11_m21_m31;<br />
a3 = g_invViewProjMatrix._m02_m12_m22_m32;<br />
a4 = g_invViewProjMatrix._m03_m13_m23_m33;<br />
//...Determinant<br />
det = a1.x*(a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y));<br />
det += a1.y*(a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.z) + a2.w*(a3.z*a4.x - a3.x*a4.z));<br />
det += a1.z*(a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x));<br />
det += a1.w*(a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y));<br />
//...Inverse Matrix Elements<br />
b1.x = a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y);<br />
b1.y = a1.y*(a3.w*a4.z - a3.z*a4.w) + a1.z*(a3.y*a4.w - a3.w*a4.y) + a1.w*(a3.z*a4.y - a3.y*a4.z);<br />
b1.z = a1.y*(a2.z*a4.w - a2.w*a4.z) + a1.z*(a2.w*a4.y - a2.y*a4.w) + a1.w*(a2.y*a4.z - a2.z*a4.y);<br />
b1.w = a1.y*(a2.w*a3.z - a2.z*a3.w) + a1.z*(a2.y*a3.w - a2.w*a3.y) + a1.w*(a2.z*a3.y - a2.y*a3.z);<br />
b2.x = a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.x) + a2.w*(a3.z*a4.x - a3.x*a4.z);<br />
b2.y = a1.x*(a3.z*a4.w - a3.w*a4.z) + a1.z*(a3.w*a4.x - a3.x*a4.w) + a1.w*(a3.x*a4.z - a3.z*a4.x);<br />
b2.z = a1.x*(a2.w*a4.z - a2.z*a4.w) + a1.z*(a2.x*a4.w - a2.w*a4.x) + a1.w*(a2.z*a4.x - a2.x*a4.z);<br />
b2.w = a1.x*(a2.z*a3.w - a2.w*a3.z) + a1.z*(a2.w*a3.x - a2.x*a3.w) + a1.w*(a2.x*a3.z - a2.z*a3.x);<br />
b3.x = a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x);<br />
b3.y = a1.x*(a3.w*a4.y - a3.y*a4.w) + a1.y*(a3.x*a4.w - a3.w*a4.x) + a1.w*(a3.y*a4.x - a3.x*a4.y);<br />
b3.z = a1.x*(a2.y*a4.w - a2.w*a4.y) + a1.y*(a2.w*a4.x - a2.x*a4.w) + a1.w*(a2.x*a4.y - a2.y*a4.x);<br />
b3.w = a1.x*(a2.w*a3.y - a2.y*a3.w) + a1.y*(a2.x*a3.w - a2.w*a3.x) + a1.w*(a2.y*a3.x - a2.x*a3.y);<br />
b4.x = a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y);<br />
b4.y = a1.x*(a3.y*a4.z - a3.z*a4.y) + a1.y*(a3.z*a4.x - a3.x*a4.z) + a1.z*(a3.x*a4.y - a3.y*a4.x);<br />
b4.z = a1.x*(a2.z*a4.y - a2.y*a4.z) + a1.y*(a2.x*a4.z - a2.z*a4.x) + a1.z*(a2.y*a4.x - a2.x*a4.y);<br />
b4.w = a1.x*(a2.y*a3.z - a2.z*a3.y) + a1.y*(a2.z*a3.x - a2.x*a3.z) + a1.z*(a2.x*a3.y - a2.y*a3.x);<br />
b1.xyzw /= det;<br />
b2.xyzw /= det;<br />
b3.xyzw /= det;<br />
b4.xyzw /= det;<br />
//End Inverse<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM '''''<br />
<br />
Generated from the HLSL, using fxc.<br />
<syntaxhighlight lang="c"><br />
// Declare how many registers ww use<br />
// The code uses registers from r38 to r53.<br />
dcl_temps 60<br />
<br />
// 3DMigoto StereoParams:<br />
dcl_resource_texture1d (float,float,float,float) t120<br />
dcl_resource_texture2d (float,float,float,float) t125<br />
ld_indexable(texture1d)(float,float,float,float) r41.xyzw, l(0, 0, 0, 0), t120.xyzw<br />
ld_indexable(texture2d)(float,float,float,float) r40.xyzw, l(0, 0, 0, 0), t125.xyzw<br />
<br />
// Inverse<br />
// cb0[0], etc is the inverseMatrix<br />
mov r0.xyzw, cb0[0].xyzw<br />
mov r1.xyzw, cb0[1].xyzw<br />
mov r2.xyzw, cb0[2].xyzw<br />
mov r3.xyzw, cb0[3].xyzw<br />
mul r4.x, r2.z, r3.w<br />
mul r4.y, r2.w, r3.z<br />
mov r4.y, -r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r1.y, r4.x<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.z<br />
mul r4.z, r2.z, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r0.x, r4.x<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.y<br />
mul r4.z, r2.y, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.y, r4.y<br />
mul r4.z, r2.w, r3.y<br />
mul r4.w, r2.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.z<br />
mul r4.w, r2.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r5.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r2.y, r3.w<br />
mul r4.w, r2.w, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.y<br />
mul r4.w, r2.y, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.y, r4.z, r4.y<br />
mul r4.y, r1.z, r3.w<br />
mul r4.z, r1.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.w, r3.y<br />
mul r4.w, r1.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.y, r3.z<br />
mul r4.w, r1.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.z, r4.z, r4.y<br />
mul r4.y, r1.w, r2.z<br />
mul r4.z, r1.z, r2.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.y, r2.w<br />
mul r4.w, r1.w, r2.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r2.y<br />
mul r4.w, r1.y, r2.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.w, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r6.x, r4.z, r4.y<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.y, r4.z, r4.y<br />
mul r4.y, r1.w, r3.z<br />
mul r4.z, r1.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.x, r3.w<br />
mul r4.w, r1.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r3.x<br />
mul r4.w, r1.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.z, r4.z, r4.y<br />
mul r4.y, r1.z, r2.w<br />
mul r4.z, r1.w, r2.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r2.x<br />
mul r4.w, r1.x, r2.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.x, r2.z<br />
mul r4.w, r1.z, r2.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.w, r4.z, r4.y<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r7.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r7.y, r4.z, r4.y<br />
mul r4.y, r1.y, r3.w<br />
mul r4.z, r1.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r3.x<br />
mul r3.w, r1.x, r3.w<br />
mov r3.w, -r3.w<br />
add r3.w, r3.w, r4.z<br />
mul r3.w, r0.y, r3.w<br />
add r3.w, r3.w, r4.y<br />
mul r4.y, r1.x, r3.y<br />
mul r4.z, r1.y, r3.x<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r7.z, r3.w, r4.y<br />
mul r3.w, r1.w, r2.y<br />
mul r4.y, r1.y, r2.w<br />
mov r4.y, -r4.y<br />
add r3.w, r3.w, r4.y<br />
mul r3.w, r0.x, r3.w<br />
mul r2.w, r1.x, r2.w<br />
mul r1.w, r1.w, r2.x<br />
mov r1.w, -r1.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r1.w, r1.w, r3.w<br />
mul r2.w, r1.y, r2.x<br />
mul r3.w, r1.x, r2.y<br />
mov r3.w, -r3.w<br />
add r2.w, r2.w, r3.w<br />
mul r0.w, r0.w, r2.w<br />
add r7.w, r0.w, r1.w<br />
mul r0.w, r2.z, r3.y<br />
mul r1.w, r2.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r1.x<br />
mul r1.w, r2.x, r3.z<br />
mul r2.w, r2.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.y<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.y, r3.x<br />
mul r2.w, r2.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.z<br />
add r8.x, r0.w, r1.w<br />
mul r0.w, r2.y, r3.z<br />
mul r1.w, r2.z, r3.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r2.z, r3.x<br />
mul r2.w, r2.x, r3.z<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.x, r3.y<br />
mul r2.w, r2.y, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.y, r0.w, r1.w<br />
mul r0.w, r1.z, r3.y<br />
mul r1.w, r1.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r1.x, r3.z<br />
mul r2.w, r1.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r1.y, r3.x<br />
mul r2.w, r1.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.z, r0.w, r1.w<br />
mul r0.w, r1.y, r2.z<br />
mul r1.w, r1.z, r2.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.x, r0.w, r0.x<br />
mul r0.w, r1.z, r2.x<br />
mul r1.z, r1.x, r2.z<br />
mov r1.z, -r1.z<br />
add r0.w, r0.w, r1.z<br />
mul r0.y, r0.w, r0.y<br />
add r0.x, r0.y, r0.x<br />
mul r0.y, r1.x, r2.y<br />
mul r0.w, r1.y, r2.x<br />
mov r0.w, -r0.w<br />
add r0.y, r0.w, r0.y<br />
mul r0.y, r0.y, r0.z<br />
add r8.w, r0.y, r0.x<br />
div r0.xyzw, r5.xyzw, r4.xxxx<br />
div r1.xyzw, r6.xyzw, r4.xxxx<br />
div r2.xyzw, r7.xyzw, r4.xxxx<br />
div r3.xyzw, r8.xyzw, r4.xxxx<br />
<br />
// Store results for later use as r0-r4 are most <br />
// likely to be used by the default shader code.<br />
// r50 equivalent of matrix._m00_m01_m02_m03<br />
// r51 equivalent of matrix._m10_m11_m12_m13<br />
// r52 equivalent of matrix._m20_m21_m22_m23<br />
// r53 equivalent of matrix._m30_m31_m32_m33<br />
<br />
mov r50.xyzw, r0.xyzw <br />
mov r51.xyzw, r1.xyzw <br />
mov r52.xyzw, r2.xyzw <br />
mov r53.xyzw, r3.xyzw<br />
</syntaxhighlight></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Driver_Profile_SettingsDriver Profile Settings2019-11-28T00:11:05Z<p>Bo3b admin: /* Notable Settings */</p>
<hr />
<div>This page is a work in progress - feel free to expand it with extra knowledge, before & after screenshots, etc.<br />
<br />
<br />
== Tools ==<br />
<br />
The recommended tool for working with profiles is [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/2.1.2.12/artifacts NVIDIA Profile Inspector 2.1.2.12] or later due to its ability to decrypt internal settings.<br />
<br />
[https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/artifacts Latest continuous integration build]<br />
<br />
[https://github.com/Orbmu2k/nvidiaProfileInspector Source code]<br />
<br />
[http://forums.guru3d.com/showthread.php?t=403676 Forum thread] (note that the download linked from here does not yet support decrypting internal settings)<br />
<br />
3DMigoto 1.2.50 now has built in support for working with driver profiles, including decrypting and logging the current profile in d3d11_log.txt, and making any changes necessary when the game is launched.<br />
<br />
==== Obsolete tools: ====<br />
<br />
NVIDIA Profile Inspector 2.1.2.6 or older<br />
<br />
[http://orbmu2k.de/tools/nvidia-inspector-tool NVIDIA Inspector] 1.9.7.5 or older ([http://www.guru3d.com/files-details/nvidia-inspector-download.html English mirror])<br />
<br />
[http://nvidia.custhelp.com/app/answers/detail/a_id/2625/kw/Profile GeForce 3D Profile Manager]<br />
<br />
== NVIDIA Inspector Custom Stereo Settings Names ==<br />
<br />
NVIDIA Inspector (old versions): Download this [https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/CustomSettingNames_en-EN.xml CustomSettingNames_en-EN.xml] file to replace the one from NVIDIA Inspector, which will add all the settings listed on this page to the Stereo category.<br />
<br />
NVIDIA Profile Inspector: This program automatically decodes most setting names (you may need to select "Show unknown settings from NVIDIA predefined profiles" to see them) '''Edit: This no longer works as recent drivers have removed the DLLs that the tool relied on to find the stereo settings names'''. There are some exceptions - most notably the all important StereoProfile setting is missing. You can use the XML file linked above, but name it 'CustomSettingNames.xml' (i.e. remove the '_en-EN').<br />
<br />
== Important note about encoding of "Internal" Settings ==<br />
<br />
Some profiles are shipped with the internal settings flag set on certain settings. These show up with "InternalSettingFlag=V0" in Geforce Profile Manager, but there is no easy way to distinguish them in NVIDIA Inspector. These settings are encrypted and the values read out with these tools will not match any of the documentation here. Further, if they are written back with NVIDIA Inspector, the flag will be cleared and they will become corrupt. Geforce Profile Manager allows them to be written back with the flag intact avoiding the corruption, but still does not help understand them.<br />
<br />
A script to decipher these values from Geforce Profile Manager is available: [https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/__profiles__/sanitise_nv_profiles.py here]<br />
<br />
NVIDIA Profile Inspector 2.1.2.7 or later can correctly decode these, and is now the recommended tool for working with driver profiles. [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/2.1.2.7/artifacts Version 2.1.2.7] [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/artifacts Latest build]<br />
<br />
3DMigoto 1.2.50 and later includes support for logging and updating driver profiles, and correctly handles encrypted settings. The undocumented option [Logging] dump_all_profiles=1 can be used to have it decrypt and log every profile instead of just the ones relevant to the game being run.<br />
<br />
== Notes on settings with multiple IDs ==<br />
<br />
Some settings on this page are listed with two or three IDs. This is not fully understood yet. Generally you should stick to the first value listed, but if a profile also lists the second or third value in this list it might be used in place of the first (however a given profile will only use a specific ID out of the second or third in the list).<br />
<br />
The following settings have multiple IDs:<br />
{| class="wikitable"<br />
! Name || Primary ID || 1st Alternate ID || 2nd Alternate ID<br />
|-<br />
| StereoConvergence || 0x708DB8C5 || 0x7077BACE || 0x7084807E<br />
|-<br />
| LaserSight || 0x7058B6E1 || 0x7031A2E7 || 0x7045B752<br />
|-<br />
| FrustumAdjustMode || 0x70A1411A || 0x70ED1DA7 || 0x70F475A0<br />
|-<br />
| StereoTextureEnable || 0x70EDB381 || 0x70E1518C || 0x70C0125E<br />
|-<br />
| Rhwinf || 0x706E1913 || 0x70CC286A || 0x70A3FEE6<br />
|-<br />
| Rhwscr || 0x70A4995C || 0x7030B071 || 0x70B57ED1<br />
|-<br />
| InGameLaserSight || 0x7064F0C2 || 0x70DD2585 || 0x70E7ADAD<br />
|-<br />
| StereoCutoffDepthNear || 0x7050E011 || 0x704EF483 || 0x7031DE06<br />
|-<br />
| StereoCutoff || 0x709A1DDF || 0x704FCF5C || 0x7053569A<br />
|-<br />
| DX10VSCBNumber || 0x70F8E408 || || 0x70F64A32<br />
|}<br />
<br />
== StereoProfile (AKA The Mystery Stereo Setting) 0x701EB457 ==<br />
<br />
This setting is known to be very important to stereo profiles. We now know it's official name is STEREO_STEREOPROFILE, and will be referred to as "StereoProfile" in future releases of NVIDIA Profile Inspector.<br />
<br />
<u> Observations </u><br />
<br />
- The mere existance of this setting on a DX9 profile will enable Stereo in windowed mode, regardless of the value.<br />
<br />
- This setting is required to enable a lot of stereo related code in the driver.<br />
<br />
- Certain other stereo settings (e.g. StereoTextureEnable) may be ignored without this setting.<br />
<br />
- If this is missing in a profile, attempting to save the profile with Ctrl+F7 will not work, and will restore the default convergence instead. It has been noted that adding this setting to the base profile can solve this globally, but may cause the monitor to switch to stereo mode when using certain 2D applications (e.g. VS2015), which may be undesirable in some cases.<br />
<br />
<u>Bit Definitions</u><br />
<br />
{| class="wikitable"<br />
|Missing || Not a stereo profile (Certain things will not work, including saving the profile via Ctrl+F7)<br />
|-<br />
|0x00000000 || Not a stereo profile (Certain things will not work - need to confirm exactly what differs compared to missing)<br />
|-<br />
|0x00000001 || Stereo profile (everything will work)<br />
|-<br />
|0x2241AB21 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
== Notable Settings ==<br />
<br />
=== StereoTextureEnable (0x70edb381 / 0x70e1518c / 0x70c0125e) ===<br />
<br />
- Controls the heuristics that determines which render targets & Z buffers are stereoised and which are not.<br />
<br />
- Controls the heuristics that determines in what situations the stereo correction formula will be applied.<br />
<br />
- Some bits are used for specific games.<br />
<br />
<u> Observations </u><br />
<br />
- Setting this to all F's will turn a game into mono, suggesting that some high bits might filter out some render targets, rather than enabling them.<br />
<br />
<u> Bit Definitions </u><br />
<br />
Chiri determined a number of these (see [https://forums.geforce.com/default/topic/506784/3d-vision/l-a-noire-official-3d-vision-thread/post/3613599/#3613599 this post])<br />
<br />
{| class="wikitable"<br />
|0x00000001 || COMMON_STEREO_TEXTURE_ENABLED || The texture surfaces used as render targets are stereorized ( If their size >to window size and NOT square)<br />
|-<br />
|0x00000002 || SMALL_STEREO_TEXTURE_ENABLED || Enable the smaller texture surfaces to be stereorized ( If their size < to the window size and NOT square)<br />
|-<br />
|0x00000004 || SQUARE_STEREO_TEXTURE_ENABLED || The SQUARE texture surfaces are stereorized.<br />
|-<br />
|0x00000008 || DISABLE_BB_SEPARATION_IF_STEREO_TEX || When drawing in a Back buffer surface, the stereo separation is disabled if the draw call fetches from a stereo texture<br />
|-<br />
|0x00000010 || DISABLE_BB_SEPARATION_COMPLETELY || When drawing in a Back buffer surface, the stereo separation is disabled all the time<br />
|-<br />
|0x00000020 || COMMON_STEREO_PLANERT_ENABLED || Enable the common surface to be stereorized<br />
|-<br />
|0x00000040 || ORTHO_PROJECTION_DISABLED || Deprecated (only used for fixed pipe in d3d9 in ortho)<br />
|-<br />
|0x00000080 || ENABLE_SEPARATION_IF_ZBNULL || Enable the stereo separation when drawing in a stereo render target without using a Z buffer<br />
|-<br />
|0x00000100 || RESERVED_BY_DX10 || Specific value to disable Geometry Shader under DX10 (Call of Juarez)<br />
|-<br />
|0x00000200 || DISABLE_TEX_SEPARATION_IF_STEREO_TEX || When drawing in a Texture surface, the stereo separation is disabled if the draw call fetches from a stereo texture<br />
|-<br />
|0x00000400 || ENABLE_SEPARATION_IF_MONORT || Enable the stereo separation when drawing in a mono render target, but in a stereorized Z buffer.<br />
This should be enabled when doing a Z pass with a non valid render target (NULL format or 1x1 surface)<br />
|-<br />
|0x00000800 || DISABLE_FULLSCREEN_A8R8G8B8_STEREO_TEXTURES || The A8R8G8B8 full screen texture used as render target are not stereorized. Used for particular games<br />
|-<br />
|0x00001000 || DISABLE_SMALL_SQUARE_STEREO_TEXTURES || Do NOT stereorize the SQUARE texture if the width is smaller than the window width<br />
|-<br />
|0x00002000 || ENABLE_ALL_STEREO_ZB_SIZES || All the Z buffer are stereorized whitout any check on their size<br />
|-<br />
|0x00004000 || ENABLE_NULLFORMAT_PRIMSIZE_RT || Stereorize NULL format render target surfaces if their size is equal to the window size<br />
|-<br />
|0x00008000 || DISABLE_ALL_NULLFORMAT_RT || The NULL format render target surfaces are never stereorized<br />
|-<br />
|0x00040000 || ENABLE_VSSTEREO_SHADERS_WITHOUT_CONST || This bit allows to stereoize DX1x vs shaders if there are no const in a shader (i.e. vertices prerendered). By default these shaders are skipped<br />
|}<br />
<br />
<br />
<br />
<br />
<u> Known Values </u><br />
<br />
This only lists known values of games using the high bits (0x10000 and above), since the meaning of the low bits are all known. These high bits are believed to be for game specific quirks:<br />
<br />
{| class="wikitable"<br />
|0x0001xxxx || MX vs. ATV Reflex, Prince of Persia - The Forgotten Sands, Prince of Persia(gameinterpreters_rd.exe)<br />
|-<br />
|0x0002xxxx || Call of Duty: Modern Warfare 2, EverQuest II, F.E.A.R. 2: Project Origin, F.E.A.R. 2: Project Origin(Demo), Lost Planet: Colonies Edition, Serious Sam II, Vizerra Viewer<br />
|-<br />
|0x0003xxxx || Time of Shadows<br />
|-<br />
|0x0004xxxx || BioShock 2<br />
|-<br />
|0x0010xxxx || Kane & Lynch 2: Dog days, Need for Speed: World, R.U.S.E., Super Street Fighter IV<br />
|-<br />
|0x0020xxxx || Tom Clancy's H.A.W.X. 2<br />
|-<br />
|0x00c0xxxx || Battlefield: Bad Company 2, BFBC2Game_dx10<br />
|-<br />
|0x0100xxxx || AngleLib<br />
|-<br />
|0x0200xxxx || Ashes of the Singularity, F1 2015 DX12, Fable Legends, Sid Meier's Civilization VI<br />
|-<br />
|0x0400xxxx || Rise of the Tomb Raider<br />
|-<br />
|0x0800xxxx || Gears of War 4<br />
|-<br />
|0x2000xxxx || World of Tanks<br />
|-<br />
|0x8000xxxx || Need for Speed: Shift, Resident Evil 5<br />
|}<br />
<br />
<br />
<u> Default Value </u><br />
<br />
If not specified in a profile, the driver appears to use 0x23 as the default.<br />
<br />
=== StereoUseMatrix (0x70e34a78) ===<br />
<br />
- Able to automatically fix halo type issues in many games<br />
<br />
<u> Known Values </u><br />
{| class="wikitable"<br />
|0x00000000 || Disabled (only vertex output position will be adjusted by the driver)<br />
|-<br />
|0x00000001 || Enabled (other texcoord outputs based on the position will be adjusted by the driver)<br />
|-<br />
|0x1945B570 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
=== StereoFlagsDX10 (0x702442fc) ===<br />
<br />
- Able to resolve mono depth buffer issues in DirectX 11 games, such as Far Cry 4 and Ryse: Son of Rome.<br />
<br />
<u> Bit Definitions </u><br />
<br />
{| class="wikitable"<br />
|0x00000008 || Allows the reverse stereo blit (e.g. stereo2mono and the SBS/TB output modes of 3DMigoto) to work in SLI<br />
|-<br />
|0x00000020 || Negates the separation value passed to 3DMigoto effectively breaking/inverting any fix.<br />
|-<br />
|0x00001000 || Believed to force graphics shaders to run in both eyes regardless of the bound render target heuristic (alternative fix: use 3DMigoto to bind a dummy render or depth target to the broken shaders)<br />
|-<br />
|0x00004000 || STEREO_COMPUTE_ENABLE - enables running compute shaders once for each eye. Fixes mono depth buffer issue in Far Cry 4 (SLI users can alternatively resolve this with custom SLI compatibility bits), Witcher 3, and other games.<br />
|-<br />
|0x00008000 || STEREO_COMPUTE_SAME_RESOURCES_AS_GRAPHICS - "stereorize the same resources as for graphics (do not mark all UAVs as stereorizable)". WARNING: Using this value will prevent StructuredBuffer resources from being stereoised - prefer using 3DMigoto 1.2.70's fuzzy texture override matching.<br />
|}<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
|0x00000001 || Far Cry 2 (DX10 version)<br />
|-<br />
|0x00000004 || Crysis, Civilisation V<br />
|-<br />
|0x00000008 || 3DMark Vantage<br />
|-<br />
|0x000000E0 || Resident Evil 5<br />
|-<br />
|0x00000200 || Crysis 3, Battlefield 3<br />
|-<br />
|0x00000400 || Batman: Arkham City, Metro 2033<br />
|-<br />
|0x00001000 || Passion Leads Army Benchmark<br />
|-<br />
|0x00002000 || Titanfall<br />
|-<br />
|0x00002004 || Crysis Warhead<br />
|-<br />
|0x00004000 || Max Payne 3, Far Cry 4 (352.86+), The Witcher 3, Batman: Arkham Knight, The Park<br />
|-<br />
|0x00034000 || Metro: Last Light<br />
|-<br />
|0x1C22FE24 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
<u>Observations</u><br />
<br />
Kaimasta found that 0x00005000 fixed GameWorks effects in The Surge (SLI?). That will be stereo compute shaders + something else:<br />
<br />
https://forums.geforce.com/default/topic/1010253/3d-vision/the-surge-3d-vision-fix/post/5214378/#5214378<br />
<br />
Kaimasta noted some performance differences in Mass Effect: Andromeda with differing flags. My reading of his results is that STEREO_COMPUTE_SAME_RESOURCES_AS_GRAPHICS regains some (up to 5fps) of the performance lost with STEREO_COMPUTE_ENABLE on single GPU (which makes sense, since some compute shaders will then only be run once), and whatever 0x00001000 is has an additional performance cost of up to 3fps:<br />
<br />
https://forums.geforce.com/default/topic/998781/3d-vision/mass-effect-andromeda-3d-vision-fix-3d-vision-partial-fix-released-/post/5216274/#5216274<br />
<br />
DarkStarSword performed some detailed analysis on how this setting affects our ability to stereoise buffers and structured buffers:<br />
<br />
https://forums.geforce.com/default/topic/1029242/3d-vision/mass-effect-andromeda-3d-vision-fix-placeholder-/post/5274436/#5274436<br />
<br />
=== StereoCutoff (0x709a1ddf / 0x704fcf5c / 0x7053569a) ===<br />
<br />
Present in almost all Stereo profiles, but meaning unknown. My complete guess is that it may be related to driver heuristics to decide when the stereo correction formula is applied (e.g. for UI elements)?<br />
<br />
<u> Possible Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000000 || Unknown<br />
|-<br />
| 0x00000001 || Default<br />
|-<br />
| 0x00000002 || Use StereoCutoffDepthNear<br />
|-<br />
| 0x00000004 || Use StereoCutoffDepthFar<br />
|-<br />
| 0x00000008 || Unknown<br />
|}<br />
<br />
Other values are invalid.<br />
<br />
<u> Observations </u><br />
<br />
- Setting this to 0x00000000 broke shadows in Miasmata<br />
<br />
<u> Observations from D-Man11 (see [https://forums.geforce.com/default/topic/801771/3d-vision/tomb-raider-triology/post/4785703/#4785703 this post]) </u><br />
<br />
Note: the values below have been edited from the original post to use the setting names and their decrypted values.<br />
<br />
Interesting thing is, if you apply the TR: Underworld profile, the UI text doesn't split, just the background.<br />
<br />
Messing around with Legend, I found that StereoCutoffDepthNear = 25.0 and Setting StereoCutoff = 0x00000002 were the responsible flags from the Anniversary profile to stop the UI from splitting. Either by itself would not do anything.<br />
<br />
If I just added them to the existing Legend profile, it wouldn't work, something was stopping it. (DarkStarSword's note - this may have been because they were encrypted. This experiment should be repeated)<br />
<br />
If I deleted everything from the Legend profile, excluding StereoProfile = 0x00000001 (which is needed, if you remove it, the profile defaults to generic) and added the 2 flags from Anniversary, the UI would not split.<br />
<br />
StereoCutoffDepthNear = 0x41c80000 (25.0) // is exclusive to TR: Anniversary<br />
StereoCutoff = 0x00000002 // is found in 26 other profiles<br />
StereoProfile = 0x00000001 // is found in 2110 profiles<br />
<br />
So the above 3 settings need to be present and there must not be any current settings in the profile to block the effect.<br />
<br />
I did not bother to find the offending setting in the original Legend profile.<br />
<br />
=== StereoCutoffDepthNear (0x7050e011 / 0x704ef483 / 0x7031de06) ===<br />
<br />
Floating point value used when StereoCutoff is set to 2 to set a threshold depth to stop the UI splitting when it is rendered nearer than this value (someone confirm if that is entirely correct and if this can affect other things besides the UI).<br />
<br />
=== StereoCutoffDepthFar (0x70add220) ===<br />
<br />
Floating point value used when StereoCutoff is set to 1 to set a threshold depth to stop the UI splitting when it is rendered further away than this value (someone confirm if that is entirely correct and if this can affect other things besides the UI).<br />
<br />
=== GameSpecific0 (0x702244b7) ===<br />
<br />
For a DX9 game, this defines which constant register the driver injects the stereo settings in with x = -separation*convergence, y = separation (making the stereo correction formula pos.x += c255.x + c255.y * pos.w). Only vertex shaders that the driver modifies will have anything injected at all. The default is c255, and StereoProfile must be set for this setting to have any effect. Note that unlike the equivelent options for DX11 games, merely accessing this register will *not* neutralise the driver's stereo correction.<br />
<br />
More info: https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4786821/#4786821<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
|19 || MLB2K10<br />
|-<br />
|25 || NBA 2K9<br />
|-<br />
|28 || MLB 2K12, Pro Baseball 2K, NBA 2K12, NBA 2K13<br />
|-<br />
|198 || Alaska, Diablo III<br />
|-<br />
|236 || World Of Warcraft (but note that this profile may be outdated from the old DX9 version)<br />
|-<br />
|248 || Rogue Warrior<br />
|-<br />
|254 || Mafia II, Serious Sam II<br />
|}<br />
<br />
=== DX10VSCBNumber (0x70f8e408 / 0x70f64a32) ===<br />
For a DX10/11 game, this defines which constant buffer the driver uses to inject the stereo parameters into vertex shaders. The first float in the buffer is -separation*convergence, the second is separation, the third seems to be unused and the fourth indicates that 3D Vision is enabled. The default value is cb12. Note that in contrast to the equivelent DX9 option, merely declaring this constant buffer in a shader will disable the driver's built in stereo correction for that shader (for a HLSL shader the buffer must be accessed and the result used in a meaningful way otherwise the compiler will optimise out the declaration).<br />
<br />
More info: https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4786821/#4786821<br />
<br />
Note that constant buffer 14 is reserved for "internal use" and not normally accessible through HLSL (it is defined in shader model 4/5 and declaring it in assembly proves that it does exist and can be used for this purpose, but it is not clear if that might ever interfere with anything else).<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 6 || Metro 2033, Middle-Earth: Shadow of Mordor<br />
|-<br />
| 8 || Assassin's Creed, Fallout 4, Just Cause 3<br />
|-<br />
| 9 || The Witcher 3<br />
|-<br />
| 13 || Mirror's Edge: Catalyst<br />
|-<br />
| 14 || Assassin's Creed: Syndicate, Assassin's Creed: Unity, Dark Souls III, Dead Rising 4, F1 2015 DX12, Grand Theft Auto V, Homefront, Homefront(HOMEFRONT_DX10.exe), Homefront: The Revolution, Rise of the Tomb Raider<br />
|}<br />
<br />
=== DX10DSCBNumber (0x70092d4a) ===<br />
As above, but for tessellation domain shaders.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 8 || Fallout 4, Just Cause 3, Middle-Earth: Shadow of Mordor<br />
|-<br />
| 9 || The Witcher 3<br />
|-<br />
| 13 || Mirror's Edge: Catalyst<br />
|-<br />
| 14 || Assassin's Creed: Syndicate, Assassin's Creed: Unity, Dark Souls III, Dead Rising 4, F1 2015 DX12, Homefront: The Revolution, Rise of the Tomb Raider<br />
|}<br />
<br />
=== StereoMiscFlags (0x70ccb5f0) ===<br />
<u> Bit Definitions </u><br />
{| class="wikitable"<br />
|0x00000001 || Reverses eyes (does not apply to shader fixes). Can be used along with StereoFlagsDX10 (0x702442fc) = 0x00000020 which reverses shader fixes.<br />
|-<br />
|0x00000400 || Disables 3D Vision Direct mode, alternate to setting automatic_mode=1 that does not require our nvapi wrapper. Use for CryEngine games.<br />
<br />
|}<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000006 || PixEVRComponentTest<br />
|-<br />
| 0x00000008 || Assassin's Creed: Unity, Diablo III<br />
|-<br />
| 0x00000010 || Depth Hunter, Elder Scrolls V: Skyrim, End of Nations, Strike Suit Zero, The Walking Dead 2, The Walking Dead<br />
|-<br />
| 0x00000020 || Star Trek<br />
|-<br />
| 0x00000080 || Stereoscopic Player<br />
|-<br />
| 0x00000086 || Cyberlink PowerDVD10, VFTV<br />
|-<br />
| 0x00000100 || Biohazard 5, Devil May Cry 4(DX9), Lost Planet 2, Resident Evil 5<br />
|-<br />
| 0x00000400 || Homefront: The Revolution, Kingdom Come: Deliverance<br />
|-<br />
| 0x00000c06 || Cyberlink PowerDVD<br />
|-<br />
| 0x00000c86 || Cyberlink PowerDVD9<br />
|}<br />
<br />
== More Settings ==<br />
<br />
=== StereoConvergence (0x708db8c5 / 0x7077bace / 0x7084807e) ===<br />
Stores the convergence value of a profile as a floating point value.<br />
<br />
Default Value: 4.0<br />
<br />
=== Comments (0x704d456e) - text ===<br />
Stores the comments displayed in the green text by the driver.<br />
<br />
<br />
=== Developer_Issues (0x704f5928) - text ===<br />
Alternate setting for the comments displayed in the green text by the driver.<br />
<br />
<br />
=== StereoMemoEnabled (0x707f4b45) ===<br />
{| class="wikitable"<br />
| 0x00000000 || Green text disabled<br />
|-<br />
| 0x00000001 || Green text enabled<br />
|}<br />
<br />
<br />
=== Compat (0x7051e5f5) - text ===<br />
<br />
Selects the 3D Vision rating in the green text:<br />
<br />
"0": "3D Vision Ready"<br />
<br />
"1": "Excellent"<br />
<br />
"2": "Good"<br />
<br />
"3": "Fair"<br />
<br />
"4": "Not Recommended"<br />
<br />
"5": "Not Recommended"<br />
<br />
Other observed values: "-1", "101", "102"<br />
<br />
Default value? (crashes): "1000"<br />
<br />
=== PF_Issues (0x704cde5a) - text ===<br />
Comma separated list of letters corresponding to the following issues listed in the green text:<br />
<br />
A: "Incorrect 3D object placement"<br />
<br />
B: "Text/Objects are small and difficult to use"<br />
<br />
C: "Objects clipped at sides of monitor"<br />
<br />
D: "Incorrect clipping of subviews"<br />
<br />
E: "Mixed 2D and 3D objects in Pop-up or HUD"<br />
<br />
F: "Gunsight or Pointer is 2D object"<br />
<br />
G: "Issues with setup screens with stereo on"<br />
<br />
H: "Text highlight for 3D objects is at incorrect depth"<br />
<br />
I: "Bright colors on dark background produce ghosting"<br />
<br />
J: "Excessive use of 2D makes stereo look flat"<br />
<br />
K: Nothing (any more?), but a lot of profiles still mention this<br />
<br />
=== StereoDefaultOn (0x70ab30a7) ===<br />
Defines whether stereo is enabled automatically when the game is launched, or must be manually enabled with Ctrl+T. Useful to set to 0 if having stereo enabled when launching the game breaks something but works when enabled later.<br />
<br />
=== FrustumAdjustMode (0x70a1411a / 0x70ed1da7 / 0x70f475a0) ===<br />
Frustum adjust mode normally adjusted with Ctrl+F11<br />
<br />
{| class="wikitable"<br />
| 0 || No adjustment<br />
|-<br />
| 1 || Stretch<br />
|-<br />
| 2 || Crop<br />
|}<br />
<br />
<br />
== Compatibility Mode Settings ==<br />
<br />
Helifax created a guide with more information about these settings: [https://forums.geforce.com/default/topic/791450/3d-vision/guide-how-to-enable-and-tweak-3d-compatibility-mode-in-any-dx11-game/ Guide: How to Enable and TWEAK 3D Compatibility Mode in any DX11 Game]<br />
<br />
=== 2DDHUDSettings (0x709adada) ===<br />
Controls the compatibility mode settings - overall 3D strength, heuristics to pin the HUD at screen depth, rating.<br />
<br />
Bizarrely, enabling compatibility mode in a profile via this setting (can still be disabled via Disable2DD) allows the reverse stereo blit to work in SLI, but this is probably better off being done with StereoFlagsDX10.<br />
<br />
<u> Observations </u><br />
<br />
- Deleting this setting from the Far Cry Primal profile breaks a lot of geometry (becomes 2D) even outside of CM. Based on the reverse stereo blit observation I would hazard a guess that this setting implies various other settings.<br />
<br />
<u> Observations from Losti </u><br />
<br />
The below post has been decrypted. The original post is [https://forums.geforce.com/default/topic/791450/3d-vision/guide-how-to-enable-and-tweak-3d-compatibility-mode-in-any-dx11-game/post/4377990/#4377990 here].<br />
<br />
So i have did some investigations with the nvidia used values and i discovered that:<br />
<br />
<u>'''(For Dragon Age: Inquisition)'''</u><br />
<br />
-----------------------<br />
{| class=wikitable<br />
| 0x10000002 || high depth UI and world<br />
|-<br />
| 0x1000000a || high depth UI and world<br />
|-<br />
| 0x1000001a || high depth UI and world<br />
|-<br />
| 0x20000002 || high depth UI and world<br />
|-<br />
| 0x2000000a || high depth UI and world<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x10000015 || no Depth, UI only right eye<br />
|-<br />
| 0x10000102 || low depth UI and world<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x20000006 || UI @ screen depth world high depth<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x51000002 || Game will not have CM<br />
|-<br />
| 0x11000006 || Game will not have CM<br />
|-<br />
| 0x11000002 || Game will not have CM<br />
|-<br />
| 0x41000002 || Game will not have CM<br />
|-<br />
| 0x21000006 || Game will not have CM<br />
|-<br />
| 0x21000002 || Game will not have CM<br />
|}<br />
<br />
own tests:<br />
{| class=wikitable<br />
| 0x20000006 || UI @ screen dempth world high deph<br />
|-<br />
| 0x20000007 || high depth UI and world<br />
|-<br />
| 0x10000036 || UI @ screen depth world high deph<br />
|-<br />
| 0x10000106 || UI @ screen depth world very-LOW deph || EXCELLENT RATING-TEXT<br />
|-<br />
| 0x20000106 || UI @ screen depth world very-LOW deph || GOOD RATING-TEXT<br />
|-<br />
| 0x20000306 || application unknown, no CM<br />
|-<br />
| 0x10000306 || very low Depth, UI only right eye<br />
|-<br />
| 0x10000606 || UI @ screen depth world high deph<br />
|-<br />
| 0x10000706 || very low Depth, UI only right eye<br />
|-<br />
| 0x10000007 || UI @ screen depth world high deph, UI only rigth eye<br />
|-<br />
| 0x10000001 || all is 2D<br />
|-<br />
| 0x10000000 || all is 2D, ALT+TAB=crash<br />
|-<br />
| 0x10000003 || crash<br />
|-<br />
| 0x1000000d || all is 2D, UI only right eye<br />
|-<br />
| 0x1000000c || all is 2D, UI only right eye<br />
|}<br />
<br />
<br />
i think the use of the numbers at the begining (0x20 and 0x10 is fot he GOD or EXCELLENT rating text display)<br />
<br />
'''006''' at the end will give me UI at screen-depth and a 3D world.<br />
<br />
'''002''' at the end will give me UI and a 3D world.<br />
<br />
=== 2DDConvergence (0x709adadb) ===<br />
As the name implies, this is the convergence setting when in compatibility mode.<br />
<br />
=== Disable2DD (0x709adadd) ===<br />
User setting to disable compatibility mode, usually set via hotkey.<br />
{| class=wikitable<br />
| 0x00000000 || Compatibility mode enabled (if supported)<br />
|-<br />
| 0x00000001 || Compatibility mode disabled via Ctrl+Alt+F11<br />
|}<br />
<br />
=== 2DD_Notes (0x709adadc) - text ===<br />
Notes displayed when compatibility mode is enabled<br />
<br />
<br />
== VR Direct Settings ==<br />
<br />
These settings have appeared in recent drivers and are believed to be related to VR Direct:<br />
<br />
=== StereoVRConvergenceBias (0x708db8c6) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00001185 || Batman: Arkham Origins<br />
|-<br />
| 0x0000130b || Devil May Cry 4<br />
|-<br />
| 0x00001a24 || Fable: The Lost Chapters<br />
|-<br />
| 0x00001cdd || Dirt 3<br />
|-<br />
| 0x00002e6b || Portal 2<br />
|-<br />
| 0x0000377c || Nvidia Stereo Test App<br />
|-<br />
| 0x00003c0f || Oil Rush<br />
|-<br />
| 0x0000849d || Serious Sam III<br />
|-<br />
| 0x0000a1a7 || Batman: Arkham City<br />
|-<br />
| 0x0000cd04 || Half-Life 2<br />
|}<br />
<br />
=== StereoVRRefreshRateOverride (0x708db8c8) ===<br />
=== StereoVRVsync (0x708db8c9) ===<br />
<br />
<br />
=== 0x709d3ad2 === <br />
Starting with driver branch R378, VR and 3D Vision are mutually exclusive, and 3D Vision is disabled when VR runtimes are detected.<br />
{| class=wikitable<br />
| 0x00000008 || disables mutual exclusion lock for VR runtimes and 3D Vision<br />
|}<br />
<br />
<br />
== Laser Sight Settings ==<br />
<br />
TsaebehT created a guide with more information about these settings: [https://forums.geforce.com/default/topic/813727/guide-correcting-off-centering-lasersight/ Guide: Correcting/Off-Centering LaserSight]<br />
<br />
<br />
=== LaserSightEnabled (0x7054837a) ===<br />
{| class="wikitable"<br />
| 0x00000000 || Laser sight disabled<br />
|-<br />
| 0x00000001 || Laser sight enabled<br />
|}<br />
<br />
<br />
=== LaserXAdjust (0x7057e831) ===<br />
Horizontal adjustment encoded as a hex float between 0.0 (left) and 2.0 (right). Default: 1.0 (center)<br />
<br />
<br />
=== LaserYAdjust (0x70225308) ===<br />
Horizontal adjustment encoded as a hex float between 0.0 (top) and 2.0 (bottom). Default: 1.0 (center)<br />
<br />
<br />
=== LaserZAdjust (0x7014fca2) ===<br />
{| class="wikitable"<br />
| 0x3f800000 || Enables dynamic laser sight depth<br />
|-<br />
| other || Laser sight is either at screen depth or infinity<br />
|}<br />
<br />
=== LaserSightProperty (0x7032243a) ===<br />
Governs the laser sight opacity<br />
<br />
<br />
=== LaserSightTrigger (0x70031b88) ===<br />
<u> Known Values </u><br />
{| class="wikitable"<br />
| 0x00000002 || Gears of War<br />
|}<br />
<br />
=== InGameLaserSight (0x7064f0c2 / 0x70dd2585 / 0x70e7adad) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000000 || Call of Duty: Modern Warfare 2, Call of Duty: Modern Warfare 3, Call of Duty: World at War, Crysis Warhead, Crysis, Divinity 2, Frontlines: Fuel of War, Medal of Honor: Airborne, Stranglehold, Tom Clancy's Rainbow Six: Vegas 2<br />
|-<br />
| 0x00000001 || BlackSite: Area 51, Delta Force: Black Hawk Down, Gears of War, Hellgate: London DX10, Hellgate: London, Kane & Lynch: Dead man, Postal 3, Unreal Tournament 2004<br />
|-<br />
| 0x00000005 || Code of Honor 2, Default.Archcfg, Shell Shock 2<br />
|-<br />
| 0x00000009 || Battlestrike/Armed Forces Series, Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Ghosts, Left 4 Dead 2, Left 4 Dead, Medal of Honor, S.T.A.L.K.E.R.: Call of Pripyat, S.T.A.L.K.E.R.: Shadow of Chernobyl, Terrorist Takedown 2, TimeShift, Unreal Tournament III<br />
|-<br />
| 0x0000000b || F.E.A.R. Perseus Mandate<br />
|-<br />
| 0x0000000d || Borderlands, Half-Life 2<br />
|-<br />
| 0x80000009 || TitanFall<br />
|}<br />
<br />
=== InGameLaserSightDX9States (0x706139ad) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00023322 || Half-Life 2, Left 4 Dead, Left 4 Dead 2<br />
|}<br />
<br />
=== LaserSight (0x7058b6e1 / 0x7031a2e7 / 0x7045b752) ===<br />
Valid values are 0 and 1<br />
<br />
=== LaserSightFile (0x707ac50d) ===<br />
<br />
<br />
=== LaserSightIndex (0x70da83c6) ===<br />
<br />
<br />
=== StereoLaserSightMaxCount (0x70bc864d) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000004 || Unreal Tournament III<br />
|-<br />
| 0x00000006 || Half-Life 2<br />
|-<br />
| 0x00000008 || Call of Duty: Ghosts, Call of Duty: World at War, UberSoldier<br />
|-<br />
| 0x0000000a || F.E.A.R. Perseus Mandate, Left 4 Dead, Left 4 Dead 2<br />
|-<br />
| 0x000000c8 || Tom Clancy's Rainbow Six: Vegas 2<br />
|}<br />
<br />
=== StereoLaserSightCount (0x70077042) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000002 || Gears of War<br />
|-<br />
| 0x00000004 || Unreal Tournament III<br />
|-<br />
| 0x00000008 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Ghosts, Call of Duty: Modern Warfare 3, Call of Duty: World at War, Medal of Honor<br />
|}<br />
<br />
=== Laser Sight Key Bindings ===<br />
==== ToggleLaserSight (0x70b7bd1f) ====<br />
Only works when set via the Registry and not via a Profile.<br />
<br />
<br />
==== LaserAdjustXMinus (0x7048b7dc) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustXPlus (0x70d8bae6) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustYMinus (0x70fb9e1e) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustYPlus (0x7024eda4) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
== Misc Key Bindings ==<br />
<br />
These are believed to be key bindings due to their names. These will override the global key bindings in the registry. Some of these settings may not work at all in recent drivers.<br />
<br />
There is a good guide for how these are encoded here: [http://3dvision-blog.com/3053-modifying-all-3d-vision-control-key-combinations-as-you-need/ Modifying All 3D Vision Control Key Combinations as You Need]<br />
<br />
=== StereoToggle (0x70d76b8b) ===<br />
Toggles Stereo on and off (Default: Ctrl+T)<br />
<br />
=== StereoSeparationAdjustLess (0x705d1e02) ===<br />
Reduce separation (Default: Ctrl+F4)<br />
<br />
=== StereoSeparationAdjustMore (0x70ab8d32) ===<br />
Increase separation (Default: Ctrl+F5)<br />
<br />
=== StereoConvergenceAdjustLess (0x70d4add7) ===<br />
Reduce convergence (Default: Ctrl+F5)<br />
<br />
=== StereoConvergenceAdjustMore (0x701ed576) ===<br />
Increase Convergence (Default: Ctrl+F6)<br />
<br />
=== SaveStereoImage (0x70121853) ===<br />
Save a stereo screenshort (Default: Alt+F1)<br />
<br />
=== WriteConfig (0x700498b3) ===<br />
Save the current convergence to a user profile (Default: Ctrl+F7)<br />
<br />
=== DeleteConfig (0x70c73ba2) ===<br />
Delete the game's user profile (Default: Alt+F7)<br />
<br />
=== GammaAdjustMore (0x703f4521) ===<br />
=== GammaAdjustLess (0x70e8420c) ===<br />
<br />
=== StereoVerticalAdjustMore (0x7087fe61) ===<br />
=== StereoVerticalAdjustLess (0x703acfc6) ===<br />
=== StereoHorizontalAdjustMore (0x70062f07) ===<br />
=== StereoHorizontalAdjustLess (0x70871a39) ===<br />
<br />
=== ToggleAutoConvergence (0x70085de3) ===<br />
NOTE: AFAIK this was never implemented<br />
<br />
=== ToggleAutoConvergenceRestore (0x703bc51e) ===<br />
NOTE: AFAIK this was never implemented<br />
<br />
=== RHWAtScreenMore (0x7066a22e) ===<br />
=== RHWAtScreenLess (0x709139ad) ===<br />
=== RHWLessAtScreenMore (0x704e4bca) ===<br />
=== RHWLessAtScreenLess (0x70b378a1) ===<br />
<br />
=== CutoffNearDepthLess (0x70d1bdb5) ===<br />
=== CutoffNearDepthMore (0x7020c991) ===<br />
=== CutoffFarDepthLess (0x704c9a46) ===<br />
=== CutoffFarDepthMore (0x70fbc04d) ===<br />
=== CutoffStepLess (0x704b45c7) ===<br />
=== CutoffStepMore (0x700f2971) ===<br />
<br />
=== GlassesDelayPlus (0x701fc5b4) ===<br />
NOTE: Believed to no longer work in recent drivers<br />
<br />
=== GlassesDelayMinus (0x70b8a743) ===<br />
NOTE: Believed to no longer work in recent drivers<br />
<br />
<br />
== Unidentified Settings ==<br />
<br />
These setting names were found in the driver, but their purpose or whether they are even functional is unknown:<br />
<br />
=== Time (0x70ad05c8) ===<br />
Only present in a handful of profiles and appears to be a UNIX Time value:<br />
<br />
{| class="wikitable"<br />
| 0x53979bf4 || 2014-06-10 23:59:48 GMT || Murdered: Soul Suspect<br />
|-<br />
| 0x5398a3b4 || 2014-06-11 18:45:08 GMT || Enemy Front<br />
|-<br />
| 0x5398cbe8 || 2014-06-11 21:36:40 GMT || Heldric - The legend of the shoemaker<br />
|-<br />
| 0x5398d296 || 2014-06-11 22:05:10 GMT || Eterium<br />
|-<br />
| 0x5398df13 || 2014-06-11 22:58:27 GMT || Blackguards<br />
|-<br />
| 0x539a472e || 2014-06-13 0:34:54 GMT || Port Royale 3<br />
|-<br />
| 0x539f8bfb || 2014-06-17 0:29:47 GMT || Sniper Elite 3<br />
|-<br />
| 0x53ab4828 || 2014-06-25 22:07:36 GMT || GRID Autosport<br />
|}<br />
<br />
=== RunTimeName (0x701a8be4) - text ===<br />
Observed values:<br />
<br />
-007, ACS, armada, bzone, Client, CLIENT, Demo, Engine, FFORCE, game, Game, GameClient, heroes, launcher, LithTech, main, mainapp, NoName, PG3, PNOCOMP, Pool, Prism3d, program, rally, sw, SW, tm, UDK, wcdemo, WRUN,<br />
<br />
=== EnableConsumerStereoSupport (0x70cb9168) ===<br />
=== StereoViewer (0x704915a1) ===<br />
=== StereoViewerType (0x708f9ef7) ===<br />
=== ShowAllViewerTypes (0x708e5cb4) ===<br />
=== StereoAdjustEnable (0x70538ab1) ===<br />
=== StereoDisableTnL (0x70633bd9) ===<br />
=== StereoTransformationType (0x70c27e3c) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || ghost<br />
|}<br />
<br />
=== StereoSeparation (0x70933c00) ===<br />
This does not seem to have any affect on the separation in other games.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 2 || AngleLib<br />
|}<br />
<br />
=== StereoSeparationStep (0x7082555b) ===<br />
=== StereoConvergenceMultiplier (0x70efbb5b) ===<br />
Default value: 5.0<br />
<br />
=== RHW2DDetectionMin (0x7029432b) ===<br />
=== RHWGreaterAtScreen (0x702c861a) ===<br />
Floating point value<br />
<br />
=== RHWEqualAtScreen (0x70ab2e09) ===<br />
'''NOT''' a floating point value.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || V-Rally 2, h2wof<br />
|}<br />
<br />
=== RHWLessAtScreen (0x70381472) ===<br />
Floating point value<br />
<br />
=== AutoConvergence (0x702a0ab2) ===<br />
Looking over the list of games with this setting I suspect this is a very old feature that well and truly pre-dates DX9 and probably won't work in any modern game.<br />
<br />
<u> Known Values </u><br />
<br />
A considerable number of profiles have this set to 0, which may be meaningless if 0 is the default, but that would be unusual to have so many profiles specify the default.<br />
<br />
{| class="wikitable"<br />
| 0 || "Alien vs Predator 2", "Archlords", "Arcsoft Media Converter", "Armies of Exigo", "Army Men RTS", "BackyardBaseball2005", "Battlefield 1942", "Battlefield 2", "Battlefield Vietnam", "Black and White 2", "Black and White 2: Battle of the Gods", "Boarder Zone", "Colin McRae Rally 5", "Comanche 4", "Combat Flight Simulator 3", "Combat Mission", "Cricket 2005", "Dark Messiah of Might and Magic", "Delta Force 3: Land Warrior(Dflw.exe)", "Delta Force: Xtreme", "Diplomacy", "Driver 3", "Elder Scrolls 3: Morrowind", "Evolva", "Expert Pool", "ExtConverter", "F.E.A.R.", "FIFA Soccer 2004(fifa2004.exe)", "FIFA Soccer 2005", "FIFA Soccer 2006", "Fable: The Lost Chapters", "Far Cry", "Firestarter", "Freelancer", "GUN", "Ghost Recon: Advanced Warfighter(Demo)", "Godfather: The game", "Google Chrome", "Gothic 2", "Ground Control 2", "Gun Metal", "Harry Potter And The Goblet Of Fire", "Harry Potter Quidditch World Cup", "Harry Potter and the Prizoner of Azkaban", "Hidden & Dangerous 2", "High Heat Major League Baseball 2004", "Hitman: Blood Money", "Impossible Creatures", "Independence War 2 - Edge of Chaos", "Jetfighter 2015", "Joint Operations: Typhoon Rising", "Knight Shift", "Kohan 2", "LEGO Star Wars", "LOTR bat2", "Lock On", "Lord of the Rings: Return of the King", "Lords of the Realm 3", "MVP Baseball 2003", "MVP Baseball 2004", "MVP Baseball 2005", "Mafia", "Manhunt", "Massive Assault", "Max Payne 2", "MechWarrior IV Mercenaries", "Men of Valor:Vietnam", "Microsoft Flight Simulator 2004", "Microsoft Train Simulator", "Midnight Club II", "Motocross Madness 2", "Mount & Blade: With Fire & Sword", "Movavi Video Converter", "Myst 4", "NASCAR SimRacing", "NBA Live 2004", "NBA Live 2005", "NBA Live 2006", "NHL 2003(nhl2003.exe)", "NHL 2005", "NHL 2006", "Nexus: The Jupiter Incident (DX9 version)", "No One Lives Forever 2", "No man's land", "Painkiller", "Paradise Cracked", "Pariah", "Perimeter", "Psychonauts", "Rainbow Six 3: Raven Shield", "Red Faction II", "Republic", "Rise and Fall: Civilizations at War", "RollerCoaster Tycoon 3", "Rome - Total War", "Roo Goo", "Roxio Video Converter", "Rugby2004", "SHGame", "Sid Meier's Pirates!", "Silent Hunter III", "Sims 2 - University", "Sims 2", "Sims 2: Nightlife", "Space Station Manager", "Spellforce 2", "Spellforce", "Splinter Cell: Chaos Theory", "Splinter Cell: Pandora Tomorrow", "Squad Assault - West Front", "Star Wars: Battlefront (2004)", "Star Wars: Battlefront II", "Star Wars: Republic Commando", "SupremeRuler", "Syberia 2", "Teenage Mutant Ninja Turtles", "Temple of Elemental Evil", "Terminator 3: War of the Machines", "The Bard's Tale", "The Incredibles", "The Simpsons: Hit and Run", "Tiger Woods PGA Tour 05", "Tiger Woods PGA Tour 06", "Tony Hawk's Underground", "Trackmania - Sunrise", "Unreal 2", "Vampire The Masquerade - Bloodlines", "WARHAMMER 40k Fire Warrior", "Warcraft III", "Warhammer 40000: Dawn of War - Winter Assault", "Warhammer 40000: Dawn of War", "Warrior Kings - Battles", "Webhead", "Winning Eleven 7", "X-Men Legends II: Rise of Apocolypse", "X2: Wolverine's Revenge", "ffvt3rd", "grand theft auto_sa"<br />
|-<br />
| 1 || "Apache: Air Assault", "Archlords", "Arcsoft Media Converter", "BlackSite: Area 51", "Championship BASS", "Combat Mission", "Crusaders of Might and Magic", "Dagoth Moor Zoological Gardens", "Darkstone", "Descent FreeSpace 2", "End of Nations", "European Air War", "Exodus from the Earth", "Expert Pool", "ExtConverter", "Extreme Biker", "Flesh Feast", "G-Police", "Grandia2", "Hot Chix 'n' Gear Stix", "Incomming", "Interstate '82", "Legends of the Seers", "Luftwaffe Commander", "Madden NFL Games", "Michelle Kwan Figure Skating(kwandemo.exe)", "Microsoft Baseball 2001", "Mount & Blade: With Fire & Sword", "Movavi Video Converter", "NASCAR 2000(NASCAR 2000 Demo.exe)", "NASCAR 2000(NASCAR 2000.exe)", "NASCAR Heat", "NASCAR Legends", "Omikron: The Nomad Soul(Nomad.exe)", "Pong", "Professional Bull Rider", "Renegade Racers(rrDemo.exe)", "Rocketsled", "Roo Goo", "Roxio Video Converter", "Test Drive 6", "Topspin", "True Crime: Streets of LA", "Up", "Wartorn"<br />
|}<br />
<br />
=== AutoConvergenceAdjustPace (0x70bf3c6b) ===<br />
Floating point value, which is almost always set to 0.05 (except for Combat Mission, where it is set to 1.0). Note that this is present in a number of profiles that lack AutoConvergence.<br />
<br />
=== StereoToggleMode (0x70d76b8c) ===<br />
=== StereoSuggestSettings (0x706315af) ===<br />
=== StereoUnsuggestSettings (0x7017861c) ===<br />
=== FavorSZ (0x705faed7) ===<br />
=== StereoPointer (0x70364596) ===<br />
Only seen in "Sims 2 - University" and "Sims 2: Nightlife", where this is set to 1. Note that this is not present in the base Sims 2 profile or any of the other Sims 2 profiles.<br />
<br />
=== MonitorSize (0x7086ebe9) ===<br />
=== MaxMonitorSize (0x7032022c) ===<br />
=== MaxVertexCount (0x709e4a94) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000002 || Half-Life 2<br />
|-<br />
| 0x00010000 || Arabian Nights<br />
|}<br />
<br />
=== PartialClearMode (0x709794cc) ===<br />
=== StereoRefreshDefaultOn (0x702ba385) ===<br />
=== MixedTnL (0x70bd11e0) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark01", "3DMark03", "3DMark05", "James Bond Nightfire", "Need for Speed Hot Pursuit 2(Nfshp2.exe)", "Need for Speed Hot Pursuit 2(NFSHP2Demo.exe)"<br />
|}<br />
<br />
=== StereoGamma (0x70c8b5d1) ===<br />
=== LineCodeColor (0x70dc4a12) ===<br />
=== LeftAnaglyphFilter (0x70d51cd1) ===<br />
=== RightAnaglyphFilter (0x70f4a930) ===<br />
=== InterleavePattern0 (0x70b1c8cc) ===<br />
=== InterleavePattern1 (0x7091a772) ===<br />
=== StereoForceVSync (0x70aae185) ===<br />
=== StereoColorKey (0x70e5773b) ===<br />
Only present in the "NV Pinball" profile, where it is set to 0x00010101<br />
<br />
=== ZDirection (0x70b17872) ===<br />
=== StereoCompatibility (0x70a2000e) ===<br />
=== LeftColorFilter0 (0x70ac6888) ===<br />
=== LeftColorFilter1 (0x7090b6ca) ===<br />
=== RightColorFilter0 (0x70b9a2f7) ===<br />
=== RightColorFilter1 (0x70aca0cc) ===<br />
=== SharpVPI (0x706e0041) ===<br />
=== StereoMode (0x701baa09) ===<br />
=== Watchdog (0x700a5654) ===<br />
=== StereoOSDEnable (0x70f455aa) ===<br />
=== StereoOrthoEnable (0x703564f6) ===<br />
An Orthographic projection does not ordinarily involve a perspective divide, and therefore it stands to reason that these games may use a slightly different stereo correction formula.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Halo", "Midnight Club II(mc2_demo.exe)", "Port Royale", "Sims 2 - University", "Sims 2", "Sims 2: Nightlife"<br />
|}<br />
<br />
=== StereoNotSupported (0x709aa171) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark Ice Storm", "3DMark", "3DMark11", "3DMark14", "All Play-On-line Games", "Evolve", "Final Fantasy XIV: A Realm Reborn", "NVIDIA NVFBC Applications", "NVKeystone", "Resident Evil: Revelations 2 / Biohazard Revelations 2", "Ryse: Son of Rome", "Sid Meier's Civilization: Beyond Earth", "VRP", "Windows Live Mail", "Windows Live Photo Gallery", "Windows Movie Maker", "WLXPGSS"<br />
|}<br />
<br />
=== ModesetWarning (0x70969bb0) ===<br />
=== StereoFirstTime (0x70af6400) ===<br />
=== StereoRefreshRate (0x70ded3c0) ===<br />
=== GameConfigs (0x704a905a) ===<br />
=== CompareEyes (0x70729e58) ===<br />
=== CompareFrom (0x70efb726) ===<br />
=== StereoImageType (0x7097906c) ===<br />
=== SnapShotQuality (0x7004e7a6) ===<br />
=== NoLockSubstitute (0x7005ad16) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark03", "3DMark05", "Bumper to Bumper", "S.T.A.L.K.E.R.: Shadow of Chernobyl", "Star Wraith 3: Shadows of Orion", "World Dance"<br />
|}<br />
<br />
=== PushbufSubstituteSize (0x7054fbf8) ===<br />
=== DiscardHotkeys (0x70175566) ===<br />
=== StereoLCDPatternType (0x707cfb97) ===<br />
=== GlassesSwitchDelay (0x70057bb6) ===<br />
<br />
Valid values appear to be between 5 <= GlassesSwitchDelay < 95<br />
<br />
=== StartZBit (0x7044d7a6) ===<br />
=== DisableOnOutOfMemory (0x70c71508) ===<br />
=== StereoWindowedEnable (0x709b3484) ===<br />
=== AllowNonExclusiveStereo (0x702c7709) ===<br />
=== Rhwinf (0x706e1913 / 0x70cc286a / 0x70a3fee6) ===<br />
Floating point value set in 26 profiles with values ranging from 0.00003125 to 0.04<br />
<br />
RHW stands for Reciprocal of Homogeneous W, really just a fancy term for 1 / linear depth. inf is presumably short for infinite depth.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.00003125 || Gears of War<br />
|-<br />
| 0.000062500985 || Unreal Tournament III<br />
|-<br />
| 0.00006666667 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Modern Warfare 3, Damnation, F.E.A.R. Perseus Mandate, Frontlines: Fuel of War, Left 4 Dead 2, Left 4 Dead, Medal of Honor, Mirror's Edge, TimeShift, Tom Clancy's Rainbow Six: Vegas 2<br />
|-<br />
| 0.0001 || F.E.A.R. 2: Project Origin, Gears of War(wargame-g4wlive_DX10.exe), Half-Life 2, Mass Effect 2, Mass Effect, Shell Shock 2, Stranglehold<br />
|-<br />
| 0.00025 || The haunted Hells Reach<br />
|-<br />
| 0.00066666666 || Q.U.B.E.<br />
|-<br />
| 0.01 || Kane & Lynch: Dead man, Serious Sam III<br />
|-<br />
| 0.04 || The Club<br />
|}<br />
<br />
=== Rhwscr (0x70a4995c / 0x7030b071 / 0x70b57ed1) ===<br />
Floating point value set in 29 profiles with values ranging from 0.05 to 1.0<br />
<br />
Presumably related to Rhwinf, and "scr" is likely short for screen depth.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.05 || The Club, Tom Clancy's Rainbow Six: Vegas 2, Unreal Tournament III<br />
|-<br />
| 0.06666667 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Modern Warfare 3, Gears of War, Medal of Honor, TimeShift<br />
|-<br />
| 0.1 || Damnation, F.E.A.R. 2: Project Origin, Frontlines: Fuel of War, Gears of War(wargame-g4wlive_DX10.exe), Half-Life 2, Mass Effect 2, Mass Effect, Mirror's Edge, Q.U.B.E., Shell Shock 2, Stranglehold, The haunted Hells Reach"<br />
|-<br />
| 0.11111111 || Left 4 Dead, Left 4 Dead 2<br />
|-<br />
| 0.125 || BlackSite: Area 51<br />
|-<br />
| 0.15 || TitanFall<br />
|-<br />
| 0.2 || Call of Duty: World at War, F.E.A.R. Perseus Mandate<br />
|-<br />
| 1.0 || Kane & Lynch: Dead man, Serious Sam III<br />
|}<br />
<br />
=== Zinf (0x70fc13ad) ===<br />
At a guess this is probably similar to Rhwinf, but uses the output Z coordinate of the vertex shader instead of the output W coordinate.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.0 || Call of Duty: Ghosts<br />
|}<br />
<br />
=== Zscr (0x707f0e69) ===<br />
At a guess this is probably similar to Rhwscr, but uses the output Z coordinate of the vertex shader instead of the output W coordinate. Presumably related to Zinf in the same way Rhwscr is related to Rhwinf.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1.0 || Call of Duty: Ghosts<br />
|}<br />
<br />
=== EnableCE (0x702b8c95) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Age of Empires III", "Age of Empires III - The War Chiefs", "Age of Empires III: The Asian Dynasties"<br />
|}<br />
<br />
=== MediaPlayer (0x70a8fc7f) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "BaoFeng / Storm Player", "Cyberlink PowerDVD", "Cyberlink PowerDVD10", "Cyberlink PowerDVD9", "Movie Studio Platinum 12", "PixEVRComponentTest", "Sony Media Gallery", "Sony Vegas Pro", "Stereoscopic Player", "VFTV", "Vegas Movie Studio HD Platinum 11", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoDX9 (0x70d10d2b) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "AZMD! Scorepocalypse", "Adam's Venture Episode 1", "Afterfall: InSanity", "Alan Wake's American Nightmare", "All Zombies Must Die", "Battlefield: Bad Company 2", "Borderlands 2", "Bullet Run", "Choplifter HD", "Counter-strike: Global Offensive", "Crysis 2", "Da Vinci Online", "Dear Esther", "Deus Ex: Human Revolution", "Dishonored", "DmC-Devil May Cry", "Duke Nukem Forever", "End of Nations", "Far Cry 2", "Gears of War", "Hawken", "Mars", "Painkiller Hell & Damnation", "Q.U.B.E.", "Quan Qiu Shi Ming(MarsGame.exe)", "Red Orchestra 2: Heroes of Stalingrad", "Risen 2: Dark Waters", "Section 8: Prejudice", "Spec Ops: The Line", "The Ball", "The Witcher 2: Assassins of Kings", "The haunted Hells Reach", "Tony Hawk's Pro Skater HD", "Tribes Ascend", "WARP", "War of the Roses", "World in Conflict", "XCOM: Enemy Unknown"<br />
|}<br />
<br />
=== StereoMsgVerticalOffset (0x70160ebf) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 16 || Assassin's Creed(DX9)<br />
|}<br />
<br />
=== StereoEasyZCheck (0x70b6d6ed) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Half-Life 2", "Kane & Lynch: Dead man", "Mass Effect 2", "Mass Effect", "Shell Shock 2", "Stranglehold", "The Club", "TimeShift", "Tom Clancy's Rainbow Six: Vegas 2"<br />
|}<br />
<br />
=== StereoStrictLSCheck (0x709bc378) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Half-Life 2", "Tom Clancy's Rainbow Six: Vegas 2"<br />
|}<br />
<br />
=== StereoDisableAsync (0x70de5533) ===<br />
=== EnablePartialStereoBlit (0x7096eced) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "BaoFeng / Storm Player", "Flash(Firefox)", "NVIDIA Stereoscopic 3D video player", "NVStWiz", "Sony Media Gallery", "Stereoscopic Player", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoNoDepthOverride (0x709dea62) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "NVIDIA Stereoscopic 3D video player", "Novlum Demes Editor", "NvStView", "Sony Media Gallery", "Stereoscopic Player", "Trine 3", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoShaderMatrixCheck (0x7044f8fb) ===<br />
=== StereoLogShaders (0x7052bdd0) ===<br />
=== StereoEpsilon (0x70e5a749) ===<br />
Floating point value seen in 46 profiles. Observed values: 0.00000088, 0.0000088, 0.000088<br />
<br />
=== DelayedStereoDesktop (0x7042eef1) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000001 || Half-Life 2, Tom Clancy's H.A.W.X.<br />
|-<br />
| 0x00140002 || Fallout 3<br />
|}<br />
<br />
=== StereoHiddenProfile (0x70e46f20) ===<br />
<u> Known Values </u><br />
<br />
A considerable number of profiles have this set to 0, which may be meaningless if 0 is the default, but that would be unusual to have so many profiles specify the default.<br />
<br />
{| class="wikitable"<br />
| 0 || "ACS", "armada", "bzone", "Client.exe", "Crysis", "Demo", "Dragon : MMORPG", "Freedom Force", "Game.exe", "GameClient.exe", "Google Chrome", "Hunting 4", "LithTech", "Madden NFL Games", "Microsoft Internet Explorer", "Mozilla FireFox - Plugin Container", "Mozilla Firefox", "Nations", "nfs", "NoName", "Novlum Demes Editor", "Panzer General 3 Scorched Earth(PG3.exe)", "Pencil Whipped", "Prince of Persia", "program", "rally", "S.T.A.L.K.E.R.: Clear Sky", "Safari Congo", "Ship Simulator 2006", "SW", "Ultimate 8 Ball", "WRUN"<br />
|- <br />
| 1 || "AngleLib", "engine", "heroes", "launcher", "UDK (Unreal Development Kit) based games"<br />
|}<br />
<br />
=== StereoLinkDll (0x70e46f2a) - text ===<br />
<br />
Appears to be a comma separated list of files to search for. At a guess, if this setting is present these files either must or must not exist for stereo to engage.<br />
<br />
=== EnableStereoCursor (0x70e46f2b) ===<br />
=== CreateStereoDTAfterPresentNum (0x70a7fc7f) ===<br />
To confirm, but presumably delays initialising 3D Vision until the game has drawn this number of frames, possibly to work around crashes on launch or other issues caused by 3D Vision being enabled when the game is launched, but works if enabled later.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 3 || Cyberlink PowerDVD9<br />
|-<br />
| 50 || Call of Duty Online<br />
|}<br />
<br />
=== Date_Rel (0x705fafec) - text ===<br />
May contain the release date in the form YYYY-MM-DD 00:00:00<br />
<br />
=== Game (0x70c8d48e) - text ===<br />
=== Style (0x709cc5e0) - text ===<br />
<br />
Contains the game's genre, such as "Action", etc.<br />
<br />
=== Publisher (0x706c7030) - text ===<br />
<br />
Lists the game's publisher.<br />
<br />
=== Developer (0x703c4026) - text ===<br />
<br />
Lists the game's developer.<br />
<br />
=== API (0x70b5603f) - text ===<br />
Usually contains "D3D", other observed values include "d3d", "D3d", "D3D_", "OGL_" and "S/W"<br />
<br />
=== Value (0x7049c7ec) ===<br />
Observed values: "0", "0.0", "1", "1.0", "2", "2.0", "3", "3.0", "4", "4.0", "5", "5.0", "101.0", "102.0"<br />
<br />
=== P1SH0 (0x70998683) - text ===<br />
=== V1SH0 (0x70e6a3cf) - text ===<br />
=== PSH0 (0x7046516e) - text ===<br />
=== VSH0 (0x708b7af8) - text ===<br />
At a guess this might stand for "Vertex Shader Hash 0" and define some kind of override for a specific vertex shader, perhaps to force the stereo correction on or off for a particular shader.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| "1162e513 0 1" || Gears of War<br />
|-<br />
| "6e34f93f 0x01 0 0 0 0 0" || AngleLib<br />
|-<br />
| "D162E513 0 1" || Batman: Arkham Asylum<br />
|}<br />
<br />
=== VSH1 (0x708b7af9) - text ===<br />
=== VSH2 (0x708b7afa) - text ===<br />
=== VSH3 (0x708b7afb) - text ===<br />
=== VSH4 (0x708b7afc) - text ===<br />
=== VSH5 (0x708b7afd) - text ===<br />
=== VSH6 (0x708b7afe) - text ===<br />
=== VSH7 (0x708b7aff) - text ===<br />
=== VSH8 (0x708b7b00) - text ===<br />
=== VSH9 (0x708b7b01) - text ===<br />
=== VSH10 (0x708b7b02) - text ===<br />
<br />
== Registry Settings ==<br />
<br />
These are settings discovered in the 3D Vision driver that are not listed in the profile table, meaning they can only be set via the registry or (in some cases) control panel. Other settings on this page may (or may not) also be placed in the registry.<br />
<br />
On a 64bit OS these settings are under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\NVIDIA Corporation\Global\Stereo3D<br />
<br />
This section is incomplete.<br />
<br />
=== MonitorSizeOverride ===<br />
Overrides MonitorSize, but is not reset constantly making it a superior option to depth hacks.<br />
<br />
=== DrsEnable ===<br />
Enables the use of driver profiles.<br />
<br />
=== 0x1800babe ===<br />
That's not a hex value - that's a literal name of a possible registry key, including the "0x".<br />
<br />
=== StereoAdvancedHKConfig ===<br />
=== StereoFullHKConfig ===<br />
In conjunction with "StereoAdvancedHKConfig", it allows the use of advanced hotkeys like "CutoffFarDepthMore".<br />
"StereoFullHKConfig" also unlocks the minimum separation setting, allowing the 0 value instead of 1.<br />
<br />
=== StereoCompatibility ===<br />
=== EnablePersistentStereoDesktop ===<br />
=== EnableWindowedMode ===<br />
=== StereoIROutput ===<br />
=== StereoFlywheelCycleState ===<br />
=== StereoFlywheelCycle ===<br />
=== StereoVBIOverride ===<br />
=== ContrastOverride ===<br />
=== MultiheadMode ===<br />
=== SOLPerf ===<br />
=== EnableAPILog ===<br />
=== EnableHDMICheckerboard ===<br />
=== ContrastOverrideLog ===<br />
=== StereoKiosk ===<br />
=== DisablePatternWindowedMode ===<br />
=== StereoForcePairFlip ===<br />
=== __S ===<br />
=== SDStereoType ===<br />
=== StereoAnaglyphType ===<br />
=== StereoDisabled ===<br />
=== HDMIBroadcast ===<br />
=== Broadcast3way ===<br />
=== IGBroadcast ===<br />
=== SLIOverride ===<br />
=== UseCE ===<br />
=== ResourceTracking ===<br />
=== EnableIE9HTML5 ===<br />
=== IE9HTML5Width ===<br />
=== IE9HTML5Height ===<br />
=== IE9HTML5Layout ===<br />
<br />
== More Registry Settings ==<br />
On a 64bit OS these settings are under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\NVIDIA Corporation\Global\Stereo3DPersistent<br />
<br />
=== 3D Vision ===<br />
=== Count ===</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2019-09-09T04:36:05Z<p>Bo3b admin: /* List of features supported by HelixMod, and all versions available. */</p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
* Gotcha - Any [VSxxxxxxxx] section must come ''after'' any key and preset definitions. Otherwise key functions will be silently disabled.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constant registers in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail. But ''add r30.x, c250.y, c250.x'' will work. Use temp registers as a workaround.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
* Gotcha - Reading from a masked component of an input register can cause strange results (in some cases fixing the issue is insufficient to make the weirdness go away and the game has to be restarted). e.g. if an input register was declared ''dcl_texcoord5 v6.xy'', then doing a ''mov r30, v6'' is illegal as it tries to read from all four components of v6, the z and w of which are invalid.<br />
<br />
* Gotcha - Right side swizzles can silently fail if you only use 2 or 3 parameters. e.g. ''mov r1.yzw, r30.xyz'' will silently add w to the end giving the result ''mov r1.yzw, r30.xyzw'' which maps yzw to yzw, which is not what you expect. ''mov r1.yzw, r30.xxyz'' is correct.<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. The alternate CRC is calculated by disassembling and reassembling the shader, which has the result of stripping any headers.<br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
If this is true there are a couple of things to keep in mind in the shader dumps:<br />
* Dumps/AllShaders/PixelShaders - files named by original CRC, headers intact<br />
* Dumps/AllShaders/VertexShaders - files named by original CRC, headers intact<br />
* Dumps/SingleShaders/PixelShasers - files named by '''alternate CRC''', '''headers removed'''<br />
* Dumps/SingleShaders/VertexShaders - files named by original CRC, '''headers removed'''<br />
<br />
It is unknown whether the original or alternate CRC must be used in the ShaderOverride directory for vertex shaders and/or pixel shaders. The fact that vertex shaders are still dumped using the original CRC suggests they may need to use the original CRC, but it is unclear.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. This enables wrapping games that use the Direct3DCreate9Ex() call instead of the regular call.<br />
<br />
If Helix mod does not work with a game and the LOG.txt contains only the following lines, you need this option:<br />
<br />
Start logging..<br />
Direct3DCreate9Ex Created<br />
<br />
It is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
UseDefinedOnly = false<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Logs any calls to SetViewport before the first Present call.<br />
<br />
Type: Boolean<br />
<br />
===== CalcMatrixOncePerFrame =====<br />
Limits the number of times that GetMatrixFromReg and GetMatrixFromReg1 will work in a frame (unconfirmed if working at all).<br />
<br />
BUG: If both GetMatrixFromReg and GetMatrixFromReg1 are used, only the first matrix will be copied, rendering the second copy slot useless.<br />
<br />
Type: Boolean<br />
<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Creates a new depth texture that can be passed into shaders. The texture will not automatically get depth information, but it can be passed into a shader as an extra render target with DepthWRT to allow the shader to copy depth (or presumably any other) information to it. It can then be added to another shader as a texture with DepthWReg.<br />
<br />
Note that it is important that the depth texture resolution matches other render targets when using DepthWRT. DepthGetDepthResFrom can be used to set this, but there may be situations where the only option is to use DepthForceWidth and DepthForceHeight.<br />
<br />
Note that in some cases this texture may be created in mono instead of stereo! To work around this (and related bugs) in Montague's Mount, I had to use DepthGetDepthResFrom = 2 and DefSurfaceCreationMode = 1 (since there is no way to force the surface creation mode with the default DepthGetDepthResFrom) to force it to stereo, then manually set DepthForceWidth and DepthForceHeight to match the resolution so it would not break the lighting shaders.<br />
<br />
The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
<br />
===== DepthGetDepthResFrom =====<br />
Determines how to get the resolution to use for the depth texture created with MakeWTexture=true and not using DepthForceWidth/Height.<br />
<br />
0 = use the back buffer resolution<br />
<br />
1 = use the resolution of a render target created with CreateRenderTarget(), provided it is *greater than* 800x600<br />
<br />
2 = use the resolution of a depth surface created with CreateDepthStencilSurface(), provided it is *greater than* 800x600<br />
<br />
Note that the texture may be created in mono instead of stereo depending on a number of factors. Setting this to 2 and using DefSurfaceCreationMode=1 can indirectly force it to stereo.<br />
<br />
===== DepthForceWidth =====<br />
Use to override the width of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthForceHeight =====<br />
Use to override the height of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthWFormat =====<br />
The D3DFORMAT of the depth texture created with MakeWTexture=true<br />
<br />
Default: 114 (D3DFMT_R32F)<br />
<br />
Type: Integer<br />
<br />
===== CheckDepthResolution =====<br />
If true, the resolution of the depth texture must match the resolution of an active render target in order to set it as an extra render target with DepthWRT.<br />
<br />
If false, the depth texture will be injected unconditionally as an extra render target on any shader with DepthWRT set (and if the size does not match the shader will stop working).<br />
<br />
Note that for vertex shaders, this checks the first *render target*, while for pixel shaders this checks the *depth/stencil target*. In practice this means that in some cases the check will not be performed as expected.<br />
<br />
Type: Boolean<br />
<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only be used when a texture in DefinedTexturesVS is in use, otherwise it will be disabled (skipped?). It is almost always a good idea to set this to false and do the filtering in the shader, if for no other reason than you will still see it if it uses a new texture that you haven't seen yet.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
Needs to be specified in *both* the source and destination shaders to work<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
Setting this between 500 and 508 (inclusive) will copy the corresponding render target 0-8 instead of a texture. -1 also appears to be a special value, though it's not clear for what.<br />
<br />
GetSampler3FromReg only works with pixel shaders, vertex shaders must use the first two.<br />
<br />
BUG: Using GetSampler3FromReg with a render target (ie. 500-508), will set sampler 1 instead!<br />
<br />
BUG: If using with a vertex shader OR a render target, the texture's width must match the resolution to be copied. See note below under S*TexW.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Filters the textures copied with GetSamplerNFromReg to textures that match a specific format.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
-1 to disable the filter and copy textures regardless of format.<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Supposed to filter the textures copied with GetSamplerNFromReg to textures matching the corresponding width & height, however is broken due to a bug.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
BUG: Can only match screen resolution, making it impossible to copy textures / render targets of other sizes.<br />
<br />
Set both to -2 to match the current resolution<br />
<br />
Supposed to use -1 to ignore one of the width/height and match on the other<br />
<br />
Other values supposed to match a given width & height<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number for vertex shaders.<br />
<br />
The depth texture will be blank unless it has been filled out by another shader using DepthWRT.<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DepthWRT ====<br />
Injects the depth texture created with MakeWTexture = true into this shader as an additional render target. The shader can then be modified to write information to this new render which can be copied to other shaders later. Note that if the depth texture does not match the resolution of other render targets assigned to the shader the whole shader will stop working (and Helix Mod has several bugs that can complicate this)!<br />
<br />
This option could be useful in e.g. a full-screen deferred lighting shader that can copy the depth buffer to the new render target (if copying the depth buffer directly with Helix Mod did not work).<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Note that if you have matched a texture using DefinedTexturesVS, this will be ignored for that draw call and the one in the matching [TEXnnnnnnnn] section will be used instead. In this case, the vertex buffer section must have the same hash as the matched TEXTURE.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Stores the contents of the first entry of the first vertex in this constant register. This will usually be the input position of one one of the vertices.<br />
<br />
It can be useful to get a consistent position across an entire icon/word for auto depth adjustments (used in Dreamfall Chapters), or to compare against to determine which corner a particular vertex is since DX9 has no SV_VertexID semantic.<br />
<br />
To get the screen position you will need to duplicate any code in the shader that derives the output position from the input position - this may be as simple as copying a matrix multiplication.<br />
<br />
I have observed that the input W may be 0, whereas the input W to dcl_position would usually be 1, which may throw out some calculations that depend on it.<br />
<br />
Requires CheckTexCRC = true, UseDefinedOnly = false, GetVertex = true (either in the VS section, or possibly in a TEX, VB or PT section if they match the draw call), VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] section to work.<br />
<br />
NOTE: If you are using this in conjunction with a DefinedTexturesVS list, you must also define [TEXnnnnnnnn] sections for all matched textures, which must contain a VBOffsetList = 0; and then you must define a (possibly empty) [VBnnnnnnnn.0] section with the hash of the texture. In that case the VB section with the hash of the shader will be used when the texture did not match the list.<br />
<br />
==== FirstTexVertexPosReg ====<br />
This is similar to FirstVertexPosReg, but it will only be updated when a texture in the DefinedTexturesVS list is matched, and only when the texture changes.<br />
<br />
The same requirements as FirstVertexPosReg apply here, and since this can only be used with DefinedTexturesVS it will always require the extra sections [TEX] and [VB] sections matching the texture hash.<br />
<br />
==== GetVertex ====<br />
Necessary to use FirstVertexPosReg, FirstTexVertexPosReg or GetMatrixTexFromReg. Possibly others.<br />
<br />
Type: Boolean<br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
This will copy a matrix from the shader, but only when the same constraints as described in FirstTexVertexPosReg are met. (untested)<br />
<br />
==== MatrixTexReg ====<br />
This will copy the matrix copied via GetMatrixTexFromReg into the shader.<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] or [TEXnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
The nnnnnnnn will usually match the hash of the corresponding shader section, BUT if a texture in a DefinedTextureVS section has been matched it must match that texture hash instead (and in that case VBOffsetList must be set in the [TEXnnnnnnnn] section).<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
Unknown exactly what this does. Appears to affect the offset into the vertex buffer used in some sort of comparison with the points list.<br />
<br />
Valid Values: 0, 1 (multiplies offset by 2), 2 (multiplies offset by 4)<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
This replaces the VBOffsetList in the shader section when the texture from this section is matched. The [VBnnnnnnnn.m] section it refers to uses the hash of the TEXTURE, not the shader.<br />
<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Note that attempting to force 256x256 format=21 textures to stereo may result in a red "Out Of Memory" error from the driver. It is not known if this is a universal problem or specific to certain games or hardware - seen in Life Is Strange and Dragon's Dogma: Dark Arisen using a 680m.<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== Index =====<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces. The information for these surfaces comes from the LOG.txt file in lines starting with CreateDepthStencilSurface.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
<br />
----<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
<br />
Release versions from newest to oldest:<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Releasev2.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.upd.zip<br />
<br />
<br />
Debug From newest to oldest <br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Debug.zip<br />
<br />
<br />
DarkStarSword's binary patched version of the 140302 debug DLL:<br />
* Allows the LOG.txt to be opened while the game is running<br />
: 32bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/d3d9.dll<br />
: 64bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/x64/d3d9.dll<br />
<br />
<br><br />
<br><br />
<br />
<u>List of versions by date</u><br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br><br />
<br />
<br />
==== Conversion from old HelixModDLL syntax to new syntax: ====<br />
Special thanks to eqzitara for the conversion tutorial.<br />
<br />
<code><br />
[General]<br />
DumpAll = true<br />
DefVSConst1 = 250<br />
Preset1Key = 13<br />
Preset2Key = 110<br />
Preset3Key = 96<br />
DefPreset = 1<br />
<br />
// The normal On settings for fixes.<br />
// Compare if_eq.x to 666 in shader for on, 999 for off.<br />
// Compare if_eq.y to 666 in shader for pink, 999 for off.<br />
[Preset1]<br />
Const1 = 0x44268000<br />
Const2 = 0x4479c000<br />
<br />
// fix off<br />
[Preset2]<br />
Const1 = 0x4479c000<br />
<br />
// pinking on<br />
[Preset3]<br />
Const2 = 0x44268000<br />
</code><br />
<br />
CORRECTED FOR NEW DLL<br />
<br />
<code><br />
[General]<br />
DefVSConst1 = 250<br />
PresetsKeysList = 0;1;2;<br />
<br />
<br />
[KEY0]<br />
Key = 13<br />
Presets = 0;<br />
Type = 2<br />
<br />
[PRES0]<br />
Const1 = 0x44268000<br />
Const2 = 0x4479c000<br />
<br />
[KEY1]<br />
Key = 110<br />
Presets = 1;<br />
Type = 2<br />
<br />
[PRES1]<br />
Const1 = 0x4479c000<br />
<br />
[KEY2]<br />
Key = 96<br />
Presets = 2;<br />
Type = 2<br />
<br />
[PRES2]<br />
Const2 = 0x44268000<br />
</code></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2019-09-09T04:35:25Z<p>Bo3b admin: /* List of features supported by HelixMod, and all versions available. */</p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
* Gotcha - Any [VSxxxxxxxx] section must come ''after'' any key and preset definitions. Otherwise key functions will be silently disabled.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constant registers in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail. But ''add r30.x, c250.y, c250.x'' will work. Use temp registers as a workaround.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
* Gotcha - Reading from a masked component of an input register can cause strange results (in some cases fixing the issue is insufficient to make the weirdness go away and the game has to be restarted). e.g. if an input register was declared ''dcl_texcoord5 v6.xy'', then doing a ''mov r30, v6'' is illegal as it tries to read from all four components of v6, the z and w of which are invalid.<br />
<br />
* Gotcha - Right side swizzles can silently fail if you only use 2 or 3 parameters. e.g. ''mov r1.yzw, r30.xyz'' will silently add w to the end giving the result ''mov r1.yzw, r30.xyzw'' which maps yzw to yzw, which is not what you expect. ''mov r1.yzw, r30.xxyz'' is correct.<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. The alternate CRC is calculated by disassembling and reassembling the shader, which has the result of stripping any headers.<br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
If this is true there are a couple of things to keep in mind in the shader dumps:<br />
* Dumps/AllShaders/PixelShaders - files named by original CRC, headers intact<br />
* Dumps/AllShaders/VertexShaders - files named by original CRC, headers intact<br />
* Dumps/SingleShaders/PixelShasers - files named by '''alternate CRC''', '''headers removed'''<br />
* Dumps/SingleShaders/VertexShaders - files named by original CRC, '''headers removed'''<br />
<br />
It is unknown whether the original or alternate CRC must be used in the ShaderOverride directory for vertex shaders and/or pixel shaders. The fact that vertex shaders are still dumped using the original CRC suggests they may need to use the original CRC, but it is unclear.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. This enables wrapping games that use the Direct3DCreate9Ex() call instead of the regular call.<br />
<br />
If Helix mod does not work with a game and the LOG.txt contains only the following lines, you need this option:<br />
<br />
Start logging..<br />
Direct3DCreate9Ex Created<br />
<br />
It is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
UseDefinedOnly = false<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Logs any calls to SetViewport before the first Present call.<br />
<br />
Type: Boolean<br />
<br />
===== CalcMatrixOncePerFrame =====<br />
Limits the number of times that GetMatrixFromReg and GetMatrixFromReg1 will work in a frame (unconfirmed if working at all).<br />
<br />
BUG: If both GetMatrixFromReg and GetMatrixFromReg1 are used, only the first matrix will be copied, rendering the second copy slot useless.<br />
<br />
Type: Boolean<br />
<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Creates a new depth texture that can be passed into shaders. The texture will not automatically get depth information, but it can be passed into a shader as an extra render target with DepthWRT to allow the shader to copy depth (or presumably any other) information to it. It can then be added to another shader as a texture with DepthWReg.<br />
<br />
Note that it is important that the depth texture resolution matches other render targets when using DepthWRT. DepthGetDepthResFrom can be used to set this, but there may be situations where the only option is to use DepthForceWidth and DepthForceHeight.<br />
<br />
Note that in some cases this texture may be created in mono instead of stereo! To work around this (and related bugs) in Montague's Mount, I had to use DepthGetDepthResFrom = 2 and DefSurfaceCreationMode = 1 (since there is no way to force the surface creation mode with the default DepthGetDepthResFrom) to force it to stereo, then manually set DepthForceWidth and DepthForceHeight to match the resolution so it would not break the lighting shaders.<br />
<br />
The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
<br />
===== DepthGetDepthResFrom =====<br />
Determines how to get the resolution to use for the depth texture created with MakeWTexture=true and not using DepthForceWidth/Height.<br />
<br />
0 = use the back buffer resolution<br />
<br />
1 = use the resolution of a render target created with CreateRenderTarget(), provided it is *greater than* 800x600<br />
<br />
2 = use the resolution of a depth surface created with CreateDepthStencilSurface(), provided it is *greater than* 800x600<br />
<br />
Note that the texture may be created in mono instead of stereo depending on a number of factors. Setting this to 2 and using DefSurfaceCreationMode=1 can indirectly force it to stereo.<br />
<br />
===== DepthForceWidth =====<br />
Use to override the width of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthForceHeight =====<br />
Use to override the height of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthWFormat =====<br />
The D3DFORMAT of the depth texture created with MakeWTexture=true<br />
<br />
Default: 114 (D3DFMT_R32F)<br />
<br />
Type: Integer<br />
<br />
===== CheckDepthResolution =====<br />
If true, the resolution of the depth texture must match the resolution of an active render target in order to set it as an extra render target with DepthWRT.<br />
<br />
If false, the depth texture will be injected unconditionally as an extra render target on any shader with DepthWRT set (and if the size does not match the shader will stop working).<br />
<br />
Note that for vertex shaders, this checks the first *render target*, while for pixel shaders this checks the *depth/stencil target*. In practice this means that in some cases the check will not be performed as expected.<br />
<br />
Type: Boolean<br />
<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only be used when a texture in DefinedTexturesVS is in use, otherwise it will be disabled (skipped?). It is almost always a good idea to set this to false and do the filtering in the shader, if for no other reason than you will still see it if it uses a new texture that you haven't seen yet.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
Needs to be specified in *both* the source and destination shaders to work<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
Setting this between 500 and 508 (inclusive) will copy the corresponding render target 0-8 instead of a texture. -1 also appears to be a special value, though it's not clear for what.<br />
<br />
GetSampler3FromReg only works with pixel shaders, vertex shaders must use the first two.<br />
<br />
BUG: Using GetSampler3FromReg with a render target (ie. 500-508), will set sampler 1 instead!<br />
<br />
BUG: If using with a vertex shader OR a render target, the texture's width must match the resolution to be copied. See note below under S*TexW.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Filters the textures copied with GetSamplerNFromReg to textures that match a specific format.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
-1 to disable the filter and copy textures regardless of format.<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Supposed to filter the textures copied with GetSamplerNFromReg to textures matching the corresponding width & height, however is broken due to a bug.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
BUG: Can only match screen resolution, making it impossible to copy textures / render targets of other sizes.<br />
<br />
Set both to -2 to match the current resolution<br />
<br />
Supposed to use -1 to ignore one of the width/height and match on the other<br />
<br />
Other values supposed to match a given width & height<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number for vertex shaders.<br />
<br />
The depth texture will be blank unless it has been filled out by another shader using DepthWRT.<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DepthWRT ====<br />
Injects the depth texture created with MakeWTexture = true into this shader as an additional render target. The shader can then be modified to write information to this new render which can be copied to other shaders later. Note that if the depth texture does not match the resolution of other render targets assigned to the shader the whole shader will stop working (and Helix Mod has several bugs that can complicate this)!<br />
<br />
This option could be useful in e.g. a full-screen deferred lighting shader that can copy the depth buffer to the new render target (if copying the depth buffer directly with Helix Mod did not work).<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Note that if you have matched a texture using DefinedTexturesVS, this will be ignored for that draw call and the one in the matching [TEXnnnnnnnn] section will be used instead. In this case, the vertex buffer section must have the same hash as the matched TEXTURE.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Stores the contents of the first entry of the first vertex in this constant register. This will usually be the input position of one one of the vertices.<br />
<br />
It can be useful to get a consistent position across an entire icon/word for auto depth adjustments (used in Dreamfall Chapters), or to compare against to determine which corner a particular vertex is since DX9 has no SV_VertexID semantic.<br />
<br />
To get the screen position you will need to duplicate any code in the shader that derives the output position from the input position - this may be as simple as copying a matrix multiplication.<br />
<br />
I have observed that the input W may be 0, whereas the input W to dcl_position would usually be 1, which may throw out some calculations that depend on it.<br />
<br />
Requires CheckTexCRC = true, UseDefinedOnly = false, GetVertex = true (either in the VS section, or possibly in a TEX, VB or PT section if they match the draw call), VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] section to work.<br />
<br />
NOTE: If you are using this in conjunction with a DefinedTexturesVS list, you must also define [TEXnnnnnnnn] sections for all matched textures, which must contain a VBOffsetList = 0; and then you must define a (possibly empty) [VBnnnnnnnn.0] section with the hash of the texture. In that case the VB section with the hash of the shader will be used when the texture did not match the list.<br />
<br />
==== FirstTexVertexPosReg ====<br />
This is similar to FirstVertexPosReg, but it will only be updated when a texture in the DefinedTexturesVS list is matched, and only when the texture changes.<br />
<br />
The same requirements as FirstVertexPosReg apply here, and since this can only be used with DefinedTexturesVS it will always require the extra sections [TEX] and [VB] sections matching the texture hash.<br />
<br />
==== GetVertex ====<br />
Necessary to use FirstVertexPosReg, FirstTexVertexPosReg or GetMatrixTexFromReg. Possibly others.<br />
<br />
Type: Boolean<br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
This will copy a matrix from the shader, but only when the same constraints as described in FirstTexVertexPosReg are met. (untested)<br />
<br />
==== MatrixTexReg ====<br />
This will copy the matrix copied via GetMatrixTexFromReg into the shader.<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] or [TEXnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
The nnnnnnnn will usually match the hash of the corresponding shader section, BUT if a texture in a DefinedTextureVS section has been matched it must match that texture hash instead (and in that case VBOffsetList must be set in the [TEXnnnnnnnn] section).<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
Unknown exactly what this does. Appears to affect the offset into the vertex buffer used in some sort of comparison with the points list.<br />
<br />
Valid Values: 0, 1 (multiplies offset by 2), 2 (multiplies offset by 4)<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
This replaces the VBOffsetList in the shader section when the texture from this section is matched. The [VBnnnnnnnn.m] section it refers to uses the hash of the TEXTURE, not the shader.<br />
<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Note that attempting to force 256x256 format=21 textures to stereo may result in a red "Out Of Memory" error from the driver. It is not known if this is a universal problem or specific to certain games or hardware - seen in Life Is Strange and Dragon's Dogma: Dark Arisen using a 680m.<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== Index =====<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces. The information for these surfaces comes from the LOG.txt file in lines starting with CreateDepthStencilSurface.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
<br />
----<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
<br />
Release versions from newest to oldest:<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Releasev2.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.upd.zip<br />
<br />
<br />
Debug From newest to oldest <br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Debug.zip<br />
<br />
<br />
DarkStarSword's binary patched version of the 140302 debug DLL:<br />
* Allows the LOG.txt to be opened while the game is running<br />
: 32bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/d3d9.dll<br />
: 64bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/x64/d3d9.dll<br />
<br />
<br><br />
<br><br />
<br />
<u>List of versions by date</u><br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br><br />
<br />
<br />
==== Conversion from old HelixModDLL syntax to new syntax: ====<br />
<br />
<code><br />
[General]<br />
DumpAll = true<br />
DefVSConst1 = 250<br />
Preset1Key = 13<br />
Preset2Key = 110<br />
Preset3Key = 96<br />
DefPreset = 1<br />
<br />
// The normal On settings for fixes.<br />
// Compare if_eq.x to 666 in shader for on, 999 for off.<br />
// Compare if_eq.y to 666 in shader for pink, 999 for off.<br />
[Preset1]<br />
Const1 = 0x44268000<br />
Const2 = 0x4479c000<br />
<br />
// fix off<br />
[Preset2]<br />
Const1 = 0x4479c000<br />
<br />
// pinking on<br />
[Preset3]<br />
Const2 = 0x44268000<br />
</code><br />
<br />
CORRECTED FOR NEW DLL<br />
<br />
<code><br />
[General]<br />
DefVSConst1 = 250<br />
PresetsKeysList = 0;1;2;<br />
<br />
<br />
[KEY0]<br />
Key = 13<br />
Presets = 0;<br />
Type = 2<br />
<br />
[PRES0]<br />
Const1 = 0x44268000<br />
Const2 = 0x4479c000<br />
<br />
[KEY1]<br />
Key = 110<br />
Presets = 1;<br />
Type = 2<br />
<br />
[PRES1]<br />
Const1 = 0x4479c000<br />
<br />
[KEY2]<br />
Key = 96<br />
Presets = 2;<br />
Type = 2<br />
<br />
[PRES2]<br />
Const2 = 0x44268000<br />
</code></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Hot_tipsHot tips2018-12-03T05:08:06Z<p>Bo3b admin: </p>
<hr />
<div>Mike:<br />
I must admit I don't understand at all what the "OverrideMethod" is actually doing, but it's worth remembering that if shaders don't seem to load, or F10 does not work, then cycle through them...[https://forums.geforce.com/default/topic/513190/3d-vision/how-to-fix-disable-shaders-in-games-dll-guide-and-fixes-/post/4048593/#4048593]<br />
<br />
eqzitara:<br />
Change in preset layout for newer dlls.[http://helixmod.blogspot.com/2013/04/guide-how-to-make-custom.html]<br />
<br />
Mike:<br />
Problems with Const1 not always working. [https://forums.geforce.com/default/topic/513190/3d-vision/how-to-fix-disable-shaders-in-games-dll-guide-and-fixes-/post/4284091/#4284091]<br />
<br />
Helix:<br />
Key codes list for mapping keys. [http://msdn.microsoft.com/en-us/library/ms927178.aspx]<br />
<br />
<br />
Future DX11 fix example. Cannot recall original demo I planned to use, maybe Crysis 2? Another possibility is DefenseGrid2.</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=List_of_glitchesList of glitches2018-08-07T01:26:07Z<p>Bo3b admin: </p>
<hr />
<div>This is intended to be a comprehensive list of visual glitches seen in games, as a way of categorizing them and having an example of each.<br />
<br />
Easy<br />
* HUD at screen depth<br />
* Nameplates at screen depth<br />
* Crosshair at screen depth<br />
* Skybox too close<br />
<br />
Medium<br />
* Lights at screen depth<br />
* Bloom at wrong depth<br />
* Character halos<br />
* Decals<br />
<br />
Hard<br />
* Shadows at screen depth<br />
* Shadows doubled<br />
* Depth mapped crosshair<br />
* Specular reflections<br />
<br />
Super hard<br />
* Reflections</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2018-01-15T22:25:07Z<p>Bo3b admin: /* ASM */</p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
* Gotcha - Any [VSxxxxxxxx] section must come ''after'' any key and preset definitions. Otherwise key functions will be silently disabled.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constant registers in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail. But ''add r30.x, c250.y, c250.x'' will work. Use temp registers as a workaround.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
* Gotcha - Reading from a masked component of an input register can cause strange results (in some cases fixing the issue is insufficient to make the weirdness go away and the game has to be restarted). e.g. if an input register was declared ''dcl_texcoord5 v6.xy'', then doing a ''mov r30, v6'' is illegal as it tries to read from all four components of v6, the z and w of which are invalid.<br />
<br />
* Gotcha - Right side swizzles can silently fail if you only use 2 or 3 parameters. e.g. ''mov r1.yzw, r30.xyz'' will silently add w to the end giving the result ''mov r1.yzw, r30.xyzw'' which maps yzw to yzw, which is not what you expect. ''mov r1.yzw, r30.xxyz'' is correct.<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. The alternate CRC is calculated by disassembling and reassembling the shader, which has the result of stripping any headers.<br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
If this is true there are a couple of things to keep in mind in the shader dumps:<br />
* Dumps/AllShaders/PixelShaders - files named by original CRC, headers intact<br />
* Dumps/AllShaders/VertexShaders - files named by original CRC, headers intact<br />
* Dumps/SingleShaders/PixelShasers - files named by '''alternate CRC''', '''headers removed'''<br />
* Dumps/SingleShaders/VertexShaders - files named by original CRC, '''headers removed'''<br />
<br />
It is unknown whether the original or alternate CRC must be used in the ShaderOverride directory for vertex shaders and/or pixel shaders. The fact that vertex shaders are still dumped using the original CRC suggests they may need to use the original CRC, but it is unclear.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. This enables wrapping games that use the Direct3DCreate9Ex() call instead of the regular call.<br />
<br />
If Helix mod does not work with a game and the LOG.txt contains only the following lines, you need this option:<br />
<br />
Start logging..<br />
Direct3DCreate9Ex Created<br />
<br />
It is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
UseDefinedOnly = false<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Logs any calls to SetViewport before the first Present call.<br />
<br />
Type: Boolean<br />
<br />
===== CalcMatrixOncePerFrame =====<br />
Limits the number of times that GetMatrixFromReg and GetMatrixFromReg1 will work in a frame (unconfirmed if working at all).<br />
<br />
BUG: If both GetMatrixFromReg and GetMatrixFromReg1 are used, only the first matrix will be copied, rendering the second copy slot useless.<br />
<br />
Type: Boolean<br />
<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Creates a new depth texture that can be passed into shaders. The texture will not automatically get depth information, but it can be passed into a shader as an extra render target with DepthWRT to allow the shader to copy depth (or presumably any other) information to it. It can then be added to another shader as a texture with DepthWReg.<br />
<br />
Note that it is important that the depth texture resolution matches other render targets when using DepthWRT. DepthGetDepthResFrom can be used to set this, but there may be situations where the only option is to use DepthForceWidth and DepthForceHeight.<br />
<br />
Note that in some cases this texture may be created in mono instead of stereo! To work around this (and related bugs) in Montague's Mount, I had to use DepthGetDepthResFrom = 2 and DefSurfaceCreationMode = 1 (since there is no way to force the surface creation mode with the default DepthGetDepthResFrom) to force it to stereo, then manually set DepthForceWidth and DepthForceHeight to match the resolution so it would not break the lighting shaders.<br />
<br />
The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
<br />
===== DepthGetDepthResFrom =====<br />
Determines how to get the resolution to use for the depth texture created with MakeWTexture=true and not using DepthForceWidth/Height.<br />
<br />
0 = use the back buffer resolution<br />
<br />
1 = use the resolution of a render target created with CreateRenderTarget(), provided it is *greater than* 800x600<br />
<br />
2 = use the resolution of a depth surface created with CreateDepthStencilSurface(), provided it is *greater than* 800x600<br />
<br />
Note that the texture may be created in mono instead of stereo depending on a number of factors. Setting this to 2 and using DefSurfaceCreationMode=1 can indirectly force it to stereo.<br />
<br />
===== DepthForceWidth =====<br />
Use to override the width of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthForceHeight =====<br />
Use to override the height of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthWFormat =====<br />
The D3DFORMAT of the depth texture created with MakeWTexture=true<br />
<br />
Default: 114 (D3DFMT_R32F)<br />
<br />
Type: Integer<br />
<br />
===== CheckDepthResolution =====<br />
If true, the resolution of the depth texture must match the resolution of an active render target in order to set it as an extra render target with DepthWRT.<br />
<br />
If false, the depth texture will be injected unconditionally as an extra render target on any shader with DepthWRT set (and if the size does not match the shader will stop working).<br />
<br />
Note that for vertex shaders, this checks the first *render target*, while for pixel shaders this checks the *depth/stencil target*. In practice this means that in some cases the check will not be performed as expected.<br />
<br />
Type: Boolean<br />
<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only be used when a texture in DefinedTexturesVS is in use, otherwise it will be disabled (skipped?). It is almost always a good idea to set this to false and do the filtering in the shader, if for no other reason than you will still see it if it uses a new texture that you haven't seen yet.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
Needs to be specified in *both* the source and destination shaders to work<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
Setting this between 500 and 508 (inclusive) will copy the corresponding render target 0-8 instead of a texture. -1 also appears to be a special value, though it's not clear for what.<br />
<br />
GetSampler3FromReg only works with pixel shaders, vertex shaders must use the first two.<br />
<br />
BUG: Using GetSampler3FromReg with a render target (ie. 500-508), will set sampler 1 instead!<br />
<br />
BUG: If using with a vertex shader OR a render target, the texture's width must match the resolution to be copied. See note below under S*TexW.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Filters the textures copied with GetSamplerNFromReg to textures that match a specific format.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
-1 to disable the filter and copy textures regardless of format.<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Supposed to filter the textures copied with GetSamplerNFromReg to textures matching the corresponding width & height, however is broken due to a bug.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
BUG: Can only match screen resolution, making it impossible to copy textures / render targets of other sizes.<br />
<br />
Set both to -2 to match the current resolution<br />
<br />
Supposed to use -1 to ignore one of the width/height and match on the other<br />
<br />
Other values supposed to match a given width & height<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number for vertex shaders.<br />
<br />
The depth texture will be blank unless it has been filled out by another shader using DepthWRT.<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DepthWRT ====<br />
Injects the depth texture created with MakeWTexture = true into this shader as an additional render target. The shader can then be modified to write information to this new render which can be copied to other shaders later. Note that if the depth texture does not match the resolution of other render targets assigned to the shader the whole shader will stop working (and Helix Mod has several bugs that can complicate this)!<br />
<br />
This option could be useful in e.g. a full-screen deferred lighting shader that can copy the depth buffer to the new render target (if copying the depth buffer directly with Helix Mod did not work).<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Note that if you have matched a texture using DefinedTexturesVS, this will be ignored for that draw call and the one in the matching [TEXnnnnnnnn] section will be used instead. In this case, the vertex buffer section must have the same hash as the matched TEXTURE.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Stores the contents of the first entry of the first vertex in this constant register. This will usually be the input position of one one of the vertices.<br />
<br />
It can be useful to get a consistent position across an entire icon/word for auto depth adjustments (used in Dreamfall Chapters), or to compare against to determine which corner a particular vertex is since DX9 has no SV_VertexID semantic.<br />
<br />
To get the screen position you will need to duplicate any code in the shader that derives the output position from the input position - this may be as simple as copying a matrix multiplication.<br />
<br />
I have observed that the input W may be 0, whereas the input W to dcl_position would usually be 1, which may throw out some calculations that depend on it.<br />
<br />
Requires CheckTexCRC = true, UseDefinedOnly = false, GetVertex = true (either in the VS section, or possibly in a TEX, VB or PT section if they match the draw call), VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] section to work.<br />
<br />
NOTE: If you are using this in conjunction with a DefinedTexturesVS list, you must also define [TEXnnnnnnnn] sections for all matched textures, which must contain a VBOffsetList = 0; and then you must define a (possibly empty) [VBnnnnnnnn.0] section with the hash of the texture. In that case the VB section with the hash of the shader will be used when the texture did not match the list.<br />
<br />
==== FirstTexVertexPosReg ====<br />
This is similar to FirstVertexPosReg, but it will only be updated when a texture in the DefinedTexturesVS list is matched, and only when the texture changes.<br />
<br />
The same requirements as FirstVertexPosReg apply here, and since this can only be used with DefinedTexturesVS it will always require the extra sections [TEX] and [VB] sections matching the texture hash.<br />
<br />
==== GetVertex ====<br />
Necessary to use FirstVertexPosReg, FirstTexVertexPosReg or GetMatrixTexFromReg. Possibly others.<br />
<br />
Type: Boolean<br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
This will copy a matrix from the shader, but only when the same constraints as described in FirstTexVertexPosReg are met. (untested)<br />
<br />
==== MatrixTexReg ====<br />
This will copy the matrix copied via GetMatrixTexFromReg into the shader.<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] or [TEXnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
The nnnnnnnn will usually match the hash of the corresponding shader section, BUT if a texture in a DefinedTextureVS section has been matched it must match that texture hash instead (and in that case VBOffsetList must be set in the [TEXnnnnnnnn] section).<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
Unknown exactly what this does. Appears to affect the offset into the vertex buffer used in some sort of comparison with the points list.<br />
<br />
Valid Values: 0, 1 (multiplies offset by 2), 2 (multiplies offset by 4)<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
This replaces the VBOffsetList in the shader section when the texture from this section is matched. The [VBnnnnnnnn.m] section it refers to uses the hash of the TEXTURE, not the shader.<br />
<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Note that attempting to force 256x256 format=21 textures to stereo may result in a red "Out Of Memory" error from the driver. It is not known if this is a universal problem or specific to certain games or hardware - seen in Life Is Strange and Dragon's Dogma: Dark Arisen using a 680m.<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== Index =====<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces. The information for these surfaces comes from the LOG.txt file in lines starting with CreateDepthStencilSurface.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
<br />
----<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
<br />
Release versions from newest to oldest:<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Releasev2.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.upd.zip<br />
<br />
<br />
Debug From newest to oldest <br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Debug.zip<br />
<br />
<br />
DarkStarSword's binary patched version of the 140302 debug DLL:<br />
* Allows the LOG.txt to be opened while the game is running<br />
: 32bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/d3d9.dll<br />
: 64bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/x64/d3d9.dll<br />
<br />
<br><br />
<br><br />
<br />
<u>List of versions by date</u><br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Fixing_bookmarksFixing bookmarks2017-03-31T02:59:10Z<p>Bo3b admin: Created page with "== List of bookmarks compiled by DJ-RK while learning ShaderHacking == ==== 3DM ==== ---- [https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderh..."</p>
<hr />
<div>== List of bookmarks compiled by DJ-RK while learning ShaderHacking ==<br />
<br />
<br />
==== 3DM ====<br />
----<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4802926/#4802926 3DM: Fix via texture filtering]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4424155/#4424155 3DM: Don't fully understand]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4468768/#4468768 3DM: Active depth target filtering for UI elements sharing shaders]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4606663/#4606663 3DM v1.1.34- Texture and RenderTarget size filtering]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4608352/#4608352 3DM: Finding texture hashes]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4626075/#4626075 3DM: Partner shader filtering and some Q&A's about texture filtering]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4693870/#4693870 3DM v1.2.4: Arbitrary resource copying-fix bloom, specular, auto-depth]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4604740/#4604740 3DM: Texture filtering preamble]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4694095/#4694095 3DM: Auto-crosshair instructions]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4706623/#4706623 3DM: HUD fixing using RT size filtering or partner shaders]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4739680/#4739680 3DM: Indepth using RT copying, texture injection, using Present to clear resources]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4740272/#4740272 3DM:1.2.11: Texture tracking and explaining some functionality]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4748987/#4748987 3DM: Using Vertex buffer copying explained]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4752058/#4752058 3DM: Using frame analysis explained]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4753142/#4753142 3DM: Texture filtering Q&A]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4755726/#4755726 3DM: Unity fullscreen alt-tab functionality]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4762270/#4762270 3DM: More partner shader matching and Iteration function]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4766862/#4766862 3DM: Texture replacement example]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4767495/#4767495 3DM: More on FC4 HUD using texture replacement/filtering]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4778105/#4778105 3DM v1.2.22: Custom shader injecting]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4781440/#4781440 3DM: Some vertex fixing Q&A]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4783821/#4783821 3DM v1.2.24: Hooking functionality]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4796898/#4796898 3DM: Auto-crosshair and texture filtering Q's]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4797380/#4797380 3DM: Auto-crosshair and texture filtering A's]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4798771/#4798771 3DM: No matching PS for VS in shaderusage.txt]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4800665/#4800665 3DM v1.2.28: Custom resource creation/import, copy_description]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4808715/#4808715 3DM v1.2.30: cmd_Decompiler and OM Blend override]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4810934/#4810934 3DM v1.2.31: Better custom shader functionality with examples]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4814129/#4814129 3DM: HUD fix Q&As]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4827131/#4827131 3DM - Resource copying - very indepth]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4828687/#4828687 3DM - Q&A on resource copying, lots of specifics]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4805133/#4805133 Advanced fix: DSS FC4 filtering icons by texture color for custom separation. Dumping index/vertex buffers]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/5030610/#5030610 3DM - Nvidia profile editing]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/5030676/#5030676 3DM - ASM if conditions]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/5041362/#5041362 3DM - Display constant buffer values via custom shader]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4909267/#4909267 3DM - Inverse-cs]<br />
<br />
[https://forums.geforce.com/default/topic/897529/3d-vision/3d-hbao-normal-map-artefact-fix/post/5056334/#5056334 3D HBAO+ Normal Map Artefact Fix - GeForce Forums]<br />
<br />
<br />
==== Fix examples ====<br />
----<br />
[https://github.com/DarkStarSword/3d-fixes/commit/f9f24ac4e69b0e7e9c2bac432258e92486a9eb8e#diff-1301562854974a8a351877ff9929da85L4 Reflections fix]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/135aeedeced9a9437db0fcf3f5a2deb1f5669880 FCPrimal: Fix tile lighting clipping · DarkStarSword/3d-fixes@135aeed · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/00be9c1cea0f2a031034676f1c97ca8f0e03629f FCPrimal: Fix Ambient Occlusion · DarkStarSword/3d-fixes@00be9c1 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/594d528be6f993a858330627234cd2b4947a23f5 Far Cry Primal: Fix reflections via stereo2mono technique · DarkStarSword/3d-fixes@594d528 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/0f09870fba8fa550c5df089f7619358deeb3bf89 Far Cry Primal: Fix Lens Flares · DarkStarSword/3d-fixes@0f09870 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/f72ca4cd18c5e68318b89a602b8604df183c5103 FCPrimal: Fix shadow volumes / light shafts (includes debugging shader) · DarkStarSword/3d-fixes@f72ca4c · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/6b66f3ae111ed508c17fe43466a8af42c4ac7703 FCPrimal: Move bloom to infinity · DarkStarSword/3d-fixes@6b66f3a · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/53458ac6ee49f03f8e6346350d65d42f92a1d5ac FCPrimal: Apply scripted volumetric fog fix · DarkStarSword/3d-fixes@53458ac · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/76af7b96a19723172520f61cd778a79fedf970cc Lichdom: Fix light shafts · DarkStarSword/3d-fixes@76af7b9 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/06805484e6b65d6c52380f9271346f36ae232a27 Lichdom: Accurate fix for CryEngine directional shadows!!! · DarkStarSword/3d-fixes@0680548 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/fd10e5a3be067b671d903fbfc87527f512bb1abd Lichdom: Fix specular highlights from moonlight on ground in tutorial · DarkStarSword/3d-fixes@fd10e5a · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/6ebe6e76d2951f8ec6075c769890150837ca2124 Lichdom: Use render target filtering to avoid adjusting UI elements i… · DarkStarSword/3d-fixes@6ebe6e7 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/4d3881bc6ba1a9802e83b8d7afc853c467f9f7e8 Lichdom: Fix reflections on 'very high' quality water · DarkStarSword/3d-fixes@4d3881b · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/5e29434f33f1238c5cd58806ff589ab20e3d8998 Mad Max: Fix environment reflections + specular highlights · DarkStarSword/3d-fixes@5e29434 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/a0f71fccfda105ab6a4a1d9b71534c5d68ae977c Mad Max: Fix bloom/lens flare opacity being calculated from wrong spo… · DarkStarSword/3d-fixes@a0f71fc · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/9d526e0940e968c1e10cbda8d1ead764e7f48c1c The Park: Fix UE4 ReflectionEnvironmentComputeShaders.ucf shader · DarkStarSword/3d-fixes@9d526e0 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/5d74514c6c7b7c1348238bbf255f8c9d5617a9d8 The Park: Move sun reflection to infinity · DarkStarSword/3d-fixes@5d74514 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/62c0ec7fc88d169816c24168e3df7ee9b1eea4ce The Park: Fix light shafts · DarkStarSword/3d-fixes@62c0ec7 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/8ecb3ce0f56260e56877ad118788481087faf032 The Park: Fix UE4 tile lighting · DarkStarSword/3d-fixes@8ecb3ce · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/8b1bed869b5d3ddf913dd6517262edf292e1750e The Park: Move screen space reflections to surface depth · DarkStarSword/3d-fixes@8b1bed8 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/0a29067100f4f334659790818a0dc79754595ed8 The Witness: Adjust UI depth for puzzles · DarkStarSword/3d-fixes@0a29067 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/2b07c19b95c299899a8040f0d8c6d9bbeaaf4e72 The Witness: Auto adjust the mouse cursor depth · DarkStarSword/3d-fixes@2b07c19 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/13867a8f0e63e2f8093b5052ab482c5ef5af8fe8 The Witness: Disable UI adjustment when no depth buffer is in use · DarkStarSword/3d-fixes@13867a8 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/e5f07f4c4820b4266d5316ba50224bc707435e93 The Witness: Substantial improvements to auto cursor for some puzzles · DarkStarSword/3d-fixes@e5f07f4 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/7e65c899103ef88f43febc7aeb2b2e35d9391a14 Eleusis: Fix river water refraction at shoreline · DarkStarSword/3d-fixes@7e65c89 · GitHub]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/31dfd0ff42d1d65ff389ee338ede3f7e210522e0 ABZU: Move specular highlights to correct depth · Also world space adjustment example]<br />
<br />
[https://github.com/DarkStarSword/3d-fixes/commit/154232d50aa8166b76f2e1d2f62d56f54ad69471 ABZU: Fix deferred lighting - Easy world space adj example]<br />
<br />
<br />
==== Theory / Formulas ====<br />
----<br />
[https://en.wikipedia.org/wiki/Z-buffering Z-buffering - Wikipedia]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4319127/#4319127 Fixing halos explained-bo3b]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4418002/#4418002 Theory:Objects to infinity, far clipping, W coordinate by DSS]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4482025/#4482025 PostProcessing effect adjustments]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4778134/#4778134 Fixing fixed effects being clipped via the VS]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4778156/#4778156 Theory: DSS fixes Batman CS shader lights]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4334276/#4334276 Tips for finding right shadow shaders]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4810674/#4810674 ASM: Calculating byte offsets of buffers]<br />
<br />
[http://www.tomdalling.com/blog/modern-opengl/explaining-homogenous-coordinates-and-projective-geometry/ Explaining Homogeneous Coordinates & Projective Geometry — Tom Dalling]<br />
<br />
[http://rbwhitaker.wikidot.com/intro-to-shaders Introduction to Shaders - RB Whitaker's Wiki]<br />
<br />
[https://www.youtube.com/watch?v=GssPDoVtQfA NVIDIA 3D Vision Shadow Fix Tips & Tricks - Demonicon - YouTube]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/5002744/#5002744 ASM inverse matrix formula]<br />
<br />
[https://github.com/mx-2/3d-fix/blob/master/_tools_/inverseMatrix.asm 3d-fix/inverseMatrix.asm at master · mx-2/3d-fix · GitHub]<br />
<br />
[https://forums.geforce.com/default/topic/897529/3d-hbao-normal-map-artefact-fix 3D HBAO+ Normal Map Artefact Fix - GeForce Forums]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4722833/#4722833 *More shadows fixing theory]<br />
<br />
[https://msdn.microsoft.com/en-us/library/windows/desktop/bb147302(v=vs.85).aspx Projection Transform (Direct3D 9) (Windows)]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/5059968/#5059968 Near and far clipping values from projection matrix]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4879429/#4879429 World space fix via frustum corners method]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4919490/#4919490 Stereo correction without projection matrix answers]<br />
<br />
<br><br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4391243/#4391243 UI Depth adjustment w/ texture isolating]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4391938/#4391938 HM-Texture filtering]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4407798/#4407798 ASM-cmp operator]<br />
<br />
[https://forums.geforce.com/default/topic/513190/3d-vision/how-to-fix-disable-shaders-in-games-dll-guide-and-fixes-/post/4331640/#4331640 Nvidia profiles codes]<br />
<br />
[http://wiki.bo3b.net/index.php?title=Canonical_Stereo_Code Canonical Stereo Code - Bo3b's School for Shaderhackers]<br />
<br />
[https://forums.geforce.com/default/topic/513190/3d-vision/how-to-fix-disable-shaders-in-games-dll-guide-and-fixes-/post/4069271/#4069271 Fixing shadows by Mike_ar69]<br />
<br />
[http://www.directxtutorial.com/Lesson.aspx?lessonid=9-4-5 DirectXTutorial.com]<br />
<br />
[http://wiki.bo3b.net/index.php?title=HelixMod_Feature_List HelixMod Feature List - Bo3b's School for Shaderhackers]<br />
<br />
[https://forums.geforce.com/default/topic/513190/3d-vision/how-to-fix-disable-shaders-in-games-dll-guide-and-fixes-/post/3797899/#3797899 HM-LUA script for UE3]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/42/ Unity fixes (Halos, specular, lighting) explained by DSS]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/22/ HM-Partner shader overrides]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4303537/#4303537 Fixing GodRays using screen postprocessing-DSS]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4420067/#4420067 Moon depth adjustment]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4478194/#4478194 ASM-Ways to disable a shader]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4488608/#4488608 Modify render targets/surfaces]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4489401/#4489401 UE3 shadows fixing pattern]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4490217/#4490217 DSS Shadertool.py instructions]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4490819/#4490819 More shadertool.py instructions]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4789689/#4789689 HM: Creating mono/stereo surfaces. Using grep to getin matches from log.txt]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4799000/#4799000 Depth buffer filtering for driver heuristics issue]<br />
<br />
[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4715553/#4715553 *Fixing shadows, various transformation stages and fixes for each]<br />
<br />
[https://www.diffchecker.com/ Diff Checker - Online diff tool to compare text to find the difference between two text files]<br />
<br />
[https://forums.geforce.com/default/topic/809236/3d-vision/obscure-indie-games/post/4640134/#4640134 obscure indie games - GeForce Forums]<br />
<br />
[https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4830858/#4830858 3DM - Lots of background info to study]<br />
<br />
[http://general%20-%20fixing%20reflections/ Dragons Dogma: Dark Arisen. - GeForce Forums]</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Canonical_Stereo_CodeCanonical Stereo Code2017-03-27T20:18:51Z<p>Bo3b admin: </p>
<hr />
<div>=== Prime Directive ===<br />
<br />
This is the ''prime directive'' code in ASM for DX9 and HelixMod. And the HLSL version for 3Dmigoto. In all cases, we are implementing the NVidia specified formula of: <br><br><br />
<code>clipPos.x += EyeSign * Separation * ( clipPos.w – Convergence )</code><br />
<br />
<br />
''''' ASM (both HelixMod and 3Dmigoto ASM) '''''<br />
<br />
This is the wordy version with extra comments to make it more clear what is happening.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// The required constant for txldl in c200.z<br />
def c200, 1.0, 600, 0.0625, 0<br />
// Sampler used to fetch stereo params, <br />
// s0 sampler is default for VS<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
// Fetch the Separation (r30.x) and Convergence (r30.y) <br />
// using the Helix NVapi trick<br />
texldl r30, c200.z, s0<br />
<br />
// (W - Convergence)<br />
add r30.w, r0.w, -r30.y<br />
<br />
// multiply that times Separation for:<br />
// Separation * (W - Convergence)<br />
mul r30.z, r30.x, r30.w<br />
<br />
// Add that to Xold for the complete:<br />
// Xold + Separation * (W - Convergence)<br />
add r0.x, r0.x, r30.z<br />
<br />
</syntaxhighlight><br />
<br />
<br />
Another variant that is more concise, but less clear. As you get more accustomed to seeing this sequence of code, or are sharing with an expert crowd, it's less necessary to fully document this part, as it is always the same sequence and easy to recognize because of the texldl of 0.0625.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mad r0.x, r30.x, r30.w, r0.x<br />
</syntaxhighlight><br />
<br />
<br />
Another very common variant you'll see in HelixMod fixes is the four line version, with no comments. This is less optimal than the two above, but is worth seeing to be able to recognize it.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mul r30.z, r30.x, r30.w<br />
add r0.x, r0.x, r30.z<br />
</syntaxhighlight><br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The HLSL version is very similar, but since it's a compile language there is no need to be terse when writing the code. We can make it "self-documenting" by using good variable names.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
float separation = StereoParams.Load(0).x;<br />
float convergence = StereoParams.Load(0).y;<br />
<br />
// At this point, "location" is the output position, but missing stereo.<br />
<br />
location.x += separation * (location.w - convergence);<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
=== Matrix Inversion ===<br />
<br />
We often need to invert a ViewProjectionMatrix, in order to be able to stereo correct a location in the proper viewspace (usually projection space for deferred rendering).<br />
<br />
We only need to do this in cases where the inverted matrix is not available. A lot of games have both matrices available, and can be used directly. <br />
<br />
We have code samples for both ASM, and for HLSL. It's worth noting that for HelixMod fixes in DX9, that HelixMod already supports [[HelixMod_Feature_List#InverseMatrix.2C_InverseMatrix1|inverted matrices]] directly, and this code should not be used there, because all this extra code will impact performance. Try to avoid using it in PS in particular, because inverting a matrix for every pixel is very costly.<br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The '''best''' way to invert a matrix is to use the runtime shader feature from d3dx.ini. This is best because it runs once per frame, which keeps a performance impact low. This was created by ''DarkStarSword''.<br />
<br />
[https://github.com/bo3b/3Dmigoto/wiki/Injecting-custom-shaders Described here] The actual shader is found [https://github.com/DarkStarSword/3d-fixes/blob/e0f67a3bed5fa90d8823a31b014e607f51c4fefc/inverse-cs.hlsl here] And, how to use it, described [https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4909267/#4909267 here]<br />
<br />
<br />
If that doesn't work for some reason (not all games are compatible), it's possible to do it in HLSL directly. This example is backwards in that it starts with an inverted matrix, then creates the forward matrix from that. Used in an example [https://github.com/DarkStarSword/3d-fixes/blob/master/Mad%20Max/ShaderFixes/01037617f0200a5c-ps_replace.txt here] Again, it's worth noting that doing this in a PS shader is sub-optimal.<br />
<br />
<br />
This version is found in matrix.hlsl, created by ''DarkStarSword''. It can be added into the header of any HLSL file, or #included.<br />
<br />
An original can be found [https://github.com/DarkStarSword/3d-fixes/blob/master/ABZU/ShaderFixes/matrix.hlsl here]<br />
<syntaxhighlight lang="c"><br />
matrix inverse(matrix m)<br />
{<br />
matrix inv;<br />
<br />
float det = determinant(m);<br />
inv[0].x = m[1].y*(m[2].z*m[3].w - m[2].w*m[3].z) + m[1].z*(m[2].w*m[3].y - m[2].y*m[3].w) + m[1].w*(m[2].y*m[3].z - m[2].z*m[3].y);<br />
inv[0].y = m[0].y*(m[2].w*m[3].z - m[2].z*m[3].w) + m[0].z*(m[2].y*m[3].w - m[2].w*m[3].y) + m[0].w*(m[2].z*m[3].y - m[2].y*m[3].z);<br />
inv[0].z = m[0].y*(m[1].z*m[3].w - m[1].w*m[3].z) + m[0].z*(m[1].w*m[3].y - m[1].y*m[3].w) + m[0].w*(m[1].y*m[3].z - m[1].z*m[3].y);<br />
inv[0].w = m[0].y*(m[1].w*m[2].z - m[1].z*m[2].w) + m[0].z*(m[1].y*m[2].w - m[1].w*m[2].y) + m[0].w*(m[1].z*m[2].y - m[1].y*m[2].z);<br />
inv[1].x = m[1].x*(m[2].w*m[3].z - m[2].z*m[3].w) + m[1].z*(m[2].x*m[3].w - m[2].w*m[3].x) + m[1].w*(m[2].z*m[3].x - m[2].x*m[3].z);<br />
inv[1].y = m[0].x*(m[2].z*m[3].w - m[2].w*m[3].z) + m[0].z*(m[2].w*m[3].x - m[2].x*m[3].w) + m[0].w*(m[2].x*m[3].z - m[2].z*m[3].x);<br />
inv[1].z = m[0].x*(m[1].w*m[3].z - m[1].z*m[3].w) + m[0].z*(m[1].x*m[3].w - m[1].w*m[3].x) + m[0].w*(m[1].z*m[3].x - m[1].x*m[3].z);<br />
inv[1].w = m[0].x*(m[1].z*m[2].w - m[1].w*m[2].z) + m[0].z*(m[1].w*m[2].x - m[1].x*m[2].w) + m[0].w*(m[1].x*m[2].z - m[1].z*m[2].x);<br />
inv[2].x = m[1].x*(m[2].y*m[3].w - m[2].w*m[3].y) + m[1].y*(m[2].w*m[3].x - m[2].x*m[3].w) + m[1].w*(m[2].x*m[3].y - m[2].y*m[3].x);<br />
inv[2].y = m[0].x*(m[2].w*m[3].y - m[2].y*m[3].w) + m[0].y*(m[2].x*m[3].w - m[2].w*m[3].x) + m[0].w*(m[2].y*m[3].x - m[2].x*m[3].y);<br />
inv[2].z = m[0].x*(m[1].y*m[3].w - m[1].w*m[3].y) + m[0].y*(m[1].w*m[3].x - m[1].x*m[3].w) + m[0].w*(m[1].x*m[3].y - m[1].y*m[3].x);<br />
inv[2].w = m[0].x*(m[1].w*m[2].y - m[1].y*m[2].w) + m[0].y*(m[1].x*m[2].w - m[1].w*m[2].x) + m[0].w*(m[1].y*m[2].x - m[1].x*m[2].y);<br />
inv[3].x = m[1].x*(m[2].z*m[3].y - m[2].y*m[3].z) + m[1].y*(m[2].x*m[3].z - m[2].z*m[3].x) + m[1].z*(m[2].y*m[3].x - m[2].x*m[3].y);<br />
inv[3].y = m[0].x*(m[2].y*m[3].z - m[2].z*m[3].y) + m[0].y*(m[2].z*m[3].x - m[2].x*m[3].z) + m[0].z*(m[2].x*m[3].y - m[2].y*m[3].x);<br />
inv[3].z = m[0].x*(m[1].z*m[3].y - m[1].y*m[3].z) + m[0].y*(m[1].x*m[3].z - m[1].z*m[3].x) + m[0].z*(m[1].y*m[3].x - m[1].x*m[3].y);<br />
inv[3].w = m[0].x*(m[1].y*m[2].z - m[1].z*m[2].y) + m[0].y*(m[1].z*m[2].x - m[1].x*m[2].z) + m[0].z*(m[1].x*m[2].y - m[1].y*m[2].x);<br />
inv /= det;<br />
<br />
return inv;<br />
}<br />
<br />
matrix inverse(float4 m0, float4 m1, float4 m2, float4 m3)<br />
{<br />
return inverse(matrix(m0, m1, m2, m3));<br />
}<br />
<br />
#define MATRIX(cb, idx) matrix(cb[idx], cb[idx+1], cb[idx+2], cb[idx+3])<br />
</syntaxhighlight><br />
<br />
<br />
<br />
<br />
The original version of this came from ''Mike_ar69''.<br />
<syntaxhighlight lang="c"><br />
...<br />
matrix ivp, vp;<br />
ivp = matrix(InstanceConsts[1], InstanceConsts[2], InstanceConsts[3], InstanceConsts[4]);<br />
<br />
// Work out the view-projection matrix from it's inverse:<br />
vp[0].x = ivp[1].y*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[1].z*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[1].w*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y);<br />
vp[0].y = ivp[0].y*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[0].z*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[0].w*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z);<br />
vp[0].z = ivp[0].y*(ivp[1].z*ivp[3].w - ivp[1].w*ivp[3].z) + ivp[0].z*(ivp[1].w*ivp[3].y - ivp[1].y*ivp[3].w) + ivp[0].w*(ivp[1].y*ivp[3].z - ivp[1].z*ivp[3].y);<br />
vp[0].w = ivp[0].y*(ivp[1].w*ivp[2].z - ivp[1].z*ivp[2].w) + ivp[0].z*(ivp[1].y*ivp[2].w - ivp[1].w*ivp[2].y) + ivp[0].w*(ivp[1].z*ivp[2].y - ivp[1].y*ivp[2].z);<br />
vp[1].x = ivp[1].x*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[1].z*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[1].w*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z);<br />
vp[1].y = ivp[0].x*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[0].z*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[0].w*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x);<br />
vp[1].z = ivp[0].x*(ivp[1].w*ivp[3].z - ivp[1].z*ivp[3].w) + ivp[0].z*(ivp[1].x*ivp[3].w - ivp[1].w*ivp[3].x) + ivp[0].w*(ivp[1].z*ivp[3].x - ivp[1].x*ivp[3].z);<br />
vp[1].w = ivp[0].x*(ivp[1].z*ivp[2].w - ivp[1].w*ivp[2].z) + ivp[0].z*(ivp[1].w*ivp[2].x - ivp[1].x*ivp[2].w) + ivp[0].w*(ivp[1].x*ivp[2].z - ivp[1].z*ivp[2].x);<br />
vp[2].x = ivp[1].x*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[1].y*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[1].w*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[2].y = ivp[0].x*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[0].y*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[0].w*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[2].z = ivp[0].x*(ivp[1].y*ivp[3].w - ivp[1].w*ivp[3].y) + ivp[0].y*(ivp[1].w*ivp[3].x - ivp[1].x*ivp[3].w) + ivp[0].w*(ivp[1].x*ivp[3].y - ivp[1].y*ivp[3].x);<br />
vp[2].w = ivp[0].x*(ivp[1].w*ivp[2].y - ivp[1].y*ivp[2].w) + ivp[0].y*(ivp[1].x*ivp[2].w - ivp[1].w*ivp[2].x) + ivp[0].w*(ivp[1].y*ivp[2].x - ivp[1].x*ivp[2].y);<br />
vp[3].x = ivp[1].x*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z) + ivp[1].y*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x) + ivp[1].z*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[3].y = ivp[0].x*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y) + ivp[0].y*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z) + ivp[0].z*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[3].z = ivp[0].x*(ivp[1].z*ivp[3].y - ivp[1].y*ivp[3].z) + ivp[0].y*(ivp[1].x*ivp[3].z - ivp[1].z*ivp[3].x) + ivp[0].z*(ivp[1].y*ivp[3].x - ivp[1].x*ivp[3].y);<br />
vp[3].w = ivp[0].x*(ivp[1].y*ivp[2].z - ivp[1].z*ivp[2].y) + ivp[0].y*(ivp[1].z*ivp[2].x - ivp[1].x*ivp[2].z) + ivp[0].z*(ivp[1].x*ivp[2].y - ivp[1].y*ivp[2].x);<br />
vp /= determinant(ivp);<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM (3Dmigoto ASM) '''''<br />
<br />
This one hasn't been fully tested, but should work. This is created by ''mx-2'' and found on his [https://github.com/mx-2/3d-fix/blob/master/_tools_/inverseMatrix.asm GitHub]<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
//<br />
// inverseMatrix.asm<br />
//<br />
// Matrix inversion with Gauss-Jordan elimination<br />
// algorithm on GPU.<br />
//<br />
// This algorithm uses 128 instructions, from which<br />
// 83 (best case) to 110 (worst case) are executed.<br />
//<br />
// input matrix is in r0-r3<br />
// output will be in r4-r7<br />
// r8, r9 are used as temporary registers<br />
// c200 = (1,0,0,0) is required<br />
//<br />
// r0.x r0.y r0.z r0.w | r4.x, r4.y, r4.z, r4.w<br />
// r1.x r1.y r1.z r1.w | r5.x, r5.y, r5.z, r5.w<br />
// r2.x r2.y r2.z r2.w | r6.x, r6.y, r6.z, r6.w<br />
// r3.x r3.y r3.z r3.w | r7.x, r7.y, r7.z, r7.w<br />
//<br />
// Test:<br />
// SETR r0, 0, 2, 3, 4<br />
// SETR r1, 1, 0, 5, 4<br />
// SETR r2,-1, 2, 3, 4<br />
// SETR r3, 0, 2, 3, 5<br />
//<br />
// Should produce<br />
// r4 = 1.0, 0.0, -1.0, 0.0<br />
// r5 = 1.6, -0.3, -0.3, -0.8<br />
// r6 = 0.6, 0.2, 0.2, -0.8<br />
// r7 = -1.0, 0.0, 0.0, 1.0<br />
//<br />
<br />
// Init registers<br />
def c200, 1, 0, 0, 0<br />
mov r4, c200.xyzw<br />
mov r5, c200.wxyz<br />
mov r6, c200.zwxy<br />
mov r7, c200.yzwx<br />
<br />
// Pivot first column<br />
mov r8, c200<br />
if_eq r0.x, r8.y<br />
if_eq r1.x, r8.y<br />
if_eq r2.x, r8.y<br />
mov r9, r0<br />
mov r0, r3<br />
mov r3, r9<br />
mov r9, r4<br />
mov r4, r7<br />
mov r7, r9<br />
else<br />
mov r9, r0<br />
mov r0, r2<br />
mov r2, r9<br />
mov r9, r4<br />
mov r4, r6<br />
mov r6, r9<br />
endif<br />
else<br />
mov r9, r0<br />
mov r0, r1<br />
mov r1, r9<br />
mov r9, r4<br />
mov r4, r5<br />
mov r5, r9<br />
endif<br />
endif<br />
<br />
// First column<br />
rcp r8.x, r0.x<br />
mul r8.y, r8.x, r1.x<br />
mul r9, r0, r8.y<br />
add r1, r1, -r9<br />
mul r9, r4, r8.y<br />
add r5, r5, -r9<br />
<br />
mul r8.y, r8.x, r2.x<br />
mul r9, r0, r8.y<br />
add r2, r2, -r9<br />
mul r9, r4, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.x<br />
mul r9, r0, r8.y<br />
add r3, r3, -r9<br />
mul r9, r4, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot second column<br />
mov r8, c200<br />
if_eq r1.y, r8.y<br />
if_eq r2.y, r8.y<br />
mov r9, r1<br />
mov r1, r3<br />
mov r3, r9<br />
mov r9, r5<br />
mov r5, r7<br />
mov r7, r9<br />
else<br />
mov r9, r1<br />
mov r1, r2<br />
mov r2, r9<br />
mov r9, r5<br />
mov r5, r6<br />
mov r6, r9<br />
endif<br />
endif<br />
<br />
// Second column<br />
rcp r8.x, r1.y<br />
mul r8.y, r8.x, r2.y<br />
mul r9, r1, r8.y<br />
add r2, r2, -r9<br />
mul r9, r5, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.y<br />
mul r9, r1, r8.y<br />
add r3, r3, -r9<br />
mul r9, r5, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot third column<br />
mov r8, c200<br />
if_eq r2.z, r8.y<br />
mov r9, r2<br />
mov r2, r3<br />
mov r3, r9<br />
mov r9, r6<br />
mov r6, r7<br />
mov r7, r9<br />
endif<br />
<br />
// Third column<br />
rcp r8.x, r2.z<br />
mul r8.y, r8.x, r3.z<br />
mul r9, r2, r8.y<br />
add r3, r3, -r9<br />
mul r9, r6, r8.y<br />
add r7, r7, -r9<br />
<br />
// Normalize r3.w<br />
rcp r8.x, r3.w<br />
mul r3, r3, r8.x<br />
mul r7, r7, r8.x<br />
<br />
// Fourth column<br />
mul r8, r3, r2.w<br />
mul r9, r7, r2.w<br />
add r2, r2, -r8<br />
add r6, r6, -r9<br />
<br />
mul r8, r3, r1.w<br />
mul r9, r7, r1.w<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r3, r0.w<br />
mul r9, r7, r0.w<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r2.z<br />
rcp r8.x, r2.z<br />
mul r2, r2, r8.x<br />
mul r6, r6, r8.x<br />
<br />
// Third column (upper part)<br />
mul r8, r2, r1.z<br />
mul r9, r6, r1.z<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r2, r0.z<br />
mul r9, r6, r0.z<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r1.y<br />
rcp r8.x, r1.y<br />
mul r1, r1, r8.x<br />
mul r5, r5, r8.x<br />
<br />
// Second column (upper part)<br />
mul r8, r1, r0.y<br />
mul r9, r5, r0.y<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize first column<br />
rcp r8.x, r0.x<br />
mul r0, r0, r8.x<br />
mul r4, r4, r8.x<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
Two more variants, both from Helifax. In case those previous ones don't seem quite right.<br />
<br />
''''' HLSL '''''<br />
<br />
<syntaxhighlight lang="c"><br />
//Work out Inverse<br />
//...Variables<br />
float4 a1, a2, a3, a4;<br />
float4 b1, b2, b3, b4;<br />
float det;<br />
//...Original Matrix<br />
a1 = g_invViewProjMatrix._m00_m10_m20_m30;<br />
a2 = g_invViewProjMatrix._m01_m11_m21_m31;<br />
a3 = g_invViewProjMatrix._m02_m12_m22_m32;<br />
a4 = g_invViewProjMatrix._m03_m13_m23_m33;<br />
//...Determinant<br />
det = a1.x*(a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y));<br />
det += a1.y*(a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.z) + a2.w*(a3.z*a4.x - a3.x*a4.z));<br />
det += a1.z*(a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x));<br />
det += a1.w*(a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y));<br />
//...Inverse Matrix Elements<br />
b1.x = a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y);<br />
b1.y = a1.y*(a3.w*a4.z - a3.z*a4.w) + a1.z*(a3.y*a4.w - a3.w*a4.y) + a1.w*(a3.z*a4.y - a3.y*a4.z);<br />
b1.z = a1.y*(a2.z*a4.w - a2.w*a4.z) + a1.z*(a2.w*a4.y - a2.y*a4.w) + a1.w*(a2.y*a4.z - a2.z*a4.y);<br />
b1.w = a1.y*(a2.w*a3.z - a2.z*a3.w) + a1.z*(a2.y*a3.w - a2.w*a3.y) + a1.w*(a2.z*a3.y - a2.y*a3.z);<br />
b2.x = a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.x) + a2.w*(a3.z*a4.x - a3.x*a4.z);<br />
b2.y = a1.x*(a3.z*a4.w - a3.w*a4.z) + a1.z*(a3.w*a4.x - a3.x*a4.w) + a1.w*(a3.x*a4.z - a3.z*a4.x);<br />
b2.z = a1.x*(a2.w*a4.z - a2.z*a4.w) + a1.z*(a2.x*a4.w - a2.w*a4.x) + a1.w*(a2.z*a4.x - a2.x*a4.z);<br />
b2.w = a1.x*(a2.z*a3.w - a2.w*a3.z) + a1.z*(a2.w*a3.x - a2.x*a3.w) + a1.w*(a2.x*a3.z - a2.z*a3.x);<br />
b3.x = a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x);<br />
b3.y = a1.x*(a3.w*a4.y - a3.y*a4.w) + a1.y*(a3.x*a4.w - a3.w*a4.x) + a1.w*(a3.y*a4.x - a3.x*a4.y);<br />
b3.z = a1.x*(a2.y*a4.w - a2.w*a4.y) + a1.y*(a2.w*a4.x - a2.x*a4.w) + a1.w*(a2.x*a4.y - a2.y*a4.x);<br />
b3.w = a1.x*(a2.w*a3.y - a2.y*a3.w) + a1.y*(a2.x*a3.w - a2.w*a3.x) + a1.w*(a2.y*a3.x - a2.x*a3.y);<br />
b4.x = a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y);<br />
b4.y = a1.x*(a3.y*a4.z - a3.z*a4.y) + a1.y*(a3.z*a4.x - a3.x*a4.z) + a1.z*(a3.x*a4.y - a3.y*a4.x);<br />
b4.z = a1.x*(a2.z*a4.y - a2.y*a4.z) + a1.y*(a2.x*a4.z - a2.z*a4.x) + a1.z*(a2.y*a4.x - a2.x*a4.y);<br />
b4.w = a1.x*(a2.y*a3.z - a2.z*a3.y) + a1.y*(a2.z*a3.x - a2.x*a3.z) + a1.z*(a2.x*a3.y - a2.y*a3.x);<br />
b1.xyzw /= det;<br />
b2.xyzw /= det;<br />
b3.xyzw /= det;<br />
b4.xyzw /= det;<br />
//End Inverse<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM '''''<br />
<br />
Generated from the HLSL, using fxc.<br />
<syntaxhighlight lang="c"><br />
// Declare how many registers ww use<br />
// The code uses registers from r38 to r53.<br />
dcl_temps 60<br />
<br />
// 3DMigoto StereoParams:<br />
dcl_resource_texture1d (float,float,float,float) t120<br />
dcl_resource_texture2d (float,float,float,float) t125<br />
ld_indexable(texture1d)(float,float,float,float) r41.xyzw, l(0, 0, 0, 0), t120.xyzw<br />
ld_indexable(texture2d)(float,float,float,float) r40.xyzw, l(0, 0, 0, 0), t125.xyzw<br />
<br />
// Inverse<br />
// cb0[0], etc is the inverseMatrix<br />
mov r0.xyzw, cb0[0].xyzw<br />
mov r1.xyzw, cb0[1].xyzw<br />
mov r2.xyzw, cb0[2].xyzw<br />
mov r3.xyzw, cb0[3].xyzw<br />
mul r4.x, r2.z, r3.w<br />
mul r4.y, r2.w, r3.z<br />
mov r4.y, -r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r1.y, r4.x<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.z<br />
mul r4.z, r2.z, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r0.x, r4.x<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.y<br />
mul r4.z, r2.y, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.y, r4.y<br />
mul r4.z, r2.w, r3.y<br />
mul r4.w, r2.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.z<br />
mul r4.w, r2.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r5.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r2.y, r3.w<br />
mul r4.w, r2.w, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.y<br />
mul r4.w, r2.y, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.y, r4.z, r4.y<br />
mul r4.y, r1.z, r3.w<br />
mul r4.z, r1.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.w, r3.y<br />
mul r4.w, r1.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.y, r3.z<br />
mul r4.w, r1.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.z, r4.z, r4.y<br />
mul r4.y, r1.w, r2.z<br />
mul r4.z, r1.z, r2.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.y, r2.w<br />
mul r4.w, r1.w, r2.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r2.y<br />
mul r4.w, r1.y, r2.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.w, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r6.x, r4.z, r4.y<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.y, r4.z, r4.y<br />
mul r4.y, r1.w, r3.z<br />
mul r4.z, r1.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.x, r3.w<br />
mul r4.w, r1.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r3.x<br />
mul r4.w, r1.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.z, r4.z, r4.y<br />
mul r4.y, r1.z, r2.w<br />
mul r4.z, r1.w, r2.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r2.x<br />
mul r4.w, r1.x, r2.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.x, r2.z<br />
mul r4.w, r1.z, r2.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.w, r4.z, r4.y<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r7.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r7.y, r4.z, r4.y<br />
mul r4.y, r1.y, r3.w<br />
mul r4.z, r1.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r3.x<br />
mul r3.w, r1.x, r3.w<br />
mov r3.w, -r3.w<br />
add r3.w, r3.w, r4.z<br />
mul r3.w, r0.y, r3.w<br />
add r3.w, r3.w, r4.y<br />
mul r4.y, r1.x, r3.y<br />
mul r4.z, r1.y, r3.x<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r7.z, r3.w, r4.y<br />
mul r3.w, r1.w, r2.y<br />
mul r4.y, r1.y, r2.w<br />
mov r4.y, -r4.y<br />
add r3.w, r3.w, r4.y<br />
mul r3.w, r0.x, r3.w<br />
mul r2.w, r1.x, r2.w<br />
mul r1.w, r1.w, r2.x<br />
mov r1.w, -r1.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r1.w, r1.w, r3.w<br />
mul r2.w, r1.y, r2.x<br />
mul r3.w, r1.x, r2.y<br />
mov r3.w, -r3.w<br />
add r2.w, r2.w, r3.w<br />
mul r0.w, r0.w, r2.w<br />
add r7.w, r0.w, r1.w<br />
mul r0.w, r2.z, r3.y<br />
mul r1.w, r2.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r1.x<br />
mul r1.w, r2.x, r3.z<br />
mul r2.w, r2.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.y<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.y, r3.x<br />
mul r2.w, r2.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.z<br />
add r8.x, r0.w, r1.w<br />
mul r0.w, r2.y, r3.z<br />
mul r1.w, r2.z, r3.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r2.z, r3.x<br />
mul r2.w, r2.x, r3.z<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.x, r3.y<br />
mul r2.w, r2.y, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.y, r0.w, r1.w<br />
mul r0.w, r1.z, r3.y<br />
mul r1.w, r1.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r1.x, r3.z<br />
mul r2.w, r1.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r1.y, r3.x<br />
mul r2.w, r1.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.z, r0.w, r1.w<br />
mul r0.w, r1.y, r2.z<br />
mul r1.w, r1.z, r2.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.x, r0.w, r0.x<br />
mul r0.w, r1.z, r2.x<br />
mul r1.z, r1.x, r2.z<br />
mov r1.z, -r1.z<br />
add r0.w, r0.w, r1.z<br />
mul r0.y, r0.w, r0.y<br />
add r0.x, r0.y, r0.x<br />
mul r0.y, r1.x, r2.y<br />
mul r0.w, r1.y, r2.x<br />
mov r0.w, -r0.w<br />
add r0.y, r0.w, r0.y<br />
mul r0.y, r0.y, r0.z<br />
add r8.w, r0.y, r0.x<br />
div r0.xyzw, r5.xyzw, r4.xxxx<br />
div r1.xyzw, r6.xyzw, r4.xxxx<br />
div r2.xyzw, r7.xyzw, r4.xxxx<br />
div r3.xyzw, r8.xyzw, r4.xxxx<br />
<br />
// Store results for later use as r0-r4 are most <br />
// likely to be used by the default shader code.<br />
// r50 equivalent of matrix._m00_m01_m02_m03<br />
// r51 equivalent of matrix._m10_m11_m12_m13<br />
// r52 equivalent of matrix._m20_m21_m22_m23<br />
// r53 equivalent of matrix._m30_m31_m32_m33<br />
<br />
mov r50.xyzw, r0.xyzw <br />
mov r51.xyzw, r1.xyzw <br />
mov r52.xyzw, r2.xyzw <br />
mov r53.xyzw, r3.xyzw<br />
</syntaxhighlight></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Canonical_Stereo_CodeCanonical Stereo Code2017-03-27T20:18:05Z<p>Bo3b admin: </p>
<hr />
<div>=== Prime Directive ===<br />
<br />
This is the ''prime directive'' code in ASM for DX9 and HelixMod. And the HLSL version for 3Dmigoto. In all cases, we are implementing the NVidia specified formula of: <br><br><br />
<code>clipPos.x += EyeSign * Separation * ( clipPos.w – Convergence )</code><br />
<br />
<br />
''''' ASM (both HelixMod and 3Dmigoto ASM) '''''<br />
<br />
This is the wordy version with extra comments to make it more clear what is happening.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// The required constant for txldl in c200.z<br />
def c200, 1.0, 600, 0.0625, 0<br />
// Sampler used to fetch stereo params, <br />
// s0 sampler is default for VS<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
// Fetch the Separation (r30.x) and Convergence (r30.y) <br />
// using the Helix NVapi trick<br />
texldl r30, c200.z, s0<br />
<br />
// (W - Convergence)<br />
add r30.w, r0.w, -r30.y<br />
<br />
// multiply that times Separation for:<br />
// Separation * (W - Convergence)<br />
mul r30.z, r30.x, r30.w<br />
<br />
// Add that to Xold for the complete:<br />
// Xold + Separation * (W - Convergence)<br />
add r0.x, r0.x, r30.z<br />
<br />
</syntaxhighlight><br />
<br />
<br />
Another variant that is more concise, but less clear. As you get more accustomed to seeing this sequence of code, or are sharing with an expert crowd, it's less necessary to fully document this part, as it is always the same sequence and easy to recognize because of the texldl of 0.0625.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mad r0.x, r30.x, r30.w, r0.x<br />
</syntaxhighlight><br />
<br />
<br />
Another very common variant you'll see in HelixMod fixes is the four line version, with no comments. This is less optimal than the two above, but is worth seeing to be able to recognize it.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mul r30.z, r30.x, r30.w<br />
add r0.x, r0.x, r30.z<br />
</syntaxhighlight><br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The HLSL version is very similar, but since it's a compile language there is no need to be terse when writing the code. We can make it "self-documenting" by using good variable names.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// .Load should only be done once, but can be done anywhere in the code.<br />
<br />
float separation = StereoParams.Load(0).x;<br />
float convergence = StereoParams.Load(0).y;<br />
<br />
// At this point, "location" is the output position, but missing stereo.<br />
<br />
location.x += separation * (location.w - convergence);<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
=== Matrix Inversion ===<br />
<br />
We often need to invert a ViewProjectionMatrix, in order to be able to stereo correct a location in the proper viewspace (usually projection space for deferred rendering).<br />
<br />
We only need to do this in cases where the inverted matrix is not available. A lot of games have both matrices available, and can be used directly. <br />
<br />
We have code samples for both ASM, and for HLSL. It's worth noting that for HelixMod fixes in DX9, that HelixMod already supports [[HelixMod_Feature_List#InverseMatrix.2C_InverseMatrix1|inverted matrices]] directly, and this code should not be used there, because all this extra code will impact performance. Try to avoid using it in PS in particular, because inverting a matrix for every pixel is very costly.<br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The '''best''' way to invert a matrix is to use the runtime shader feature from d3dx.ini. This is best because it runs once per frame, which keeps a performance impact low. This was created by ''DarkStarSword''.<br />
<br />
[https://github.com/bo3b/3Dmigoto/wiki/Injecting-custom-shaders Described here] The actual shader is found [https://github.com/DarkStarSword/3d-fixes/blob/e0f67a3bed5fa90d8823a31b014e607f51c4fefc/inverse-cs.hlsl here] And, how to use it, described [https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4909267/#4909267 here]<br />
<br />
<br />
If that doesn't work for some reason (not all games are compatible), it's possible to do it in HLSL directly. This example is backwards in that it starts with an inverted matrix, then creates the forward matrix from that. Used in an example [https://github.com/DarkStarSword/3d-fixes/blob/master/Mad%20Max/ShaderFixes/01037617f0200a5c-ps_replace.txt here] Again, it's worth noting that doing this in a PS shader is sub-optimal.<br />
<br />
<br />
This version is found in matrix.hlsl, created by ''DarkStarSword''. It can be added into the header of any HLSL file, or #included.<br />
<br />
An original can be found [https://github.com/DarkStarSword/3d-fixes/blob/master/ABZU/ShaderFixes/matrix.hlsl here]<br />
<syntaxhighlight lang="c"><br />
matrix inverse(matrix m)<br />
{<br />
matrix inv;<br />
<br />
float det = determinant(m);<br />
inv[0].x = m[1].y*(m[2].z*m[3].w - m[2].w*m[3].z) + m[1].z*(m[2].w*m[3].y - m[2].y*m[3].w) + m[1].w*(m[2].y*m[3].z - m[2].z*m[3].y);<br />
inv[0].y = m[0].y*(m[2].w*m[3].z - m[2].z*m[3].w) + m[0].z*(m[2].y*m[3].w - m[2].w*m[3].y) + m[0].w*(m[2].z*m[3].y - m[2].y*m[3].z);<br />
inv[0].z = m[0].y*(m[1].z*m[3].w - m[1].w*m[3].z) + m[0].z*(m[1].w*m[3].y - m[1].y*m[3].w) + m[0].w*(m[1].y*m[3].z - m[1].z*m[3].y);<br />
inv[0].w = m[0].y*(m[1].w*m[2].z - m[1].z*m[2].w) + m[0].z*(m[1].y*m[2].w - m[1].w*m[2].y) + m[0].w*(m[1].z*m[2].y - m[1].y*m[2].z);<br />
inv[1].x = m[1].x*(m[2].w*m[3].z - m[2].z*m[3].w) + m[1].z*(m[2].x*m[3].w - m[2].w*m[3].x) + m[1].w*(m[2].z*m[3].x - m[2].x*m[3].z);<br />
inv[1].y = m[0].x*(m[2].z*m[3].w - m[2].w*m[3].z) + m[0].z*(m[2].w*m[3].x - m[2].x*m[3].w) + m[0].w*(m[2].x*m[3].z - m[2].z*m[3].x);<br />
inv[1].z = m[0].x*(m[1].w*m[3].z - m[1].z*m[3].w) + m[0].z*(m[1].x*m[3].w - m[1].w*m[3].x) + m[0].w*(m[1].z*m[3].x - m[1].x*m[3].z);<br />
inv[1].w = m[0].x*(m[1].z*m[2].w - m[1].w*m[2].z) + m[0].z*(m[1].w*m[2].x - m[1].x*m[2].w) + m[0].w*(m[1].x*m[2].z - m[1].z*m[2].x);<br />
inv[2].x = m[1].x*(m[2].y*m[3].w - m[2].w*m[3].y) + m[1].y*(m[2].w*m[3].x - m[2].x*m[3].w) + m[1].w*(m[2].x*m[3].y - m[2].y*m[3].x);<br />
inv[2].y = m[0].x*(m[2].w*m[3].y - m[2].y*m[3].w) + m[0].y*(m[2].x*m[3].w - m[2].w*m[3].x) + m[0].w*(m[2].y*m[3].x - m[2].x*m[3].y);<br />
inv[2].z = m[0].x*(m[1].y*m[3].w - m[1].w*m[3].y) + m[0].y*(m[1].w*m[3].x - m[1].x*m[3].w) + m[0].w*(m[1].x*m[3].y - m[1].y*m[3].x);<br />
inv[2].w = m[0].x*(m[1].w*m[2].y - m[1].y*m[2].w) + m[0].y*(m[1].x*m[2].w - m[1].w*m[2].x) + m[0].w*(m[1].y*m[2].x - m[1].x*m[2].y);<br />
inv[3].x = m[1].x*(m[2].z*m[3].y - m[2].y*m[3].z) + m[1].y*(m[2].x*m[3].z - m[2].z*m[3].x) + m[1].z*(m[2].y*m[3].x - m[2].x*m[3].y);<br />
inv[3].y = m[0].x*(m[2].y*m[3].z - m[2].z*m[3].y) + m[0].y*(m[2].z*m[3].x - m[2].x*m[3].z) + m[0].z*(m[2].x*m[3].y - m[2].y*m[3].x);<br />
inv[3].z = m[0].x*(m[1].z*m[3].y - m[1].y*m[3].z) + m[0].y*(m[1].x*m[3].z - m[1].z*m[3].x) + m[0].z*(m[1].y*m[3].x - m[1].x*m[3].y);<br />
inv[3].w = m[0].x*(m[1].y*m[2].z - m[1].z*m[2].y) + m[0].y*(m[1].z*m[2].x - m[1].x*m[2].z) + m[0].z*(m[1].x*m[2].y - m[1].y*m[2].x);<br />
inv /= det;<br />
<br />
return inv;<br />
}<br />
<br />
matrix inverse(float4 m0, float4 m1, float4 m2, float4 m3)<br />
{<br />
return inverse(matrix(m0, m1, m2, m3));<br />
}<br />
<br />
#define MATRIX(cb, idx) matrix(cb[idx], cb[idx+1], cb[idx+2], cb[idx+3])<br />
</syntaxhighlight><br />
<br />
<br />
<br />
<br />
The original version of this came from ''Mike_ar69''.<br />
<syntaxhighlight lang="c"><br />
...<br />
matrix ivp, vp;<br />
ivp = matrix(InstanceConsts[1], InstanceConsts[2], InstanceConsts[3], InstanceConsts[4]);<br />
<br />
// Work out the view-projection matrix from it's inverse:<br />
vp[0].x = ivp[1].y*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[1].z*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[1].w*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y);<br />
vp[0].y = ivp[0].y*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[0].z*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[0].w*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z);<br />
vp[0].z = ivp[0].y*(ivp[1].z*ivp[3].w - ivp[1].w*ivp[3].z) + ivp[0].z*(ivp[1].w*ivp[3].y - ivp[1].y*ivp[3].w) + ivp[0].w*(ivp[1].y*ivp[3].z - ivp[1].z*ivp[3].y);<br />
vp[0].w = ivp[0].y*(ivp[1].w*ivp[2].z - ivp[1].z*ivp[2].w) + ivp[0].z*(ivp[1].y*ivp[2].w - ivp[1].w*ivp[2].y) + ivp[0].w*(ivp[1].z*ivp[2].y - ivp[1].y*ivp[2].z);<br />
vp[1].x = ivp[1].x*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[1].z*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[1].w*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z);<br />
vp[1].y = ivp[0].x*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[0].z*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[0].w*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x);<br />
vp[1].z = ivp[0].x*(ivp[1].w*ivp[3].z - ivp[1].z*ivp[3].w) + ivp[0].z*(ivp[1].x*ivp[3].w - ivp[1].w*ivp[3].x) + ivp[0].w*(ivp[1].z*ivp[3].x - ivp[1].x*ivp[3].z);<br />
vp[1].w = ivp[0].x*(ivp[1].z*ivp[2].w - ivp[1].w*ivp[2].z) + ivp[0].z*(ivp[1].w*ivp[2].x - ivp[1].x*ivp[2].w) + ivp[0].w*(ivp[1].x*ivp[2].z - ivp[1].z*ivp[2].x);<br />
vp[2].x = ivp[1].x*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[1].y*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[1].w*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[2].y = ivp[0].x*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[0].y*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[0].w*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[2].z = ivp[0].x*(ivp[1].y*ivp[3].w - ivp[1].w*ivp[3].y) + ivp[0].y*(ivp[1].w*ivp[3].x - ivp[1].x*ivp[3].w) + ivp[0].w*(ivp[1].x*ivp[3].y - ivp[1].y*ivp[3].x);<br />
vp[2].w = ivp[0].x*(ivp[1].w*ivp[2].y - ivp[1].y*ivp[2].w) + ivp[0].y*(ivp[1].x*ivp[2].w - ivp[1].w*ivp[2].x) + ivp[0].w*(ivp[1].y*ivp[2].x - ivp[1].x*ivp[2].y);<br />
vp[3].x = ivp[1].x*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z) + ivp[1].y*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x) + ivp[1].z*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[3].y = ivp[0].x*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y) + ivp[0].y*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z) + ivp[0].z*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[3].z = ivp[0].x*(ivp[1].z*ivp[3].y - ivp[1].y*ivp[3].z) + ivp[0].y*(ivp[1].x*ivp[3].z - ivp[1].z*ivp[3].x) + ivp[0].z*(ivp[1].y*ivp[3].x - ivp[1].x*ivp[3].y);<br />
vp[3].w = ivp[0].x*(ivp[1].y*ivp[2].z - ivp[1].z*ivp[2].y) + ivp[0].y*(ivp[1].z*ivp[2].x - ivp[1].x*ivp[2].z) + ivp[0].z*(ivp[1].x*ivp[2].y - ivp[1].y*ivp[2].x);<br />
vp /= determinant(ivp);<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM (3Dmigoto ASM) '''''<br />
<br />
This one hasn't been fully tested, but should work. This is created by ''mx-2'' and found on his [https://github.com/mx-2/3d-fix/blob/master/_tools_/inverseMatrix.asm GitHub]<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
//<br />
// inverseMatrix.asm<br />
//<br />
// Matrix inversion with Gauss-Jordan elimination<br />
// algorithm on GPU.<br />
//<br />
// This algorithm uses 128 instructions, from which<br />
// 83 (best case) to 110 (worst case) are executed.<br />
//<br />
// input matrix is in r0-r3<br />
// output will be in r4-r7<br />
// r8, r9 are used as temporary registers<br />
// c200 = (1,0,0,0) is required<br />
//<br />
// r0.x r0.y r0.z r0.w | r4.x, r4.y, r4.z, r4.w<br />
// r1.x r1.y r1.z r1.w | r5.x, r5.y, r5.z, r5.w<br />
// r2.x r2.y r2.z r2.w | r6.x, r6.y, r6.z, r6.w<br />
// r3.x r3.y r3.z r3.w | r7.x, r7.y, r7.z, r7.w<br />
//<br />
// Test:<br />
// SETR r0, 0, 2, 3, 4<br />
// SETR r1, 1, 0, 5, 4<br />
// SETR r2,-1, 2, 3, 4<br />
// SETR r3, 0, 2, 3, 5<br />
//<br />
// Should produce<br />
// r4 = 1.0, 0.0, -1.0, 0.0<br />
// r5 = 1.6, -0.3, -0.3, -0.8<br />
// r6 = 0.6, 0.2, 0.2, -0.8<br />
// r7 = -1.0, 0.0, 0.0, 1.0<br />
//<br />
<br />
// Init registers<br />
def c200, 1, 0, 0, 0<br />
mov r4, c200.xyzw<br />
mov r5, c200.wxyz<br />
mov r6, c200.zwxy<br />
mov r7, c200.yzwx<br />
<br />
// Pivot first column<br />
mov r8, c200<br />
if_eq r0.x, r8.y<br />
if_eq r1.x, r8.y<br />
if_eq r2.x, r8.y<br />
mov r9, r0<br />
mov r0, r3<br />
mov r3, r9<br />
mov r9, r4<br />
mov r4, r7<br />
mov r7, r9<br />
else<br />
mov r9, r0<br />
mov r0, r2<br />
mov r2, r9<br />
mov r9, r4<br />
mov r4, r6<br />
mov r6, r9<br />
endif<br />
else<br />
mov r9, r0<br />
mov r0, r1<br />
mov r1, r9<br />
mov r9, r4<br />
mov r4, r5<br />
mov r5, r9<br />
endif<br />
endif<br />
<br />
// First column<br />
rcp r8.x, r0.x<br />
mul r8.y, r8.x, r1.x<br />
mul r9, r0, r8.y<br />
add r1, r1, -r9<br />
mul r9, r4, r8.y<br />
add r5, r5, -r9<br />
<br />
mul r8.y, r8.x, r2.x<br />
mul r9, r0, r8.y<br />
add r2, r2, -r9<br />
mul r9, r4, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.x<br />
mul r9, r0, r8.y<br />
add r3, r3, -r9<br />
mul r9, r4, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot second column<br />
mov r8, c200<br />
if_eq r1.y, r8.y<br />
if_eq r2.y, r8.y<br />
mov r9, r1<br />
mov r1, r3<br />
mov r3, r9<br />
mov r9, r5<br />
mov r5, r7<br />
mov r7, r9<br />
else<br />
mov r9, r1<br />
mov r1, r2<br />
mov r2, r9<br />
mov r9, r5<br />
mov r5, r6<br />
mov r6, r9<br />
endif<br />
endif<br />
<br />
// Second column<br />
rcp r8.x, r1.y<br />
mul r8.y, r8.x, r2.y<br />
mul r9, r1, r8.y<br />
add r2, r2, -r9<br />
mul r9, r5, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.y<br />
mul r9, r1, r8.y<br />
add r3, r3, -r9<br />
mul r9, r5, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot third column<br />
mov r8, c200<br />
if_eq r2.z, r8.y<br />
mov r9, r2<br />
mov r2, r3<br />
mov r3, r9<br />
mov r9, r6<br />
mov r6, r7<br />
mov r7, r9<br />
endif<br />
<br />
// Third column<br />
rcp r8.x, r2.z<br />
mul r8.y, r8.x, r3.z<br />
mul r9, r2, r8.y<br />
add r3, r3, -r9<br />
mul r9, r6, r8.y<br />
add r7, r7, -r9<br />
<br />
// Normalize r3.w<br />
rcp r8.x, r3.w<br />
mul r3, r3, r8.x<br />
mul r7, r7, r8.x<br />
<br />
// Fourth column<br />
mul r8, r3, r2.w<br />
mul r9, r7, r2.w<br />
add r2, r2, -r8<br />
add r6, r6, -r9<br />
<br />
mul r8, r3, r1.w<br />
mul r9, r7, r1.w<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r3, r0.w<br />
mul r9, r7, r0.w<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r2.z<br />
rcp r8.x, r2.z<br />
mul r2, r2, r8.x<br />
mul r6, r6, r8.x<br />
<br />
// Third column (upper part)<br />
mul r8, r2, r1.z<br />
mul r9, r6, r1.z<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r2, r0.z<br />
mul r9, r6, r0.z<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r1.y<br />
rcp r8.x, r1.y<br />
mul r1, r1, r8.x<br />
mul r5, r5, r8.x<br />
<br />
// Second column (upper part)<br />
mul r8, r1, r0.y<br />
mul r9, r5, r0.y<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize first column<br />
rcp r8.x, r0.x<br />
mul r0, r0, r8.x<br />
mul r4, r4, r8.x<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
Two more variants, both from Helifax. In case those previous ones don't seem quite right.<br />
<br />
''''' HLSL '''''<br />
<br />
<syntaxhighlight lang="c"><br />
//Work out Inverse<br />
//...Variables<br />
float4 a1, a2, a3, a4;<br />
float4 b1, b2, b3, b4;<br />
float det;<br />
//...Original Matrix<br />
a1 = g_invViewProjMatrix._m00_m10_m20_m30;<br />
a2 = g_invViewProjMatrix._m01_m11_m21_m31;<br />
a3 = g_invViewProjMatrix._m02_m12_m22_m32;<br />
a4 = g_invViewProjMatrix._m03_m13_m23_m33;<br />
//...Determinant<br />
det = a1.x*(a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y));<br />
det += a1.y*(a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.z) + a2.w*(a3.z*a4.x - a3.x*a4.z));<br />
det += a1.z*(a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x));<br />
det += a1.w*(a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y));<br />
//...Inverse Matrix Elements<br />
b1.x = a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y);<br />
b1.y = a1.y*(a3.w*a4.z - a3.z*a4.w) + a1.z*(a3.y*a4.w - a3.w*a4.y) + a1.w*(a3.z*a4.y - a3.y*a4.z);<br />
b1.z = a1.y*(a2.z*a4.w - a2.w*a4.z) + a1.z*(a2.w*a4.y - a2.y*a4.w) + a1.w*(a2.y*a4.z - a2.z*a4.y);<br />
b1.w = a1.y*(a2.w*a3.z - a2.z*a3.w) + a1.z*(a2.y*a3.w - a2.w*a3.y) + a1.w*(a2.z*a3.y - a2.y*a3.z);<br />
b2.x = a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.x) + a2.w*(a3.z*a4.x - a3.x*a4.z);<br />
b2.y = a1.x*(a3.z*a4.w - a3.w*a4.z) + a1.z*(a3.w*a4.x - a3.x*a4.w) + a1.w*(a3.x*a4.z - a3.z*a4.x);<br />
b2.z = a1.x*(a2.w*a4.z - a2.z*a4.w) + a1.z*(a2.x*a4.w - a2.w*a4.x) + a1.w*(a2.z*a4.x - a2.x*a4.z);<br />
b2.w = a1.x*(a2.z*a3.w - a2.w*a3.z) + a1.z*(a2.w*a3.x - a2.x*a3.w) + a1.w*(a2.x*a3.z - a2.z*a3.x);<br />
b3.x = a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x);<br />
b3.y = a1.x*(a3.w*a4.y - a3.y*a4.w) + a1.y*(a3.x*a4.w - a3.w*a4.x) + a1.w*(a3.y*a4.x - a3.x*a4.y);<br />
b3.z = a1.x*(a2.y*a4.w - a2.w*a4.y) + a1.y*(a2.w*a4.x - a2.x*a4.w) + a1.w*(a2.x*a4.y - a2.y*a4.x);<br />
b3.w = a1.x*(a2.w*a3.y - a2.y*a3.w) + a1.y*(a2.x*a3.w - a2.w*a3.x) + a1.w*(a2.y*a3.x - a2.x*a3.y);<br />
b4.x = a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y);<br />
b4.y = a1.x*(a3.y*a4.z - a3.z*a4.y) + a1.y*(a3.z*a4.x - a3.x*a4.z) + a1.z*(a3.x*a4.y - a3.y*a4.x);<br />
b4.z = a1.x*(a2.z*a4.y - a2.y*a4.z) + a1.y*(a2.x*a4.z - a2.z*a4.x) + a1.z*(a2.y*a4.x - a2.x*a4.y);<br />
b4.w = a1.x*(a2.y*a3.z - a2.z*a3.y) + a1.y*(a2.z*a3.x - a2.x*a3.z) + a1.z*(a2.x*a3.y - a2.y*a3.x);<br />
b1.xyzw /= det;<br />
b2.xyzw /= det;<br />
b3.xyzw /= det;<br />
b4.xyzw /= det;<br />
//End Inverse<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM '''''<br />
<br />
Generated from the HLSL, using fxc.<br />
<syntaxhighlight lang="c"><br />
// Declare how many registers ww use<br />
// The code uses registers from r38 to r53.<br />
dcl_temps 60<br />
<br />
// 3DMigoto StereoParams:<br />
dcl_resource_texture1d (float,float,float,float) t120<br />
dcl_resource_texture2d (float,float,float,float) t125<br />
ld_indexable(texture1d)(float,float,float,float) r41.xyzw, l(0, 0, 0, 0), t120.xyzw<br />
ld_indexable(texture2d)(float,float,float,float) r40.xyzw, l(0, 0, 0, 0), t125.xyzw<br />
<br />
// Inverse<br />
// cb0[0], etc is the inverseMatrix<br />
mov r0.xyzw, cb0[0].xyzw<br />
mov r1.xyzw, cb0[1].xyzw<br />
mov r2.xyzw, cb0[2].xyzw<br />
mov r3.xyzw, cb0[3].xyzw<br />
mul r4.x, r2.z, r3.w<br />
mul r4.y, r2.w, r3.z<br />
mov r4.y, -r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r1.y, r4.x<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.z<br />
mul r4.z, r2.z, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r0.x, r4.x<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.y<br />
mul r4.z, r2.y, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.y, r4.y<br />
mul r4.z, r2.w, r3.y<br />
mul r4.w, r2.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.z<br />
mul r4.w, r2.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r5.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r2.y, r3.w<br />
mul r4.w, r2.w, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.y<br />
mul r4.w, r2.y, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.y, r4.z, r4.y<br />
mul r4.y, r1.z, r3.w<br />
mul r4.z, r1.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.w, r3.y<br />
mul r4.w, r1.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.y, r3.z<br />
mul r4.w, r1.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.z, r4.z, r4.y<br />
mul r4.y, r1.w, r2.z<br />
mul r4.z, r1.z, r2.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.y, r2.w<br />
mul r4.w, r1.w, r2.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r2.y<br />
mul r4.w, r1.y, r2.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.w, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r6.x, r4.z, r4.y<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.y, r4.z, r4.y<br />
mul r4.y, r1.w, r3.z<br />
mul r4.z, r1.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.x, r3.w<br />
mul r4.w, r1.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r3.x<br />
mul r4.w, r1.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.z, r4.z, r4.y<br />
mul r4.y, r1.z, r2.w<br />
mul r4.z, r1.w, r2.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r2.x<br />
mul r4.w, r1.x, r2.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.x, r2.z<br />
mul r4.w, r1.z, r2.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.w, r4.z, r4.y<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r7.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r7.y, r4.z, r4.y<br />
mul r4.y, r1.y, r3.w<br />
mul r4.z, r1.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r3.x<br />
mul r3.w, r1.x, r3.w<br />
mov r3.w, -r3.w<br />
add r3.w, r3.w, r4.z<br />
mul r3.w, r0.y, r3.w<br />
add r3.w, r3.w, r4.y<br />
mul r4.y, r1.x, r3.y<br />
mul r4.z, r1.y, r3.x<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r7.z, r3.w, r4.y<br />
mul r3.w, r1.w, r2.y<br />
mul r4.y, r1.y, r2.w<br />
mov r4.y, -r4.y<br />
add r3.w, r3.w, r4.y<br />
mul r3.w, r0.x, r3.w<br />
mul r2.w, r1.x, r2.w<br />
mul r1.w, r1.w, r2.x<br />
mov r1.w, -r1.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r1.w, r1.w, r3.w<br />
mul r2.w, r1.y, r2.x<br />
mul r3.w, r1.x, r2.y<br />
mov r3.w, -r3.w<br />
add r2.w, r2.w, r3.w<br />
mul r0.w, r0.w, r2.w<br />
add r7.w, r0.w, r1.w<br />
mul r0.w, r2.z, r3.y<br />
mul r1.w, r2.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r1.x<br />
mul r1.w, r2.x, r3.z<br />
mul r2.w, r2.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.y<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.y, r3.x<br />
mul r2.w, r2.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.z<br />
add r8.x, r0.w, r1.w<br />
mul r0.w, r2.y, r3.z<br />
mul r1.w, r2.z, r3.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r2.z, r3.x<br />
mul r2.w, r2.x, r3.z<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.x, r3.y<br />
mul r2.w, r2.y, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.y, r0.w, r1.w<br />
mul r0.w, r1.z, r3.y<br />
mul r1.w, r1.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r1.x, r3.z<br />
mul r2.w, r1.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r1.y, r3.x<br />
mul r2.w, r1.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.z, r0.w, r1.w<br />
mul r0.w, r1.y, r2.z<br />
mul r1.w, r1.z, r2.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.x, r0.w, r0.x<br />
mul r0.w, r1.z, r2.x<br />
mul r1.z, r1.x, r2.z<br />
mov r1.z, -r1.z<br />
add r0.w, r0.w, r1.z<br />
mul r0.y, r0.w, r0.y<br />
add r0.x, r0.y, r0.x<br />
mul r0.y, r1.x, r2.y<br />
mul r0.w, r1.y, r2.x<br />
mov r0.w, -r0.w<br />
add r0.y, r0.w, r0.y<br />
mul r0.y, r0.y, r0.z<br />
add r8.w, r0.y, r0.x<br />
div r0.xyzw, r5.xyzw, r4.xxxx<br />
div r1.xyzw, r6.xyzw, r4.xxxx<br />
div r2.xyzw, r7.xyzw, r4.xxxx<br />
div r3.xyzw, r8.xyzw, r4.xxxx<br />
<br />
// Store results for later use as r0-r4 are most <br />
// likely to be used by the default shader code.<br />
// r50 equivalent of matrix._m00_m01_m02_m03<br />
// r51 equivalent of matrix._m10_m11_m12_m13<br />
// r52 equivalent of matrix._m20_m21_m22_m23<br />
// r53 equivalent of matrix._m30_m31_m32_m33<br />
<br />
mov r50.xyzw, r0.xyzw <br />
mov r51.xyzw, r1.xyzw <br />
mov r52.xyzw, r2.xyzw <br />
mov r53.xyzw, r3.xyzw<br />
</syntaxhighlight></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Driver_Profile_SettingsDriver Profile Settings2017-03-21T12:33:41Z<p>Bo3b admin: </p>
<hr />
<div>This page is a work in progress - feel free to expand it with extra knowledge, before & after screenshots, etc.<br />
<br />
<br />
== Tools ==<br />
<br />
The recommended tool for working with profiles is [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/2.1.2.12/artifacts NVIDIA Profile Inspector 2.1.2.12] or later due to its ability to decrypt internal settings.<br />
<br />
[https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/artifacts Latest continuous integration build]<br />
<br />
[https://github.com/Orbmu2k/nvidiaProfileInspector Source code]<br />
<br />
[http://forums.guru3d.com/showthread.php?t=403676 Forum thread] (note that the download linked from here does not yet support decrypting internal settings)<br />
<br />
3DMigoto 1.2.50 now has built in support for working with driver profiles, including decrypting and logging the current profile in d3d11_log.txt, and making any changes necessary when the game is launched.<br />
<br />
==== Obsolete tools: ====<br />
<br />
NVIDIA Profile Inspector 2.1.2.6 or older<br />
<br />
[http://orbmu2k.de/tools/nvidia-inspector-tool NVIDIA Inspector] 1.9.7.5 or older ([http://www.guru3d.com/files-details/nvidia-inspector-download.html English mirror])<br />
<br />
[http://nvidia.custhelp.com/app/answers/detail/a_id/2625/kw/Profile GeForce 3D Profile Manager]<br />
<br />
== NVIDIA Inspector Custom Stereo Settings Names ==<br />
<br />
NVIDIA Inspector (old versions): Download this [https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/CustomSettingNames_en-EN.xml CustomSettingNames_en-EN.xml] file to replace the one from NVIDIA Inspector, which will add all the settings listed on this page to the Stereo category.<br />
<br />
NVIDIA Profile Inspector: This program automatically decodes most setting names (you may need to select "Show unknown settings from NVIDIA predefined profiles" to see them) '''Edit: This no longer works as recent drivers have removed the DLLs that the tool relied on to find the stereo settings names'''. There are some exceptions - most notably the all important StereoProfile setting is missing. You can use the XML file linked above, but name it 'CustomSettingNames.xml' (i.e. remove the '_en-EN').<br />
<br />
== Important note about encoding of "Internal" Settings ==<br />
<br />
Some profiles are shipped with the internal settings flag set on certain settings. These show up with "InternalSettingFlag=V0" in Geforce Profile Manager, but there is no easy way to distinguish them in NVIDIA Inspector. These settings are encrypted and the values read out with these tools will not match any of the documentation here. Further, if they are written back with NVIDIA Inspector, the flag will be cleared and they will become corrupt. Geforce Profile Manager allows them to be written back with the flag intact avoiding the corruption, but still does not help understand them.<br />
<br />
A script to decipher these values from Geforce Profile Manager is available: [https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/__profiles__/sanitise_nv_profiles.py here]<br />
<br />
NVIDIA Profile Inspector 2.1.2.7 or later can correctly decode these, and is now the recommended tool for working with driver profiles. [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/2.1.2.7/artifacts Version 2.1.2.7] [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/artifacts Latest build]<br />
<br />
3DMigoto 1.2.50 and later includes support for logging and updating driver profiles, and correctly handles encrypted settings. The undocumented option [Logging] dump_all_profiles=1 can be used to have it decrypt and log every profile instead of just the ones relevant to the game being run.<br />
<br />
== Notes on settings with multiple IDs ==<br />
<br />
Some settings on this page are listed with two or three IDs. This is not fully understood yet. Generally you should stick to the first value listed, but if a profile also lists the second or third value in this list it might be used in place of the first (however a given profile will only use a specific ID out of the second or third in the list).<br />
<br />
The following settings have multiple IDs:<br />
{| class="wikitable"<br />
! Name || Primary ID || 1st Alternate ID || 2nd Alternate ID<br />
|-<br />
| StereoConvergence || 0x708DB8C5 || 0x7077BACE || 0x7084807E<br />
|-<br />
| LaserSight || 0x7058B6E1 || 0x7031A2E7 || 0x7045B752<br />
|-<br />
| FrustumAdjustMode || 0x70A1411A || 0x70ED1DA7 || 0x70F475A0<br />
|-<br />
| StereoTextureEnable || 0x70EDB381 || 0x70E1518C || 0x70C0125E<br />
|-<br />
| Rhwinf || 0x706E1913 || 0x70CC286A || 0x70A3FEE6<br />
|-<br />
| Rhwscr || 0x70A4995C || 0x7030B071 || 0x70B57ED1<br />
|-<br />
| InGameLaserSight || 0x7064F0C2 || 0x70DD2585 || 0x70E7ADAD<br />
|-<br />
| StereoCutoffDepthNear || 0x7050E011 || 0x704EF483 || 0x7031DE06<br />
|-<br />
| StereoCutoff || 0x709A1DDF || 0x704FCF5C || 0x7053569A<br />
|-<br />
| DX10VSCBNumber || 0x70F8E408 || || 0x70F64A32<br />
|}<br />
<br />
== StereoProfile (AKA The Mystery Stereo Setting) 0x701EB457 ==<br />
<br />
This setting is known to be very important to stereo profiles. We now know it's official name is STEREO_STEREOPROFILE, and will be referred to as "StereoProfile" in future releases of NVIDIA Profile Inspector.<br />
<br />
<u> Observations </u><br />
<br />
- The mere existance of this setting on a DX9 profile will enable Stereo in windowed mode, regardless of the value.<br />
<br />
- This setting is required to enable a lot of stereo related code in the driver.<br />
<br />
- Certain other stereo settings (e.g. StereoTextureEnable) may be ignored without this setting.<br />
<br />
- If this is missing in a profile, attempting to save the profile with Ctrl+F7 will not work, and will restore the default convergence instead. It has been noted that adding this setting to the base profile can solve this globally, but may cause the monitor to switch to stereo mode when using certain 2D applications (e.g. VS2015), which may be undesirable in some cases.<br />
<br />
<u>Bit Definitions</u><br />
<br />
{| class="wikitable"<br />
|Missing || Not a stereo profile (Certain things will not work, including saving the profile via Ctrl+F7)<br />
|-<br />
|0x00000000 || Not a stereo profile (Certain things will not work - need to confirm exactly what differs compared to missing)<br />
|-<br />
|0x00000001 || Stereo profile (everything will work)<br />
|-<br />
|0x2241AB21 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
== Notable Settings ==<br />
<br />
=== StereoTextureEnable (0x70edb381 / 0x70e1518c / 0x70c0125e) ===<br />
<br />
- Controls the heuristics that determines which render targets & Z buffers are stereoised and which are not.<br />
<br />
- Controls the heuristics that determines in what situations the stereo correction formula will be applied.<br />
<br />
- Some bits are used for specific games.<br />
<br />
<u> Observations </u><br />
<br />
- Setting this to all F's will turn a game into mono, suggesting that some high bits might filter out some render targets, rather than enabling them.<br />
<br />
<u> Bit Definitions </u><br />
<br />
Contact DarkStarSword or Bo3b privately for a complete list of bit definitions for this setting.<br />
<br />
Chiri determined a number of these (see [https://forums.geforce.com/default/topic/506784/3d-vision/l-a-noire-official-3d-vision-thread/post/3613599/#3613599 this post])<br />
<br />
{| class="wikitable"<br />
|0x00000001 || [ET] = Stereoize render target textures which are of size or exceeding the size of the backbuffer (and are not square).<br />
|-<br />
|0x00000002 || [ESMT] = Stereoize all non square render target textures smaller then backbuffer.<br />
|-<br />
|0x00000004 || [ESQT] = Stereoize sqare render target textures.<br />
|-<br />
|0x00000008 || [DBBST] = ???<br />
|-<br />
|0x00000010 || [DBBS] = ???<br />
|}<br />
<br />
<u> Known Values </u><br />
<br />
This only lists known values of games using the high bits (0x10000 and above), since the meaning of the low bits are all known. These high bits are believed to be for game specific quirks:<br />
<br />
{| class="wikitable"<br />
|0x0001xxxx || MX vs. ATV Reflex, Prince of Persia - The Forgotten Sands, Prince of Persia(gameinterpreters_rd.exe)<br />
|-<br />
|0x0002xxxx || Call of Duty: Modern Warfare 2, EverQuest II, F.E.A.R. 2: Project Origin, F.E.A.R. 2: Project Origin(Demo), Lost Planet: Colonies Edition, Serious Sam II, Vizerra Viewer<br />
|-<br />
|0x0003xxxx || Time of Shadows<br />
|-<br />
|0x0004xxxx || BioShock 2<br />
|-<br />
|0x0010xxxx || Kane & Lynch 2: Dog days, Need for Speed: World, R.U.S.E., Super Street Fighter IV<br />
|-<br />
|0x0020xxxx || Tom Clancy's H.A.W.X. 2<br />
|-<br />
|0x00c0xxxx || Battlefield: Bad Company 2, BFBC2Game_dx10<br />
|-<br />
|0x0100xxxx || AngleLib<br />
|-<br />
|0x0200xxxx || Ashes of the Singularity, F1 2015 DX12, Fable Legends, Sid Meier's Civilization VI<br />
|-<br />
|0x0400xxxx || Rise of the Tomb Raider<br />
|-<br />
|0x0800xxxx || Gears of War 4<br />
|-<br />
|0x2000xxxx || World of Tanks<br />
|-<br />
|0x8000xxxx || Need for Speed: Shift, Resident Evil 5<br />
|}<br />
<br />
<br />
<u> Default Value </u><br />
<br />
If not specified in a profile, the driver appears to use 0x23 as the default.<br />
<br />
=== StereoUseMatrix (0x70e34a78) ===<br />
<br />
- Able to automatically fix halo type issues in many games<br />
<br />
<u> Known Values </u><br />
{| class="wikitable"<br />
|0x00000000 || Disabled (only vertex output position will be adjusted by the driver)<br />
|-<br />
|0x00000001 || Enabled (other texcoord outputs based on the position will be adjusted by the driver)<br />
|-<br />
|0x1945B570 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
=== StereoFlagsDX10 (0x702442fc) ===<br />
<br />
- Able to resolve mono depth buffer issues in DirectX 11 games, such as Far Cry 4 and Ryse: Son of Rome.<br />
<br />
<u> Bit Definitions </u><br />
<br />
{| class="wikitable"<br />
|0x00008000 || STEREO_COMPUTE_SAME_RESOURCES_AS_GRAPHICS - "stereorize the same resources as for graphics (do not mark all UAVs as stereorizable)"<br />
|-<br />
|0x00004000 || STEREO_COMPUTE_ENABLE - enables running compute shaders once for each eye. Fixes mono depth buffer issue in Far Cry 4 (SLI users can alternatively resolve this with custom SLI compatibility bits), Witcher 3, and other games.<br />
|-<br />
|0x00000024 || One of these two bits negated the separation value reported to 3Dmigoto in Far Cry 4<br />
|}<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
|0x00000001 || Far Cry 2 (DX10 version)<br />
|-<br />
|0x00000004 || Crysis, Civilisation V<br />
|-<br />
|0x00000008 || 3DMark Vantage<br />
|-<br />
|0x000000E0 || Resident Evil 5<br />
|-<br />
|0x00000200 || Crysis 3, Battlefield 3<br />
|-<br />
|0x00000400 || Batman: Arkham City, Metro 2033<br />
|-<br />
|0x00001000 || Passion Leads Army Benchmark<br />
|-<br />
|0x00002000 || Titanfall<br />
|-<br />
|0x00002004 || Crysis Warhead<br />
|-<br />
|0x00004000 || Max Payne 3, Far Cry 4 (352.86+), The Witcher 3, Batman: Arkham Knight, The Park<br />
|-<br />
|0x00034000 || Metro: Last Light<br />
|-<br />
|0x1C22FE24 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
=== StereoCutoff (0x709a1ddf / 0x704fcf5c / 0x7053569a) ===<br />
<br />
Present in almost all Stereo profiles, but meaning unknown. My complete guess is that it may be related to driver heuristics to decide when the stereo correction formula is applied (e.g. for UI elements)?<br />
<br />
<u> Possible Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000000 || Unknown<br />
|-<br />
| 0x00000001 || Default<br />
|-<br />
| 0x00000002 || Use StereoCutoffDepthNear<br />
|-<br />
| 0x00000004 || Use StereoCutoffDepthFar<br />
|-<br />
| 0x00000008 || Unknown<br />
|}<br />
<br />
Other values are invalid.<br />
<br />
<u> Observations </u><br />
<br />
- Setting this to 0x00000000 broke shadows in Miasmata<br />
<br />
<u> Observations from D-Man11 (see [https://forums.geforce.com/default/topic/801771/3d-vision/tomb-raider-triology/post/4785703/#4785703 this post]) </u><br />
<br />
Note: the values below have been edited from the original post to use the setting names and their decrypted values.<br />
<br />
Interesting thing is, if you apply the TR: Underworld profile, the UI text doesn't split, just the background.<br />
<br />
Messing around with Legend, I found that StereoCutoffDepthNear = 25.0 and Setting StereoCutoff = 0x00000002 were the responsible flags from the Anniversary profile to stop the UI from splitting. Either by itself would not do anything.<br />
<br />
If I just added them to the existing Legend profile, it wouldn't work, something was stopping it. (DarkStarSword's note - this may have been because they were encrypted. This experiment should be repeated)<br />
<br />
If I deleted everything from the Legend profile, excluding StereoProfile = 0x00000001 (which is needed, if you remove it, the profile defaults to generic) and added the 2 flags from Anniversary, the UI would not split.<br />
<br />
StereoCutoffDepthNear = 0x41c80000 (25.0) // is exclusive to TR: Anniversary<br />
StereoCutoff = 0x00000002 // is found in 26 other profiles<br />
StereoProfile = 0x00000001 // is found in 2110 profiles<br />
<br />
So the above 3 settings need to be present and there must not be any current settings in the profile to block the effect.<br />
<br />
I did not bother to find the offending setting in the original Legend profile.<br />
<br />
=== StereoCutoffDepthNear (0x7050e011 / 0x704ef483 / 0x7031de06) ===<br />
<br />
Floating point value used when StereoCutoff is set to 2 to set a threshold depth to stop the UI splitting when it is rendered nearer than this value (someone confirm if that is entirely correct and if this can affect other things besides the UI).<br />
<br />
=== StereoCutoffDepthFar (0x70add220) ===<br />
<br />
Floating point value used when StereoCutoff is set to 1 to set a threshold depth to stop the UI splitting when it is rendered further away than this value (someone confirm if that is entirely correct and if this can affect other things besides the UI).<br />
<br />
=== GameSpecific0 (0x702244b7) ===<br />
<br />
For a DX9 game, this defines which constant register the driver injects the stereo settings in with x = -separation*convergence, y = separation (making the stereo correction formula pos.x += c255.x + c255.y * pos.w). Only vertex shaders that the driver modifies will have anything injected at all. The default is c255, and StereoProfile must be set for this setting to have any effect. Note that unlike the equivelent options for DX11 games, merely accessing this register will *not* neutralise the driver's stereo correction.<br />
<br />
More info: https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4786821/#4786821<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
|19 || MLB2K10<br />
|-<br />
|25 || NBA 2K9<br />
|-<br />
|28 || MLB 2K12, Pro Baseball 2K, NBA 2K12, NBA 2K13<br />
|-<br />
|198 || Alaska, Diablo III<br />
|-<br />
|236 || World Of Warcraft (but note that this profile may be outdated from the old DX9 version)<br />
|-<br />
|248 || Rogue Warrior<br />
|-<br />
|254 || Mafia II, Serious Sam II<br />
|}<br />
<br />
=== DX10VSCBNumber (0x70f8e408 / 0x70f64a32) ===<br />
For a DX10/11 game, this defines which constant buffer the driver uses to inject the stereo parameters into vertex shaders. The first float in the buffer is -separation*convergence, the second is separation, the third seems to be unused and the fourth indicates that 3D Vision is enabled. The default value is cb12. Note that in contrast to the equivelent DX9 option, merely declaring this constant buffer in a shader will disable the driver's built in stereo correction for that shader (for a HLSL shader the buffer must be accessed and the result used in a meaningful way otherwise the compiler will optimise out the declaration).<br />
<br />
More info: https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4786821/#4786821<br />
<br />
Note that constant buffer 14 is reserved for "internal use" and not normally accessible through HLSL (it is defined in shader model 4/5 and declaring it in assembly proves that it does exist and can be used for this purpose, but it is not clear if that might ever interfere with anything else).<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 6 || Metro 2033, Middle-Earth: Shadow of Mordor<br />
|-<br />
| 8 || Assassin's Creed, Fallout 4, Just Cause 3<br />
|-<br />
| 9 || The Witcher 3<br />
|-<br />
| 13 || Mirror's Edge: Catalyst<br />
|-<br />
| 14 || Assassin's Creed: Syndicate, Assassin's Creed: Unity, Dark Souls III, Dead Rising 4, F1 2015 DX12, Grand Theft Auto V, Homefront, Homefront(HOMEFRONT_DX10.exe), Homefront: The Revolution, Rise of the Tomb Raider<br />
|}<br />
<br />
=== DX10DSCBNumber (0x70092d4a) ===<br />
As above, but for tessellation domain shaders.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 8 || Fallout 4, Just Cause 3, Middle-Earth: Shadow of Mordor<br />
|-<br />
| 9 || The Witcher 3<br />
|-<br />
| 13 || Mirror's Edge: Catalyst<br />
|-<br />
| 14 || Assassin's Creed: Syndicate, Assassin's Creed: Unity, Dark Souls III, Dead Rising 4, F1 2015 DX12, Homefront: The Revolution, Rise of the Tomb Raider<br />
|}<br />
<br />
<br />
== More Settings ==<br />
<br />
=== StereoConvergence (0x708db8c5 / 0x7077bace / 0x7084807e) ===<br />
Stores the convergence value of a profile as a floating point value.<br />
<br />
Default Value: 4.0<br />
<br />
=== Comments (0x704d456e) - text ===<br />
Stores the comments displayed in the green text by the driver.<br />
<br />
<br />
=== Developer_Issues (0x704f5928) - text ===<br />
Alternate setting for the comments displayed in the green text by the driver.<br />
<br />
<br />
=== StereoMemoEnabled (0x707f4b45) ===<br />
{| class="wikitable"<br />
| 0x00000000 || Green text disabled<br />
|-<br />
| 0x00000001 || Green text enabled<br />
|}<br />
<br />
<br />
=== Compat (0x7051e5f5) - text ===<br />
<br />
Selects the 3D Vision rating in the green text:<br />
<br />
"0": "3D Vision Ready"<br />
<br />
"1": "Excellent"<br />
<br />
"2": "Good"<br />
<br />
"3": "Fair"<br />
<br />
"4": "Not Recommended"<br />
<br />
"5": "Not Recommended"<br />
<br />
Other observed values: "-1", "101", "102"<br />
<br />
Default value? (crashes): "1000"<br />
<br />
=== PF_Issues (0x704cde5a) - text ===<br />
Comma separated list of letters corresponding to the following issues listed in the green text:<br />
<br />
A: "Incorrect 3D object placement"<br />
<br />
B: "Text/Objects are small and difficult to use"<br />
<br />
C: "Objects clipped at sides of monitor"<br />
<br />
D: "Incorrect clipping of subviews"<br />
<br />
E: "Mixed 2D and 3D objects in Pop-up or HUD"<br />
<br />
F: "Gunsight or Pointer is 2D object"<br />
<br />
G: "Issues with setup screens with stereo on"<br />
<br />
H: "Text highlight for 3D objects is at incorrect depth"<br />
<br />
I: "Bright colors on dark background produce ghosting"<br />
<br />
J: "Excessive use of 2D makes stereo look flat"<br />
<br />
K: Nothing (any more?), but a lot of profiles still mention this<br />
<br />
=== StereoDefaultOn (0x70ab30a7) ===<br />
Defines whether stereo is enabled automatically when the game is launched, or must be manually enabled with Ctrl+T. Useful to set to 0 if having stereo enabled when launching the game breaks something but works when enabled later.<br />
<br />
=== FrustumAdjustMode (0x70a1411a / 0x70ed1da7 / 0x70f475a0) ===<br />
Frustum adjust mode normally adjusted with Ctrl+F11<br />
<br />
{| class="wikitable"<br />
| 0 || No adjustment<br />
|-<br />
| 1 || Stretch<br />
|-<br />
| 2 || Crop<br />
|}<br />
<br />
<br />
== Compatibility Mode Settings ==<br />
<br />
Helifax created a guide with more information about these settings: [https://forums.geforce.com/default/topic/791450/3d-vision/guide-how-to-enable-and-tweak-3d-compatibility-mode-in-any-dx11-game/ Guide: How to Enable and TWEAK 3D Compatibility Mode in any DX11 Game]<br />
<br />
=== 2DDHUDSettings (0x709adada) ===<br />
Controls the compatibility mode settings - overall 3D strength, heuristics to pin the HUD at screen depth, rating.<br />
<br />
<u> Observations from Losti </u><br />
<br />
The below post has been decrypted. The original post is [https://forums.geforce.com/default/topic/791450/3d-vision/guide-how-to-enable-and-tweak-3d-compatibility-mode-in-any-dx11-game/post/4377990/#4377990 here].<br />
<br />
So i have did some investigations with the nvidia used values and i discovered that:<br />
<br />
<u>'''(For Dragon Age: Inquisition)'''</u><br />
<br />
-----------------------<br />
{| class=wikitable<br />
| 0x10000002 || high depth UI and world<br />
|-<br />
| 0x1000000a || high depth UI and world<br />
|-<br />
| 0x1000001a || high depth UI and world<br />
|-<br />
| 0x20000002 || high depth UI and world<br />
|-<br />
| 0x2000000a || high depth UI and world<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x10000015 || no Depth, UI only right eye<br />
|-<br />
| 0x10000102 || low depth UI and world<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x20000006 || UI @ screen depth world high depth<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x51000002 || Game will not have CM<br />
|-<br />
| 0x11000006 || Game will not have CM<br />
|-<br />
| 0x11000002 || Game will not have CM<br />
|-<br />
| 0x41000002 || Game will not have CM<br />
|-<br />
| 0x21000006 || Game will not have CM<br />
|-<br />
| 0x21000002 || Game will not have CM<br />
|}<br />
<br />
own tests:<br />
{| class=wikitable<br />
| 0x20000006 || UI @ screen dempth world high deph<br />
|-<br />
| 0x20000007 || high depth UI and world<br />
|-<br />
| 0x10000036 || UI @ screen depth world high deph<br />
|-<br />
| 0x10000106 || UI @ screen depth world very-LOW deph || EXCELLENT RATING-TEXT<br />
|-<br />
| 0x20000106 || UI @ screen depth world very-LOW deph || GOOD RATING-TEXT<br />
|-<br />
| 0x20000306 || application unknown, no CM<br />
|-<br />
| 0x10000306 || very low Depth, UI only right eye<br />
|-<br />
| 0x10000606 || UI @ screen depth world high deph<br />
|-<br />
| 0x10000706 || very low Depth, UI only right eye<br />
|-<br />
| 0x10000007 || UI @ screen depth world high deph, UI only rigth eye<br />
|-<br />
| 0x10000001 || all is 2D<br />
|-<br />
| 0x10000000 || all is 2D, ALT+TAB=crash<br />
|-<br />
| 0x10000003 || crash<br />
|-<br />
| 0x1000000d || all is 2D, UI only right eye<br />
|-<br />
| 0x1000000c || all is 2D, UI only right eye<br />
|}<br />
<br />
<br />
i think the use of the numbers at the begining (0x20 and 0x10 is fot he GOD or EXCELLENT rating text display)<br />
<br />
'''006''' at the end will give me UI at screen-depth and a 3D world.<br />
<br />
'''002''' at the end will give me UI and a 3D world.<br />
<br />
=== 2DDConvergence (0x709adadb) ===<br />
As the name implies, this is the convergence setting when in compatibility mode.<br />
<br />
=== Disable2DD (0x709adadd) ===<br />
User setting to disable compatibility mode, usually set via hotkey.<br />
{| class=wikitable<br />
| 0x00000000 || Compatibility mode enabled (if supported)<br />
|-<br />
| 0x00000001 || Compatibility mode disabled via Ctrl+Alt+F11<br />
|}<br />
<br />
=== 2DD_Notes (0x709adadc) - text ===<br />
Notes displayed when compatibility mode is enabled<br />
<br />
<br />
== VR Direct Settings ==<br />
<br />
These settings have appeared in recent drivers and are believed to be related to VR Direct:<br />
<br />
=== StereoVRConvergenceBias (0x708db8c6) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00001185 || Batman: Arkham Origins<br />
|-<br />
| 0x0000130b || Devil May Cry 4<br />
|-<br />
| 0x00001a24 || Fable: The Lost Chapters<br />
|-<br />
| 0x00001cdd || Dirt 3<br />
|-<br />
| 0x00002e6b || Portal 2<br />
|-<br />
| 0x0000377c || Nvidia Stereo Test App<br />
|-<br />
| 0x00003c0f || Oil Rush<br />
|-<br />
| 0x0000849d || Serious Sam III<br />
|-<br />
| 0x0000a1a7 || Batman: Arkham City<br />
|-<br />
| 0x0000cd04 || Half-Life 2<br />
|}<br />
<br />
=== StereoVRRefreshRateOverride (0x708db8c8) ===<br />
=== StereoVRVsync (0x708db8c9) ===<br />
<br />
<br />
=== 0x709d3ad2 === <br />
Starting with driver branch R378, VR and 3D Vision are mutually exclusive, and 3D Vision is disabled when VR runtimes are detected.<br />
{| class=wikitable<br />
| 0x00000008 || disables mutual exclusion lock for VR runtimes and 3D Vision<br />
|}<br />
<br />
<br />
== Laser Sight Settings ==<br />
<br />
TsaebehT created a guide with more information about these settings: [https://forums.geforce.com/default/topic/813727/guide-correcting-off-centering-lasersight/ Guide: Correcting/Off-Centering LaserSight]<br />
<br />
<br />
=== LaserSightEnabled (0x7054837a) ===<br />
{| class="wikitable"<br />
| 0x00000000 || Laser sight disabled<br />
|-<br />
| 0x00000001 || Laser sight enabled<br />
|}<br />
<br />
<br />
=== LaserXAdjust (0x7057e831) ===<br />
Horizontal adjustment encoded as a hex float between 0.0 (left) and 2.0 (right). Default: 1.0 (center)<br />
<br />
<br />
=== LaserYAdjust (0x70225308) ===<br />
Horizontal adjustment encoded as a hex float between 0.0 (top) and 2.0 (bottom). Default: 1.0 (center)<br />
<br />
<br />
=== LaserZAdjust (0x7014fca2) ===<br />
{| class="wikitable"<br />
| 0x3f800000 || Enables dynamic laser sight depth<br />
|-<br />
| other || Laser sight is either at screen depth or infinity<br />
|}<br />
<br />
=== LaserSightProperty (0x7032243a) ===<br />
Governs the laser sight opacity<br />
<br />
<br />
=== LaserSightTrigger (0x70031b88) ===<br />
<u> Known Values </u><br />
{| class="wikitable"<br />
| 0x00000002 || Gears of War<br />
|}<br />
<br />
=== InGameLaserSight (0x7064f0c2 / 0x70dd2585 / 0x70e7adad) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000000 || Call of Duty: Modern Warfare 2, Call of Duty: Modern Warfare 3, Call of Duty: World at War, Crysis Warhead, Crysis, Divinity 2, Frontlines: Fuel of War, Medal of Honor: Airborne, Stranglehold, Tom Clancy's Rainbow Six: Vegas 2<br />
|-<br />
| 0x00000001 || BlackSite: Area 51, Delta Force: Black Hawk Down, Gears of War, Hellgate: London DX10, Hellgate: London, Kane & Lynch: Dead man, Postal 3, Unreal Tournament 2004<br />
|-<br />
| 0x00000005 || Code of Honor 2, Default.Archcfg, Shell Shock 2<br />
|-<br />
| 0x00000009 || Battlestrike/Armed Forces Series, Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Ghosts, Left 4 Dead 2, Left 4 Dead, Medal of Honor, S.T.A.L.K.E.R.: Call of Pripyat, S.T.A.L.K.E.R.: Shadow of Chernobyl, Terrorist Takedown 2, TimeShift, Unreal Tournament III<br />
|-<br />
| 0x0000000b || F.E.A.R. Perseus Mandate<br />
|-<br />
| 0x0000000d || Borderlands, Half-Life 2<br />
|-<br />
| 0x80000009 || TitanFall<br />
|}<br />
<br />
=== InGameLaserSightDX9States (0x706139ad) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00023322 || Half-Life 2, Left 4 Dead, Left 4 Dead 2<br />
|}<br />
<br />
=== LaserSight (0x7058b6e1 / 0x7031a2e7 / 0x7045b752) ===<br />
Valid values are 0 and 1<br />
<br />
=== LaserSightFile (0x707ac50d) ===<br />
<br />
<br />
=== LaserSightIndex (0x70da83c6) ===<br />
<br />
<br />
=== StereoLaserSightMaxCount (0x70bc864d) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000004 || Unreal Tournament III<br />
|-<br />
| 0x00000006 || Half-Life 2<br />
|-<br />
| 0x00000008 || Call of Duty: Ghosts, Call of Duty: World at War, UberSoldier<br />
|-<br />
| 0x0000000a || F.E.A.R. Perseus Mandate, Left 4 Dead, Left 4 Dead 2<br />
|-<br />
| 0x000000c8 || Tom Clancy's Rainbow Six: Vegas 2<br />
|}<br />
<br />
=== StereoLaserSightCount (0x70077042) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000002 || Gears of War<br />
|-<br />
| 0x00000004 || Unreal Tournament III<br />
|-<br />
| 0x00000008 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Ghosts, Call of Duty: Modern Warfare 3, Call of Duty: World at War, Medal of Honor<br />
|}<br />
<br />
=== Laser Sight Key Bindings ===<br />
==== ToggleLaserSight (0x70b7bd1f) ====<br />
Only works when set via the Registry and not via a Profile.<br />
<br />
<br />
==== LaserAdjustXMinus (0x7048b7dc) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustXPlus (0x70d8bae6) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustYMinus (0x70fb9e1e) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustYPlus (0x7024eda4) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
== Misc Key Bindings ==<br />
<br />
These are believed to be key bindings due to their names. These will override the global key bindings in the registry. Some of these settings may not work at all in recent drivers.<br />
<br />
There is a good guide for how these are encoded here: [http://3dvision-blog.com/3053-modifying-all-3d-vision-control-key-combinations-as-you-need/ Modifying All 3D Vision Control Key Combinations as You Need]<br />
<br />
=== StereoToggle (0x70d76b8b) ===<br />
Toggles Stereo on and off (Default: Ctrl+T)<br />
<br />
=== StereoSeparationAdjustLess (0x705d1e02) ===<br />
Reduce separation (Default: Ctrl+F4)<br />
<br />
=== StereoSeparationAdjustMore (0x70ab8d32) ===<br />
Increase separation (Default: Ctrl+F5)<br />
<br />
=== StereoConvergenceAdjustLess (0x70d4add7) ===<br />
Reduce convergence (Default: Ctrl+F5)<br />
<br />
=== StereoConvergenceAdjustMore (0x701ed576) ===<br />
Increase Convergence (Default: Ctrl+F6)<br />
<br />
=== SaveStereoImage (0x70121853) ===<br />
Save a stereo screenshort (Default: Alt+F1)<br />
<br />
=== WriteConfig (0x700498b3) ===<br />
Save the current convergence to a user profile (Default: Ctrl+F7)<br />
<br />
=== DeleteConfig (0x70c73ba2) ===<br />
Delete the game's user profile (Default: Alt+F7)<br />
<br />
=== GammaAdjustMore (0x703f4521) ===<br />
=== GammaAdjustLess (0x70e8420c) ===<br />
<br />
=== StereoVerticalAdjustMore (0x7087fe61) ===<br />
=== StereoVerticalAdjustLess (0x703acfc6) ===<br />
=== StereoHorizontalAdjustMore (0x70062f07) ===<br />
=== StereoHorizontalAdjustLess (0x70871a39) ===<br />
<br />
=== ToggleAutoConvergence (0x70085de3) ===<br />
NOTE: AFAIK this was never implemented<br />
<br />
=== ToggleAutoConvergenceRestore (0x703bc51e) ===<br />
NOTE: AFAIK this was never implemented<br />
<br />
=== RHWAtScreenMore (0x7066a22e) ===<br />
=== RHWAtScreenLess (0x709139ad) ===<br />
=== RHWLessAtScreenMore (0x704e4bca) ===<br />
=== RHWLessAtScreenLess (0x70b378a1) ===<br />
<br />
=== CutoffNearDepthLess (0x70d1bdb5) ===<br />
=== CutoffNearDepthMore (0x7020c991) ===<br />
=== CutoffFarDepthLess (0x704c9a46) ===<br />
=== CutoffFarDepthMore (0x70fbc04d) ===<br />
=== CutoffStepLess (0x704b45c7) ===<br />
=== CutoffStepMore (0x700f2971) ===<br />
<br />
=== GlassesDelayPlus (0x701fc5b4) ===<br />
NOTE: Believed to no longer work in recent drivers<br />
<br />
=== GlassesDelayMinus (0x70b8a743) ===<br />
NOTE: Believed to no longer work in recent drivers<br />
<br />
<br />
== Unidentified Settings ==<br />
<br />
These setting names were found in the driver, but their purpose or whether they are even functional is unknown:<br />
<br />
=== Time (0x70ad05c8) ===<br />
Only present in a handful of profiles and appears to be a UNIX Time value:<br />
<br />
{| class="wikitable"<br />
| 0x53979bf4 || 2014-06-10 23:59:48 GMT || Murdered: Soul Suspect<br />
|-<br />
| 0x5398a3b4 || 2014-06-11 18:45:08 GMT || Enemy Front<br />
|-<br />
| 0x5398cbe8 || 2014-06-11 21:36:40 GMT || Heldric - The legend of the shoemaker<br />
|-<br />
| 0x5398d296 || 2014-06-11 22:05:10 GMT || Eterium<br />
|-<br />
| 0x5398df13 || 2014-06-11 22:58:27 GMT || Blackguards<br />
|-<br />
| 0x539a472e || 2014-06-13 0:34:54 GMT || Port Royale 3<br />
|-<br />
| 0x539f8bfb || 2014-06-17 0:29:47 GMT || Sniper Elite 3<br />
|-<br />
| 0x53ab4828 || 2014-06-25 22:07:36 GMT || GRID Autosport<br />
|}<br />
<br />
=== RunTimeName (0x701a8be4) - text ===<br />
Observed values:<br />
<br />
-007, ACS, armada, bzone, Client, CLIENT, Demo, Engine, FFORCE, game, Game, GameClient, heroes, launcher, LithTech, main, mainapp, NoName, PG3, PNOCOMP, Pool, Prism3d, program, rally, sw, SW, tm, UDK, wcdemo, WRUN,<br />
<br />
=== EnableConsumerStereoSupport (0x70cb9168) ===<br />
=== StereoViewer (0x704915a1) ===<br />
=== StereoViewerType (0x708f9ef7) ===<br />
=== ShowAllViewerTypes (0x708e5cb4) ===<br />
=== StereoAdjustEnable (0x70538ab1) ===<br />
=== StereoDisableTnL (0x70633bd9) ===<br />
=== StereoTransformationType (0x70c27e3c) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || ghost<br />
|}<br />
<br />
=== StereoSeparation (0x70933c00) ===<br />
This does not seem to have any affect on the separation in other games.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 2 || AngleLib<br />
|}<br />
<br />
=== StereoSeparationStep (0x7082555b) ===<br />
=== StereoConvergenceMultiplier (0x70efbb5b) ===<br />
Default value: 5.0<br />
<br />
=== RHW2DDetectionMin (0x7029432b) ===<br />
=== RHWGreaterAtScreen (0x702c861a) ===<br />
Floating point value<br />
<br />
=== RHWEqualAtScreen (0x70ab2e09) ===<br />
'''NOT''' a floating point value.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || V-Rally 2, h2wof<br />
|}<br />
<br />
=== RHWLessAtScreen (0x70381472) ===<br />
Floating point value<br />
<br />
=== AutoConvergence (0x702a0ab2) ===<br />
Looking over the list of games with this setting I suspect this is a very old feature that well and truly pre-dates DX9 and probably won't work in any modern game.<br />
<br />
<u> Known Values </u><br />
<br />
A considerable number of profiles have this set to 0, which may be meaningless if 0 is the default, but that would be unusual to have so many profiles specify the default.<br />
<br />
{| class="wikitable"<br />
| 0 || "Alien vs Predator 2", "Archlords", "Arcsoft Media Converter", "Armies of Exigo", "Army Men RTS", "BackyardBaseball2005", "Battlefield 1942", "Battlefield 2", "Battlefield Vietnam", "Black and White 2", "Black and White 2: Battle of the Gods", "Boarder Zone", "Colin McRae Rally 5", "Comanche 4", "Combat Flight Simulator 3", "Combat Mission", "Cricket 2005", "Dark Messiah of Might and Magic", "Delta Force 3: Land Warrior(Dflw.exe)", "Delta Force: Xtreme", "Diplomacy", "Driver 3", "Elder Scrolls 3: Morrowind", "Evolva", "Expert Pool", "ExtConverter", "F.E.A.R.", "FIFA Soccer 2004(fifa2004.exe)", "FIFA Soccer 2005", "FIFA Soccer 2006", "Fable: The Lost Chapters", "Far Cry", "Firestarter", "Freelancer", "GUN", "Ghost Recon: Advanced Warfighter(Demo)", "Godfather: The game", "Google Chrome", "Gothic 2", "Ground Control 2", "Gun Metal", "Harry Potter And The Goblet Of Fire", "Harry Potter Quidditch World Cup", "Harry Potter and the Prizoner of Azkaban", "Hidden & Dangerous 2", "High Heat Major League Baseball 2004", "Hitman: Blood Money", "Impossible Creatures", "Independence War 2 - Edge of Chaos", "Jetfighter 2015", "Joint Operations: Typhoon Rising", "Knight Shift", "Kohan 2", "LEGO Star Wars", "LOTR bat2", "Lock On", "Lord of the Rings: Return of the King", "Lords of the Realm 3", "MVP Baseball 2003", "MVP Baseball 2004", "MVP Baseball 2005", "Mafia", "Manhunt", "Massive Assault", "Max Payne 2", "MechWarrior IV Mercenaries", "Men of Valor:Vietnam", "Microsoft Flight Simulator 2004", "Microsoft Train Simulator", "Midnight Club II", "Motocross Madness 2", "Mount & Blade: With Fire & Sword", "Movavi Video Converter", "Myst 4", "NASCAR SimRacing", "NBA Live 2004", "NBA Live 2005", "NBA Live 2006", "NHL 2003(nhl2003.exe)", "NHL 2005", "NHL 2006", "Nexus: The Jupiter Incident (DX9 version)", "No One Lives Forever 2", "No man's land", "Painkiller", "Paradise Cracked", "Pariah", "Perimeter", "Psychonauts", "Rainbow Six 3: Raven Shield", "Red Faction II", "Republic", "Rise and Fall: Civilizations at War", "RollerCoaster Tycoon 3", "Rome - Total War", "Roo Goo", "Roxio Video Converter", "Rugby2004", "SHGame", "Sid Meier's Pirates!", "Silent Hunter III", "Sims 2 - University", "Sims 2", "Sims 2: Nightlife", "Space Station Manager", "Spellforce 2", "Spellforce", "Splinter Cell: Chaos Theory", "Splinter Cell: Pandora Tomorrow", "Squad Assault - West Front", "Star Wars: Battlefront (2004)", "Star Wars: Battlefront II", "Star Wars: Republic Commando", "SupremeRuler", "Syberia 2", "Teenage Mutant Ninja Turtles", "Temple of Elemental Evil", "Terminator 3: War of the Machines", "The Bard's Tale", "The Incredibles", "The Simpsons: Hit and Run", "Tiger Woods PGA Tour 05", "Tiger Woods PGA Tour 06", "Tony Hawk's Underground", "Trackmania - Sunrise", "Unreal 2", "Vampire The Masquerade - Bloodlines", "WARHAMMER 40k Fire Warrior", "Warcraft III", "Warhammer 40000: Dawn of War - Winter Assault", "Warhammer 40000: Dawn of War", "Warrior Kings - Battles", "Webhead", "Winning Eleven 7", "X-Men Legends II: Rise of Apocolypse", "X2: Wolverine's Revenge", "ffvt3rd", "grand theft auto_sa"<br />
|-<br />
| 1 || "Apache: Air Assault", "Archlords", "Arcsoft Media Converter", "BlackSite: Area 51", "Championship BASS", "Combat Mission", "Crusaders of Might and Magic", "Dagoth Moor Zoological Gardens", "Darkstone", "Descent FreeSpace 2", "End of Nations", "European Air War", "Exodus from the Earth", "Expert Pool", "ExtConverter", "Extreme Biker", "Flesh Feast", "G-Police", "Grandia2", "Hot Chix 'n' Gear Stix", "Incomming", "Interstate '82", "Legends of the Seers", "Luftwaffe Commander", "Madden NFL Games", "Michelle Kwan Figure Skating(kwandemo.exe)", "Microsoft Baseball 2001", "Mount & Blade: With Fire & Sword", "Movavi Video Converter", "NASCAR 2000(NASCAR 2000 Demo.exe)", "NASCAR 2000(NASCAR 2000.exe)", "NASCAR Heat", "NASCAR Legends", "Omikron: The Nomad Soul(Nomad.exe)", "Pong", "Professional Bull Rider", "Renegade Racers(rrDemo.exe)", "Rocketsled", "Roo Goo", "Roxio Video Converter", "Test Drive 6", "Topspin", "True Crime: Streets of LA", "Up", "Wartorn"<br />
|}<br />
<br />
=== AutoConvergenceAdjustPace (0x70bf3c6b) ===<br />
Floating point value, which is almost always set to 0.05 (except for Combat Mission, where it is set to 1.0). Note that this is present in a number of profiles that lack AutoConvergence.<br />
<br />
=== StereoToggleMode (0x70d76b8c) ===<br />
=== StereoSuggestSettings (0x706315af) ===<br />
=== StereoUnsuggestSettings (0x7017861c) ===<br />
=== FavorSZ (0x705faed7) ===<br />
=== StereoPointer (0x70364596) ===<br />
Only seen in "Sims 2 - University" and "Sims 2: Nightlife", where this is set to 1. Note that this is not present in the base Sims 2 profile or any of the other Sims 2 profiles.<br />
<br />
=== MonitorSize (0x7086ebe9) ===<br />
=== MaxMonitorSize (0x7032022c) ===<br />
=== MaxVertexCount (0x709e4a94) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000002 || Half-Life 2<br />
|-<br />
| 0x00010000 || Arabian Nights<br />
|}<br />
<br />
=== PartialClearMode (0x709794cc) ===<br />
=== StereoRefreshDefaultOn (0x702ba385) ===<br />
=== MixedTnL (0x70bd11e0) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark01", "3DMark03", "3DMark05", "James Bond Nightfire", "Need for Speed Hot Pursuit 2(Nfshp2.exe)", "Need for Speed Hot Pursuit 2(NFSHP2Demo.exe)"<br />
|}<br />
<br />
=== StereoGamma (0x70c8b5d1) ===<br />
=== LineCodeColor (0x70dc4a12) ===<br />
=== LeftAnaglyphFilter (0x70d51cd1) ===<br />
=== RightAnaglyphFilter (0x70f4a930) ===<br />
=== InterleavePattern0 (0x70b1c8cc) ===<br />
=== InterleavePattern1 (0x7091a772) ===<br />
=== StereoForceVSync (0x70aae185) ===<br />
=== StereoColorKey (0x70e5773b) ===<br />
Only present in the "NV Pinball" profile, where it is set to 0x00010101<br />
<br />
=== ZDirection (0x70b17872) ===<br />
=== StereoCompatibility (0x70a2000e) ===<br />
=== LeftColorFilter0 (0x70ac6888) ===<br />
=== LeftColorFilter1 (0x7090b6ca) ===<br />
=== RightColorFilter0 (0x70b9a2f7) ===<br />
=== RightColorFilter1 (0x70aca0cc) ===<br />
=== SharpVPI (0x706e0041) ===<br />
=== StereoMode (0x701baa09) ===<br />
=== Watchdog (0x700a5654) ===<br />
=== StereoOSDEnable (0x70f455aa) ===<br />
=== StereoOrthoEnable (0x703564f6) ===<br />
An Orthographic projection does not ordinarily involve a perspective divide, and therefore it stands to reason that these games may use a slightly different stereo correction formula.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Halo", "Midnight Club II(mc2_demo.exe)", "Port Royale", "Sims 2 - University", "Sims 2", "Sims 2: Nightlife"<br />
|}<br />
<br />
=== StereoNotSupported (0x709aa171) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark Ice Storm", "3DMark", "3DMark11", "3DMark14", "All Play-On-line Games", "Evolve", "Final Fantasy XIV: A Realm Reborn", "NVIDIA NVFBC Applications", "NVKeystone", "Resident Evil: Revelations 2 / Biohazard Revelations 2", "Ryse: Son of Rome", "Sid Meier's Civilization: Beyond Earth", "VRP", "Windows Live Mail", "Windows Live Photo Gallery", "Windows Movie Maker", "WLXPGSS"<br />
|}<br />
<br />
=== ModesetWarning (0x70969bb0) ===<br />
=== StereoFirstTime (0x70af6400) ===<br />
=== StereoRefreshRate (0x70ded3c0) ===<br />
=== GameConfigs (0x704a905a) ===<br />
=== CompareEyes (0x70729e58) ===<br />
=== CompareFrom (0x70efb726) ===<br />
=== StereoImageType (0x7097906c) ===<br />
=== SnapShotQuality (0x7004e7a6) ===<br />
=== NoLockSubstitute (0x7005ad16) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark03", "3DMark05", "Bumper to Bumper", "S.T.A.L.K.E.R.: Shadow of Chernobyl", "Star Wraith 3: Shadows of Orion", "World Dance"<br />
|}<br />
<br />
=== PushbufSubstituteSize (0x7054fbf8) ===<br />
=== DiscardHotkeys (0x70175566) ===<br />
=== StereoLCDPatternType (0x707cfb97) ===<br />
=== GlassesSwitchDelay (0x70057bb6) ===<br />
<br />
Valid values appear to be between 5 <= GlassesSwitchDelay < 95<br />
<br />
=== StartZBit (0x7044d7a6) ===<br />
=== DisableOnOutOfMemory (0x70c71508) ===<br />
=== StereoWindowedEnable (0x709b3484) ===<br />
=== AllowNonExclusiveStereo (0x702c7709) ===<br />
=== Rhwinf (0x706e1913 / 0x70cc286a / 0x70a3fee6) ===<br />
Floating point value set in 26 profiles with values ranging from 0.00003125 to 0.04<br />
<br />
RHW stands for Reciprocal of Homogeneous W, really just a fancy term for 1 / linear depth. inf is presumably short for infinite depth.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.00003125 || Gears of War<br />
|-<br />
| 0.000062500985 || Unreal Tournament III<br />
|-<br />
| 0.00006666667 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Modern Warfare 3, Damnation, F.E.A.R. Perseus Mandate, Frontlines: Fuel of War, Left 4 Dead 2, Left 4 Dead, Medal of Honor, Mirror's Edge, TimeShift, Tom Clancy's Rainbow Six: Vegas 2<br />
|-<br />
| 0.0001 || F.E.A.R. 2: Project Origin, Gears of War(wargame-g4wlive_DX10.exe), Half-Life 2, Mass Effect 2, Mass Effect, Shell Shock 2, Stranglehold<br />
|-<br />
| 0.00025 || The haunted Hells Reach<br />
|-<br />
| 0.00066666666 || Q.U.B.E.<br />
|-<br />
| 0.01 || Kane & Lynch: Dead man, Serious Sam III<br />
|-<br />
| 0.04 || The Club<br />
|}<br />
<br />
=== Rhwscr (0x70a4995c / 0x7030b071 / 0x70b57ed1) ===<br />
Floating point value set in 29 profiles with values ranging from 0.05 to 1.0<br />
<br />
Presumably related to Rhwinf, and "scr" is likely short for screen depth.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.05 || The Club, Tom Clancy's Rainbow Six: Vegas 2, Unreal Tournament III<br />
|-<br />
| 0.06666667 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Modern Warfare 3, Gears of War, Medal of Honor, TimeShift<br />
|-<br />
| 0.1 || Damnation, F.E.A.R. 2: Project Origin, Frontlines: Fuel of War, Gears of War(wargame-g4wlive_DX10.exe), Half-Life 2, Mass Effect 2, Mass Effect, Mirror's Edge, Q.U.B.E., Shell Shock 2, Stranglehold, The haunted Hells Reach"<br />
|-<br />
| 0.11111111 || Left 4 Dead, Left 4 Dead 2<br />
|-<br />
| 0.125 || BlackSite: Area 51<br />
|-<br />
| 0.15 || TitanFall<br />
|-<br />
| 0.2 || Call of Duty: World at War, F.E.A.R. Perseus Mandate<br />
|-<br />
| 1.0 || Kane & Lynch: Dead man, Serious Sam III<br />
|}<br />
<br />
=== Zinf (0x70fc13ad) ===<br />
At a guess this is probably similar to Rhwinf, but uses the output Z coordinate of the vertex shader instead of the output W coordinate.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.0 || Call of Duty: Ghosts<br />
|}<br />
<br />
=== Zscr (0x707f0e69) ===<br />
At a guess this is probably similar to Rhwscr, but uses the output Z coordinate of the vertex shader instead of the output W coordinate. Presumably related to Zinf in the same way Rhwscr is related to Rhwinf.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1.0 || Call of Duty: Ghosts<br />
|}<br />
<br />
=== EnableCE (0x702b8c95) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Age of Empires III", "Age of Empires III - The War Chiefs", "Age of Empires III: The Asian Dynasties"<br />
|}<br />
<br />
=== MediaPlayer (0x70a8fc7f) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "BaoFeng / Storm Player", "Cyberlink PowerDVD", "Cyberlink PowerDVD10", "Cyberlink PowerDVD9", "Movie Studio Platinum 12", "PixEVRComponentTest", "Sony Media Gallery", "Sony Vegas Pro", "Stereoscopic Player", "VFTV", "Vegas Movie Studio HD Platinum 11", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoDX9 (0x70d10d2b) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "AZMD! Scorepocalypse", "Adam's Venture Episode 1", "Afterfall: InSanity", "Alan Wake's American Nightmare", "All Zombies Must Die", "Battlefield: Bad Company 2", "Borderlands 2", "Bullet Run", "Choplifter HD", "Counter-strike: Global Offensive", "Crysis 2", "Da Vinci Online", "Dear Esther", "Deus Ex: Human Revolution", "Dishonored", "DmC-Devil May Cry", "Duke Nukem Forever", "End of Nations", "Far Cry 2", "Gears of War", "Hawken", "Mars", "Painkiller Hell & Damnation", "Q.U.B.E.", "Quan Qiu Shi Ming(MarsGame.exe)", "Red Orchestra 2: Heroes of Stalingrad", "Risen 2: Dark Waters", "Section 8: Prejudice", "Spec Ops: The Line", "The Ball", "The Witcher 2: Assassins of Kings", "The haunted Hells Reach", "Tony Hawk's Pro Skater HD", "Tribes Ascend", "WARP", "War of the Roses", "World in Conflict", "XCOM: Enemy Unknown"<br />
|}<br />
<br />
=== StereoMsgVerticalOffset (0x70160ebf) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 16 || Assassin's Creed(DX9)<br />
|}<br />
<br />
=== StereoEasyZCheck (0x70b6d6ed) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Half-Life 2", "Kane & Lynch: Dead man", "Mass Effect 2", "Mass Effect", "Shell Shock 2", "Stranglehold", "The Club", "TimeShift", "Tom Clancy's Rainbow Six: Vegas 2"<br />
|}<br />
<br />
=== StereoStrictLSCheck (0x709bc378) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Half-Life 2", "Tom Clancy's Rainbow Six: Vegas 2"<br />
|}<br />
<br />
=== StereoDisableAsync (0x70de5533) ===<br />
=== EnablePartialStereoBlit (0x7096eced) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "BaoFeng / Storm Player", "Flash(Firefox)", "NVIDIA Stereoscopic 3D video player", "NVStWiz", "Sony Media Gallery", "Stereoscopic Player", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoNoDepthOverride (0x709dea62) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "NVIDIA Stereoscopic 3D video player", "Novlum Demes Editor", "NvStView", "Sony Media Gallery", "Stereoscopic Player", "Trine 3", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoShaderMatrixCheck (0x7044f8fb) ===<br />
=== StereoLogShaders (0x7052bdd0) ===<br />
=== StereoEpsilon (0x70e5a749) ===<br />
Floating point value seen in 46 profiles. Observed values: 0.00000088, 0.0000088, 0.000088<br />
<br />
=== DelayedStereoDesktop (0x7042eef1) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000001 || Half-Life 2, Tom Clancy's H.A.W.X.<br />
|-<br />
| 0x00140002 || Fallout 3<br />
|}<br />
<br />
=== StereoMiscFlags (0x70ccb5f0) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000006 || PixEVRComponentTest<br />
|-<br />
| 0x00000008 || Assassin's Creed: Unity, Diablo III<br />
|-<br />
| 0x00000010 || Depth Hunter, Elder Scrolls V: Skyrim, End of Nations, Strike Suit Zero, The Walking Dead 2, The Walking Dead<br />
|-<br />
| 0x00000020 || Star Trek<br />
|-<br />
| 0x00000080 || Stereoscopic Player<br />
|-<br />
| 0x00000086 || Cyberlink PowerDVD10, VFTV<br />
|-<br />
| 0x00000100 || Biohazard 5, Devil May Cry 4(DX9), Lost Planet 2, Resident Evil 5<br />
|-<br />
| 0x00000400 || Homefront: The Revolution<br />
|-<br />
| 0x00000c06 || Cyberlink PowerDVD<br />
|-<br />
| 0x00000c86 || Cyberlink PowerDVD9<br />
|}<br />
<br />
=== StereoHiddenProfile (0x70e46f20) ===<br />
<u> Known Values </u><br />
<br />
A considerable number of profiles have this set to 0, which may be meaningless if 0 is the default, but that would be unusual to have so many profiles specify the default.<br />
<br />
{| class="wikitable"<br />
| 0 || "ACS", "armada", "bzone", "Client.exe", "Crysis", "Demo", "Dragon : MMORPG", "Freedom Force", "Game.exe", "GameClient.exe", "Google Chrome", "Hunting 4", "LithTech", "Madden NFL Games", "Microsoft Internet Explorer", "Mozilla FireFox - Plugin Container", "Mozilla Firefox", "Nations", "nfs", "NoName", "Novlum Demes Editor", "Panzer General 3 Scorched Earth(PG3.exe)", "Pencil Whipped", "Prince of Persia", "program", "rally", "S.T.A.L.K.E.R.: Clear Sky", "Safari Congo", "Ship Simulator 2006", "SW", "Ultimate 8 Ball", "WRUN"<br />
|- <br />
| 1 || "AngleLib", "engine", "heroes", "launcher", "UDK (Unreal Development Kit) based games"<br />
|}<br />
<br />
=== StereoLinkDll (0x70e46f2a) - text ===<br />
<br />
Appears to be a comma separated list of files to search for. At a guess, if this setting is present these files either must or must not exist for stereo to engage.<br />
<br />
=== EnableStereoCursor (0x70e46f2b) ===<br />
=== CreateStereoDTAfterPresentNum (0x70a7fc7f) ===<br />
To confirm, but presumably delays initialising 3D Vision until the game has drawn this number of frames, possibly to work around crashes on launch or other issues caused by 3D Vision being enabled when the game is launched, but works if enabled later.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 3 || Cyberlink PowerDVD9<br />
|-<br />
| 50 || Call of Duty Online<br />
|}<br />
<br />
=== Date_Rel (0x705fafec) - text ===<br />
May contain the release date in the form YYYY-MM-DD 00:00:00<br />
<br />
=== Game (0x70c8d48e) - text ===<br />
=== Style (0x709cc5e0) - text ===<br />
<br />
Contains the game's genre, such as "Action", etc.<br />
<br />
=== Publisher (0x706c7030) - text ===<br />
<br />
Lists the game's publisher.<br />
<br />
=== Developer (0x703c4026) - text ===<br />
<br />
Lists the game's developer.<br />
<br />
=== API (0x70b5603f) - text ===<br />
Usually contains "D3D", other observed values include "d3d", "D3d", "D3D_", "OGL_" and "S/W"<br />
<br />
=== Value (0x7049c7ec) ===<br />
Observed values: "0", "0.0", "1", "1.0", "2", "2.0", "3", "3.0", "4", "4.0", "5", "5.0", "101.0", "102.0"<br />
<br />
=== P1SH0 (0x70998683) - text ===<br />
=== V1SH0 (0x70e6a3cf) - text ===<br />
=== PSH0 (0x7046516e) - text ===<br />
=== VSH0 (0x708b7af8) - text ===<br />
At a guess this might stand for "Vertex Shader Hash 0" and define some kind of override for a specific vertex shader, perhaps to force the stereo correction on or off for a particular shader.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| "1162e513 0 1" || Gears of War<br />
|-<br />
| "6e34f93f 0x01 0 0 0 0 0" || AngleLib<br />
|-<br />
| "D162E513 0 1" || Batman: Arkham Asylum<br />
|}<br />
<br />
=== VSH1 (0x708b7af9) - text ===<br />
=== VSH2 (0x708b7afa) - text ===<br />
=== VSH3 (0x708b7afb) - text ===<br />
=== VSH4 (0x708b7afc) - text ===<br />
=== VSH5 (0x708b7afd) - text ===<br />
=== VSH6 (0x708b7afe) - text ===<br />
=== VSH7 (0x708b7aff) - text ===<br />
=== VSH8 (0x708b7b00) - text ===<br />
=== VSH9 (0x708b7b01) - text ===<br />
=== VSH10 (0x708b7b02) - text ===<br />
<br />
== Registry Settings ==<br />
<br />
These are settings discovered in the 3D Vision driver that are not listed in the profile table, meaning they can only be set via the registry or (in some cases) control panel. Other settings on this page may (or may not) also be placed in the registry.<br />
<br />
On a 64bit OS these settings are under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\NVIDIA Corporation\Global\Stereo3D<br />
<br />
This section is incomplete.<br />
<br />
=== MonitorSizeOverride ===<br />
Overrides MonitorSize, but is not reset constantly making it a superior option to depth hacks.<br />
<br />
=== DrsEnable ===<br />
Enables the use of driver profiles.<br />
<br />
=== 0x1800babe ===<br />
That's not a hex value - that's a literal name of a possible registry key, including the "0x".<br />
<br />
=== StereoAdvancedHKConfig ===<br />
=== StereoFullHKConfig ===<br />
=== StereoCompatibility ===<br />
=== EnablePersistentStereoDesktop ===<br />
=== EnableWindowedMode ===<br />
=== StereoIROutput ===<br />
=== StereoFlywheelCycleState ===<br />
=== StereoFlywheelCycle ===<br />
=== StereoVBIOverride ===<br />
=== ContrastOverride ===<br />
=== MultiheadMode ===<br />
=== SOLPerf ===<br />
=== EnableAPILog ===<br />
=== EnableHDMICheckerboard ===<br />
=== ContrastOverrideLog ===<br />
=== StereoKiosk ===<br />
=== DisablePatternWindowedMode ===<br />
=== StereoForcePairFlip ===<br />
=== __S ===<br />
=== SDStereoType ===<br />
=== StereoAnaglyphType ===<br />
=== StereoDisabled ===<br />
=== HDMIBroadcast ===<br />
=== Broadcast3way ===<br />
=== IGBroadcast ===<br />
=== SLIOverride ===<br />
=== UseCE ===<br />
=== ResourceTracking ===<br />
=== EnableIE9HTML5 ===<br />
=== IE9HTML5Width ===<br />
=== IE9HTML5Height ===<br />
=== IE9HTML5Layout ===<br />
<br />
== More Registry Settings ==<br />
On a 64bit OS these settings are under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\NVIDIA Corporation\Global\Stereo3DPersistent<br />
<br />
=== 3D Vision ===<br />
=== Count ===</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Driver_Profile_SettingsDriver Profile Settings2017-03-21T12:28:36Z<p>Bo3b admin: </p>
<hr />
<div>This page is a work in progress - feel free to expand it with extra knowledge, before & after screenshots, etc.<br />
<br />
<br />
== Tools ==<br />
<br />
The recommended tool for working with profiles is [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/2.1.2.12/artifacts NVIDIA Profile Inspector 2.1.2.12] or later due to its ability to decrypt internal settings.<br />
<br />
[https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/artifacts Latest continuous integration build]<br />
<br />
[https://github.com/Orbmu2k/nvidiaProfileInspector Source code]<br />
<br />
[http://forums.guru3d.com/showthread.php?t=403676 Forum thread] (note that the download linked from here does not yet support decrypting internal settings)<br />
<br />
3DMigoto 1.2.50 now has built in support for working with driver profiles, including decrypting and logging the current profile in d3d11_log.txt, and making any changes necessary when the game is launched.<br />
<br />
==== Obsolete tools: ====<br />
<br />
NVIDIA Profile Inspector 2.1.2.6 or older<br />
<br />
[http://orbmu2k.de/tools/nvidia-inspector-tool NVIDIA Inspector] 1.9.7.5 or older ([http://www.guru3d.com/files-details/nvidia-inspector-download.html English mirror])<br />
<br />
[http://nvidia.custhelp.com/app/answers/detail/a_id/2625/kw/Profile GeForce 3D Profile Manager]<br />
<br />
== NVIDIA Inspector Custom Stereo Settings Names ==<br />
<br />
NVIDIA Inspector (old versions): Download this [https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/CustomSettingNames_en-EN.xml CustomSettingNames_en-EN.xml] file to replace the one from NVIDIA Inspector, which will add all the settings listed on this page to the Stereo category.<br />
<br />
NVIDIA Profile Inspector: This program automatically decodes most setting names (you may need to select "Show unknown settings from NVIDIA predefined profiles" to see them) '''Edit: This no longer works as recent drivers have removed the DLLs that the tool relied on to find the stereo settings names'''. There are some exceptions - most notably the all important StereoProfile setting is missing. You can use the XML file linked above, but name it 'CustomSettingNames.xml' (i.e. remove the '_en-EN').<br />
<br />
== Important note about encoding of "Internal" Settings ==<br />
<br />
Some profiles are shipped with the internal settings flag set on certain settings. These show up with "InternalSettingFlag=V0" in Geforce Profile Manager, but there is no easy way to distinguish them in NVIDIA Inspector. These settings are encrypted and the values read out with these tools will not match any of the documentation here. Further, if they are written back with NVIDIA Inspector, the flag will be cleared and they will become corrupt. Geforce Profile Manager allows them to be written back with the flag intact avoiding the corruption, but still does not help understand them.<br />
<br />
A script to decipher these values from Geforce Profile Manager is available: [https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/__profiles__/sanitise_nv_profiles.py here]<br />
<br />
NVIDIA Profile Inspector 2.1.2.7 or later can correctly decode these, and is now the recommended tool for working with driver profiles. [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/2.1.2.7/artifacts Version 2.1.2.7] [https://ci.appveyor.com/project/Orbmu2k/nvidiaprofileinspector/build/artifacts Latest build]<br />
<br />
3DMigoto 1.2.50 and later includes support for logging and updating driver profiles, and correctly handles encrypted settings. The undocumented option [Logging] dump_all_profiles=1 can be used to have it decrypt and log every profile instead of just the ones relevant to the game being run.<br />
<br />
== Notes on settings with multiple IDs ==<br />
<br />
Some settings on this page are listed with two or three IDs. This is not fully understood yet. Generally you should stick to the first value listed, but if a profile also lists the second or third value in this list it might be used in place of the first (however a given profile will only use a specific ID out of the second or third in the list).<br />
<br />
The following settings have multiple IDs:<br />
{| class="wikitable"<br />
! Name || Primary ID || 1st Alternate ID || 2nd Alternate ID<br />
|-<br />
| StereoConvergence || 0x708DB8C5 || 0x7077BACE || 0x7084807E<br />
|-<br />
| LaserSight || 0x7058B6E1 || 0x7031A2E7 || 0x7045B752<br />
|-<br />
| FrustumAdjustMode || 0x70A1411A || 0x70ED1DA7 || 0x70F475A0<br />
|-<br />
| StereoTextureEnable || 0x70EDB381 || 0x70E1518C || 0x70C0125E<br />
|-<br />
| Rhwinf || 0x706E1913 || 0x70CC286A || 0x70A3FEE6<br />
|-<br />
| Rhwscr || 0x70A4995C || 0x7030B071 || 0x70B57ED1<br />
|-<br />
| InGameLaserSight || 0x7064F0C2 || 0x70DD2585 || 0x70E7ADAD<br />
|-<br />
| StereoCutoffDepthNear || 0x7050E011 || 0x704EF483 || 0x7031DE06<br />
|-<br />
| StereoCutoff || 0x709A1DDF || 0x704FCF5C || 0x7053569A<br />
|-<br />
| DX10VSCBNumber || 0x70F8E408 || || 0x70F64A32<br />
|}<br />
<br />
== StereoProfile (AKA The Mystery Stereo Setting) 0x701EB457 ==<br />
<br />
This setting is known to be very important to stereo profiles. We now know it's official name is STEREO_STEREOPROFILE, and will be referred to as "StereoProfile" in future releases of NVIDIA Profile Inspector.<br />
<br />
<u> Observations </u><br />
<br />
- The mere existance of this setting on a DX9 profile will enable Stereo in windowed mode, regardless of the value.<br />
<br />
- This setting is required to enable a lot of stereo related code in the driver.<br />
<br />
- Certain other stereo settings (e.g. StereoTextureEnable) may be ignored without this setting.<br />
<br />
- If this is missing in a profile, attempting to save the profile with Ctrl+F7 will not work, and will restore the default convergence instead. It has been noted that adding this setting to the base profile can solve this globally, but may cause the monitor to switch to stereo mode when using certain 2D applications (e.g. VS2015), which may be undesirable in some cases.<br />
<br />
<u>Bit Definitions</u><br />
<br />
{| class="wikitable"<br />
|Missing || Not a stereo profile (Certain things will not work, including saving the profile via Ctrl+F7)<br />
|-<br />
|0x00000000 || Not a stereo profile (Certain things will not work - need to confirm exactly what differs compared to missing)<br />
|-<br />
|0x00000001 || Stereo profile (everything will work)<br />
|-<br />
|0x2241AB21 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
== Notable Settings ==<br />
<br />
=== StereoTextureEnable (0x70edb381 / 0x70e1518c / 0x70c0125e) ===<br />
<br />
- Controls the heuristics that determines which render targets & Z buffers are stereoised and which are not.<br />
<br />
- Controls the heuristics that determines in what situations the stereo correction formula will be applied.<br />
<br />
- Some bits are used for specific games.<br />
<br />
<u> Observations </u><br />
<br />
- Setting this to all F's will turn a game into mono, suggesting that some high bits might filter out some render targets, rather than enabling them.<br />
<br />
<u> Bit Definitions </u><br />
<br />
Contact DarkStarSword or Bo3b privately for a complete list of bit definitions for this setting.<br />
<br />
Chiri determined a number of these (see [https://forums.geforce.com/default/topic/506784/3d-vision/l-a-noire-official-3d-vision-thread/post/3613599/#3613599 this post])<br />
<br />
{| class="wikitable"<br />
|0x00000001 || [ET] = Stereoize render target textures which are of size or exceeding the size of the backbuffer (and are not square).<br />
|-<br />
|0x00000002 || [ESMT] = Stereoize all non square render target textures smaller then backbuffer.<br />
|-<br />
|0x00000004 || [ESQT] = Stereoize sqare render target textures.<br />
|-<br />
|0x00000008 || [DBBST] = ???<br />
|-<br />
|0x00000010 || [DBBS] = ???<br />
|}<br />
<br />
<u> Known Values </u><br />
<br />
This only lists known values of games using the high bits (0x10000 and above), since the meaning of the low bits are all known. These high bits are believed to be for game specific quirks:<br />
<br />
{| class="wikitable"<br />
|0x0001xxxx || MX vs. ATV Reflex, Prince of Persia - The Forgotten Sands, Prince of Persia(gameinterpreters_rd.exe)<br />
|-<br />
|0x0002xxxx || Call of Duty: Modern Warfare 2, EverQuest II, F.E.A.R. 2: Project Origin, F.E.A.R. 2: Project Origin(Demo), Lost Planet: Colonies Edition, Serious Sam II, Vizerra Viewer<br />
|-<br />
|0x0003xxxx || Time of Shadows<br />
|-<br />
|0x0004xxxx || BioShock 2<br />
|-<br />
|0x0010xxxx || Kane & Lynch 2: Dog days, Need for Speed: World, R.U.S.E., Super Street Fighter IV<br />
|-<br />
|0x0020xxxx || Tom Clancy's H.A.W.X. 2<br />
|-<br />
|0x00c0xxxx || Battlefield: Bad Company 2, BFBC2Game_dx10<br />
|-<br />
|0x0100xxxx || AngleLib<br />
|-<br />
|0x0200xxxx || Ashes of the Singularity, F1 2015 DX12, Fable Legends, Sid Meier's Civilization VI<br />
|-<br />
|0x0400xxxx || Rise of the Tomb Raider<br />
|-<br />
|0x0800xxxx || Gears of War 4<br />
|-<br />
|0x2000xxxx || World of Tanks<br />
|-<br />
|0x8000xxxx || Need for Speed: Shift, Resident Evil 5<br />
|}<br />
<br />
<br />
<u> Default Value </u><br />
<br />
If not specified in a profile, the driver appears to use 0x23 as the default.<br />
<br />
=== StereoUseMatrix (0x70e34a78) ===<br />
<br />
- Able to automatically fix halo type issues in many games<br />
<br />
<u> Known Values </u><br />
{| class="wikitable"<br />
|0x00000000 || Disabled (only vertex output position will be adjusted by the driver)<br />
|-<br />
|0x00000001 || Enabled (other texcoord outputs based on the position will be adjusted by the driver)<br />
|-<br />
|0x1945B570 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
=== StereoFlagsDX10 (0x702442fc) ===<br />
<br />
- Able to resolve mono depth buffer issues in DirectX 11 games, such as Far Cry 4 and Ryse: Son of Rome.<br />
<br />
<u> Bit Definitions </u><br />
<br />
{| class="wikitable"<br />
|0x00008000 || STEREO_COMPUTE_SAME_RESOURCES_AS_GRAPHICS - "stereorize the same resources as for graphics (do not mark all UAVs as stereorizable)"<br />
|-<br />
|0x00004000 || STEREO_COMPUTE_ENABLE - enables running compute shaders once for each eye. Fixes mono depth buffer issue in Far Cry 4 (SLI users can alternatively resolve this with custom SLI compatibility bits), Witcher 3, and other games.<br />
|-<br />
|0x00000024 || One of these two bits negated the separation value reported to 3Dmigoto in Far Cry 4<br />
|}<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
|0x00000001 || Far Cry 2 (DX10 version)<br />
|-<br />
|0x00000004 || Crysis, Civilisation V<br />
|-<br />
|0x00000008 || 3DMark Vantage<br />
|-<br />
|0x000000E0 || Resident Evil 5<br />
|-<br />
|0x00000200 || Crysis 3, Battlefield 3<br />
|-<br />
|0x00000400 || Batman: Arkham City, Metro 2033<br />
|-<br />
|0x00001000 || Passion Leads Army Benchmark<br />
|-<br />
|0x00002000 || Titanfall<br />
|-<br />
|0x00002004 || Crysis Warhead<br />
|-<br />
|0x00004000 || Max Payne 3, Far Cry 4 (352.86+), The Witcher 3, Batman: Arkham Knight, The Park<br />
|-<br />
|0x00034000 || Metro: Last Light<br />
|-<br />
|0x1C22FE24 || Encrypted, upgrade NVIDIA Profile Inspector<br />
|}<br />
<br />
=== StereoCutoff (0x709a1ddf / 0x704fcf5c / 0x7053569a) ===<br />
<br />
Present in almost all Stereo profiles, but meaning unknown. My complete guess is that it may be related to driver heuristics to decide when the stereo correction formula is applied (e.g. for UI elements)?<br />
<br />
<u> Possible Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000000 || Unknown<br />
|-<br />
| 0x00000001 || Default<br />
|-<br />
| 0x00000002 || Use StereoCutoffDepthNear<br />
|-<br />
| 0x00000004 || Use StereoCutoffDepthFar<br />
|-<br />
| 0x00000008 || Unknown<br />
|}<br />
<br />
Other values are invalid.<br />
<br />
<u> Observations </u><br />
<br />
- Setting this to 0x00000000 broke shadows in Miasmata<br />
<br />
<u> Observations from D-Man11 (see [https://forums.geforce.com/default/topic/801771/3d-vision/tomb-raider-triology/post/4785703/#4785703 this post]) </u><br />
<br />
Note: the values below have been edited from the original post to use the setting names and their decrypted values.<br />
<br />
Interesting thing is, if you apply the TR: Underworld profile, the UI text doesn't split, just the background.<br />
<br />
Messing around with Legend, I found that StereoCutoffDepthNear = 25.0 and Setting StereoCutoff = 0x00000002 were the responsible flags from the Anniversary profile to stop the UI from splitting. Either by itself would not do anything.<br />
<br />
If I just added them to the existing Legend profile, it wouldn't work, something was stopping it. (DarkStarSword's note - this may have been because they were encrypted. This experiment should be repeated)<br />
<br />
If I deleted everything from the Legend profile, excluding StereoProfile = 0x00000001 (which is needed, if you remove it, the profile defaults to generic) and added the 2 flags from Anniversary, the UI would not split.<br />
<br />
StereoCutoffDepthNear = 0x41c80000 (25.0) // is exclusive to TR: Anniversary<br />
StereoCutoff = 0x00000002 // is found in 26 other profiles<br />
StereoProfile = 0x00000001 // is found in 2110 profiles<br />
<br />
So the above 3 settings need to be present and there must not be any current settings in the profile to block the effect.<br />
<br />
I did not bother to find the offending setting in the original Legend profile.<br />
<br />
=== StereoCutoffDepthNear (0x7050e011 / 0x704ef483 / 0x7031de06) ===<br />
<br />
Floating point value used when StereoCutoff is set to 2 to set a threshold depth to stop the UI splitting when it is rendered nearer than this value (someone confirm if that is entirely correct and if this can affect other things besides the UI).<br />
<br />
=== StereoCutoffDepthFar (0x70add220) ===<br />
<br />
Floating point value used when StereoCutoff is set to 1 to set a threshold depth to stop the UI splitting when it is rendered further away than this value (someone confirm if that is entirely correct and if this can affect other things besides the UI).<br />
<br />
=== GameSpecific0 (0x702244b7) ===<br />
<br />
For a DX9 game, this defines which constant register the driver injects the stereo settings in with x = -separation*convergence, y = separation (making the stereo correction formula pos.x += c255.x + c255.y * pos.w). Only vertex shaders that the driver modifies will have anything injected at all. The default is c255, and StereoProfile must be set for this setting to have any effect. Note that unlike the equivelent options for DX11 games, merely accessing this register will *not* neutralise the driver's stereo correction.<br />
<br />
More info: https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4786821/#4786821<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
|19 || MLB2K10<br />
|-<br />
|25 || NBA 2K9<br />
|-<br />
|28 || MLB 2K12, Pro Baseball 2K, NBA 2K12, NBA 2K13<br />
|-<br />
|198 || Alaska, Diablo III<br />
|-<br />
|236 || World Of Warcraft (but note that this profile may be outdated from the old DX9 version)<br />
|-<br />
|248 || Rogue Warrior<br />
|-<br />
|254 || Mafia II, Serious Sam II<br />
|}<br />
<br />
=== DX10VSCBNumber (0x70f8e408 / 0x70f64a32) ===<br />
For a DX10/11 game, this defines which constant buffer the driver uses to inject the stereo parameters into vertex shaders. The first float in the buffer is -separation*convergence, the second is separation, the third seems to be unused and the fourth indicates that 3D Vision is enabled. The default value is cb12. Note that in contrast to the equivelent DX9 option, merely declaring this constant buffer in a shader will disable the driver's built in stereo correction for that shader (for a HLSL shader the buffer must be accessed and the result used in a meaningful way otherwise the compiler will optimise out the declaration).<br />
<br />
More info: https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4786821/#4786821<br />
<br />
Note that constant buffer 14 is reserved for "internal use" and not normally accessible through HLSL (it is defined in shader model 4/5 and declaring it in assembly proves that it does exist and can be used for this purpose, but it is not clear if that might ever interfere with anything else).<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 6 || Metro 2033, Middle-Earth: Shadow of Mordor<br />
|-<br />
| 8 || Assassin's Creed, Fallout 4, Just Cause 3<br />
|-<br />
| 9 || The Witcher 3<br />
|-<br />
| 13 || Mirror's Edge: Catalyst<br />
|-<br />
| 14 || Assassin's Creed: Syndicate, Assassin's Creed: Unity, Dark Souls III, Dead Rising 4, F1 2015 DX12, Grand Theft Auto V, Homefront, Homefront(HOMEFRONT_DX10.exe), Homefront: The Revolution, Rise of the Tomb Raider<br />
|}<br />
<br />
=== DX10DSCBNumber (0x70092d4a) ===<br />
As above, but for tessellation domain shaders.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 8 || Fallout 4, Just Cause 3, Middle-Earth: Shadow of Mordor<br />
|-<br />
| 9 || The Witcher 3<br />
|-<br />
| 13 || Mirror's Edge: Catalyst<br />
|-<br />
| 14 || Assassin's Creed: Syndicate, Assassin's Creed: Unity, Dark Souls III, Dead Rising 4, F1 2015 DX12, Homefront: The Revolution, Rise of the Tomb Raider<br />
|}<br />
<br />
<br />
== More Settings ==<br />
<br />
=== StereoConvergence (0x708db8c5 / 0x7077bace / 0x7084807e) ===<br />
Stores the convergence value of a profile as a floating point value.<br />
<br />
Default Value: 4.0<br />
<br />
=== Comments (0x704d456e) - text ===<br />
Stores the comments displayed in the green text by the driver.<br />
<br />
<br />
=== Developer_Issues (0x704f5928) - text ===<br />
Alternate setting for the comments displayed in the green text by the driver.<br />
<br />
<br />
=== StereoMemoEnabled (0x707f4b45) ===<br />
{| class="wikitable"<br />
| 0x00000000 || Green text disabled<br />
|-<br />
| 0x00000001 || Green text enabled<br />
|}<br />
<br />
<br />
=== Compat (0x7051e5f5) - text ===<br />
<br />
Selects the 3D Vision rating in the green text:<br />
<br />
"0": "3D Vision Ready"<br />
<br />
"1": "Excellent"<br />
<br />
"2": "Good"<br />
<br />
"3": "Fair"<br />
<br />
"4": "Not Recommended"<br />
<br />
"5": "Not Recommended"<br />
<br />
Other observed values: "-1", "101", "102"<br />
<br />
Default value? (crashes): "1000"<br />
<br />
=== PF_Issues (0x704cde5a) - text ===<br />
Comma separated list of letters corresponding to the following issues listed in the green text:<br />
<br />
A: "Incorrect 3D object placement"<br />
<br />
B: "Text/Objects are small and difficult to use"<br />
<br />
C: "Objects clipped at sides of monitor"<br />
<br />
D: "Incorrect clipping of subviews"<br />
<br />
E: "Mixed 2D and 3D objects in Pop-up or HUD"<br />
<br />
F: "Gunsight or Pointer is 2D object"<br />
<br />
G: "Issues with setup screens with stereo on"<br />
<br />
H: "Text highlight for 3D objects is at incorrect depth"<br />
<br />
I: "Bright colors on dark background produce ghosting"<br />
<br />
J: "Excessive use of 2D makes stereo look flat"<br />
<br />
K: Nothing (any more?), but a lot of profiles still mention this<br />
<br />
=== StereoDefaultOn (0x70ab30a7) ===<br />
Defines whether stereo is enabled automatically when the game is launched, or must be manually enabled with Ctrl+T. Useful to set to 0 if having stereo enabled when launching the game breaks something but works when enabled later.<br />
<br />
=== FrustumAdjustMode (0x70a1411a / 0x70ed1da7 / 0x70f475a0) ===<br />
Frustum adjust mode normally adjusted with Ctrl+F11<br />
<br />
{| class="wikitable"<br />
| 0 || No adjustment<br />
|-<br />
| 1 || Stretch<br />
|-<br />
| 2 || Crop<br />
|}<br />
<br />
<br />
== Compatibility Mode Settings ==<br />
<br />
Helifax created a guide with more information about these settings: [https://forums.geforce.com/default/topic/791450/3d-vision/guide-how-to-enable-and-tweak-3d-compatibility-mode-in-any-dx11-game/ Guide: How to Enable and TWEAK 3D Compatibility Mode in any DX11 Game]<br />
<br />
=== 2DDHUDSettings (0x709adada) ===<br />
Controls the compatibility mode settings - overall 3D strength, heuristics to pin the HUD at screen depth, rating.<br />
<br />
<u> Observations from Losti </u><br />
<br />
The below post has been decrypted. The original post is [https://forums.geforce.com/default/topic/791450/3d-vision/guide-how-to-enable-and-tweak-3d-compatibility-mode-in-any-dx11-game/post/4377990/#4377990 here].<br />
<br />
So i have did some investigations with the nvidia used values and i discovered that:<br />
<br />
<u>'''(For Dragon Age: Inquisition)'''</u><br />
<br />
-----------------------<br />
{| class=wikitable<br />
| 0x10000002 || high depth UI and world<br />
|-<br />
| 0x1000000a || high depth UI and world<br />
|-<br />
| 0x1000001a || high depth UI and world<br />
|-<br />
| 0x20000002 || high depth UI and world<br />
|-<br />
| 0x2000000a || high depth UI and world<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x10000015 || no Depth, UI only right eye<br />
|-<br />
| 0x10000102 || low depth UI and world<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x20000006 || UI @ screen depth world high depth<br />
|}<br />
<br />
{| class=wikitable<br />
| 0x51000002 || Game will not have CM<br />
|-<br />
| 0x11000006 || Game will not have CM<br />
|-<br />
| 0x11000002 || Game will not have CM<br />
|-<br />
| 0x41000002 || Game will not have CM<br />
|-<br />
| 0x21000006 || Game will not have CM<br />
|-<br />
| 0x21000002 || Game will not have CM<br />
|}<br />
<br />
own tests:<br />
{| class=wikitable<br />
| 0x20000006 || UI @ screen dempth world high deph<br />
|-<br />
| 0x20000007 || high depth UI and world<br />
|-<br />
| 0x10000036 || UI @ screen depth world high deph<br />
|-<br />
| 0x10000106 || UI @ screen depth world very-LOW deph || EXCELLENT RATING-TEXT<br />
|-<br />
| 0x20000106 || UI @ screen depth world very-LOW deph || GOOD RATING-TEXT<br />
|-<br />
| 0x20000306 || application unknown, no CM<br />
|-<br />
| 0x10000306 || very low Depth, UI only right eye<br />
|-<br />
| 0x10000606 || UI @ screen depth world high deph<br />
|-<br />
| 0x10000706 || very low Depth, UI only right eye<br />
|-<br />
| 0x10000007 || UI @ screen depth world high deph, UI only rigth eye<br />
|-<br />
| 0x10000001 || all is 2D<br />
|-<br />
| 0x10000000 || all is 2D, ALT+TAB=crash<br />
|-<br />
| 0x10000003 || crash<br />
|-<br />
| 0x1000000d || all is 2D, UI only right eye<br />
|-<br />
| 0x1000000c || all is 2D, UI only right eye<br />
|}<br />
<br />
<br />
i think the use of the numbers at the begining (0x20 and 0x10 is fot he GOD or EXCELLENT rating text display)<br />
<br />
'''006''' at the end will give me UI at screen-depth and a 3D world.<br />
<br />
'''002''' at the end will give me UI and a 3D world.<br />
<br />
=== 2DDConvergence (0x709adadb) ===<br />
As the name implies, this is the convergence setting when in compatibility mode.<br />
<br />
=== Disable2DD (0x709adadd) ===<br />
User setting to disable compatibility mode, usually set via hotkey.<br />
{| class=wikitable<br />
| 0x00000000 || Compatibility mode enabled (if supported)<br />
|-<br />
| 0x00000001 || Compatibility mode disabled via Ctrl+Alt+F11<br />
|}<br />
<br />
=== 2DD_Notes (0x709adadc) - text ===<br />
Notes displayed when compatibility mode is enabled<br />
<br />
<br />
== VR Direct Settings ==<br />
<br />
These settings have appeared in recent drivers and are believed to be related to VR Direct:<br />
<br />
=== StereoVRConvergenceBias (0x708db8c6) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00001185 || Batman: Arkham Origins<br />
|-<br />
| 0x0000130b || Devil May Cry 4<br />
|-<br />
| 0x00001a24 || Fable: The Lost Chapters<br />
|-<br />
| 0x00001cdd || Dirt 3<br />
|-<br />
| 0x00002e6b || Portal 2<br />
|-<br />
| 0x0000377c || Nvidia Stereo Test App<br />
|-<br />
| 0x00003c0f || Oil Rush<br />
|-<br />
| 0x0000849d || Serious Sam III<br />
|-<br />
| 0x0000a1a7 || Batman: Arkham City<br />
|-<br />
| 0x0000cd04 || Half-Life 2<br />
|}<br />
<br />
=== StereoVRRefreshRateOverride (0x708db8c8) ===<br />
=== StereoVRVsync (0x708db8c9) ===<br />
<br />
<br />
=== 0x709d3ad2 === <br />
{| class=wikitable<br />
| 0x00000008 || disables mutual exclusion lock for VR runtimes and 3D Vision<br />
|}<br />
<br />
<br />
== Laser Sight Settings ==<br />
<br />
TsaebehT created a guide with more information about these settings: [https://forums.geforce.com/default/topic/813727/guide-correcting-off-centering-lasersight/ Guide: Correcting/Off-Centering LaserSight]<br />
<br />
<br />
=== LaserSightEnabled (0x7054837a) ===<br />
{| class="wikitable"<br />
| 0x00000000 || Laser sight disabled<br />
|-<br />
| 0x00000001 || Laser sight enabled<br />
|}<br />
<br />
<br />
=== LaserXAdjust (0x7057e831) ===<br />
Horizontal adjustment encoded as a hex float between 0.0 (left) and 2.0 (right). Default: 1.0 (center)<br />
<br />
<br />
=== LaserYAdjust (0x70225308) ===<br />
Horizontal adjustment encoded as a hex float between 0.0 (top) and 2.0 (bottom). Default: 1.0 (center)<br />
<br />
<br />
=== LaserZAdjust (0x7014fca2) ===<br />
{| class="wikitable"<br />
| 0x3f800000 || Enables dynamic laser sight depth<br />
|-<br />
| other || Laser sight is either at screen depth or infinity<br />
|}<br />
<br />
=== LaserSightProperty (0x7032243a) ===<br />
Governs the laser sight opacity<br />
<br />
<br />
=== LaserSightTrigger (0x70031b88) ===<br />
<u> Known Values </u><br />
{| class="wikitable"<br />
| 0x00000002 || Gears of War<br />
|}<br />
<br />
=== InGameLaserSight (0x7064f0c2 / 0x70dd2585 / 0x70e7adad) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000000 || Call of Duty: Modern Warfare 2, Call of Duty: Modern Warfare 3, Call of Duty: World at War, Crysis Warhead, Crysis, Divinity 2, Frontlines: Fuel of War, Medal of Honor: Airborne, Stranglehold, Tom Clancy's Rainbow Six: Vegas 2<br />
|-<br />
| 0x00000001 || BlackSite: Area 51, Delta Force: Black Hawk Down, Gears of War, Hellgate: London DX10, Hellgate: London, Kane & Lynch: Dead man, Postal 3, Unreal Tournament 2004<br />
|-<br />
| 0x00000005 || Code of Honor 2, Default.Archcfg, Shell Shock 2<br />
|-<br />
| 0x00000009 || Battlestrike/Armed Forces Series, Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Ghosts, Left 4 Dead 2, Left 4 Dead, Medal of Honor, S.T.A.L.K.E.R.: Call of Pripyat, S.T.A.L.K.E.R.: Shadow of Chernobyl, Terrorist Takedown 2, TimeShift, Unreal Tournament III<br />
|-<br />
| 0x0000000b || F.E.A.R. Perseus Mandate<br />
|-<br />
| 0x0000000d || Borderlands, Half-Life 2<br />
|-<br />
| 0x80000009 || TitanFall<br />
|}<br />
<br />
=== InGameLaserSightDX9States (0x706139ad) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00023322 || Half-Life 2, Left 4 Dead, Left 4 Dead 2<br />
|}<br />
<br />
=== LaserSight (0x7058b6e1 / 0x7031a2e7 / 0x7045b752) ===<br />
Valid values are 0 and 1<br />
<br />
=== LaserSightFile (0x707ac50d) ===<br />
<br />
<br />
=== LaserSightIndex (0x70da83c6) ===<br />
<br />
<br />
=== StereoLaserSightMaxCount (0x70bc864d) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000004 || Unreal Tournament III<br />
|-<br />
| 0x00000006 || Half-Life 2<br />
|-<br />
| 0x00000008 || Call of Duty: Ghosts, Call of Duty: World at War, UberSoldier<br />
|-<br />
| 0x0000000a || F.E.A.R. Perseus Mandate, Left 4 Dead, Left 4 Dead 2<br />
|-<br />
| 0x000000c8 || Tom Clancy's Rainbow Six: Vegas 2<br />
|}<br />
<br />
=== StereoLaserSightCount (0x70077042) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000002 || Gears of War<br />
|-<br />
| 0x00000004 || Unreal Tournament III<br />
|-<br />
| 0x00000008 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Ghosts, Call of Duty: Modern Warfare 3, Call of Duty: World at War, Medal of Honor<br />
|}<br />
<br />
=== Laser Sight Key Bindings ===<br />
==== ToggleLaserSight (0x70b7bd1f) ====<br />
Only works when set via the Registry and not via a Profile.<br />
<br />
<br />
==== LaserAdjustXMinus (0x7048b7dc) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustXPlus (0x70d8bae6) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustYMinus (0x70fb9e1e) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
<br />
==== LaserAdjustYPlus (0x7024eda4) ====<br />
Doesn't seem to work via registry or profile.<br />
<br />
== Misc Key Bindings ==<br />
<br />
These are believed to be key bindings due to their names. These will override the global key bindings in the registry. Some of these settings may not work at all in recent drivers.<br />
<br />
There is a good guide for how these are encoded here: [http://3dvision-blog.com/3053-modifying-all-3d-vision-control-key-combinations-as-you-need/ Modifying All 3D Vision Control Key Combinations as You Need]<br />
<br />
=== StereoToggle (0x70d76b8b) ===<br />
Toggles Stereo on and off (Default: Ctrl+T)<br />
<br />
=== StereoSeparationAdjustLess (0x705d1e02) ===<br />
Reduce separation (Default: Ctrl+F4)<br />
<br />
=== StereoSeparationAdjustMore (0x70ab8d32) ===<br />
Increase separation (Default: Ctrl+F5)<br />
<br />
=== StereoConvergenceAdjustLess (0x70d4add7) ===<br />
Reduce convergence (Default: Ctrl+F5)<br />
<br />
=== StereoConvergenceAdjustMore (0x701ed576) ===<br />
Increase Convergence (Default: Ctrl+F6)<br />
<br />
=== SaveStereoImage (0x70121853) ===<br />
Save a stereo screenshort (Default: Alt+F1)<br />
<br />
=== WriteConfig (0x700498b3) ===<br />
Save the current convergence to a user profile (Default: Ctrl+F7)<br />
<br />
=== DeleteConfig (0x70c73ba2) ===<br />
Delete the game's user profile (Default: Alt+F7)<br />
<br />
=== GammaAdjustMore (0x703f4521) ===<br />
=== GammaAdjustLess (0x70e8420c) ===<br />
<br />
=== StereoVerticalAdjustMore (0x7087fe61) ===<br />
=== StereoVerticalAdjustLess (0x703acfc6) ===<br />
=== StereoHorizontalAdjustMore (0x70062f07) ===<br />
=== StereoHorizontalAdjustLess (0x70871a39) ===<br />
<br />
=== ToggleAutoConvergence (0x70085de3) ===<br />
NOTE: AFAIK this was never implemented<br />
<br />
=== ToggleAutoConvergenceRestore (0x703bc51e) ===<br />
NOTE: AFAIK this was never implemented<br />
<br />
=== RHWAtScreenMore (0x7066a22e) ===<br />
=== RHWAtScreenLess (0x709139ad) ===<br />
=== RHWLessAtScreenMore (0x704e4bca) ===<br />
=== RHWLessAtScreenLess (0x70b378a1) ===<br />
<br />
=== CutoffNearDepthLess (0x70d1bdb5) ===<br />
=== CutoffNearDepthMore (0x7020c991) ===<br />
=== CutoffFarDepthLess (0x704c9a46) ===<br />
=== CutoffFarDepthMore (0x70fbc04d) ===<br />
=== CutoffStepLess (0x704b45c7) ===<br />
=== CutoffStepMore (0x700f2971) ===<br />
<br />
=== GlassesDelayPlus (0x701fc5b4) ===<br />
NOTE: Believed to no longer work in recent drivers<br />
<br />
=== GlassesDelayMinus (0x70b8a743) ===<br />
NOTE: Believed to no longer work in recent drivers<br />
<br />
<br />
== Unidentified Settings ==<br />
<br />
These setting names were found in the driver, but their purpose or whether they are even functional is unknown:<br />
<br />
=== Time (0x70ad05c8) ===<br />
Only present in a handful of profiles and appears to be a UNIX Time value:<br />
<br />
{| class="wikitable"<br />
| 0x53979bf4 || 2014-06-10 23:59:48 GMT || Murdered: Soul Suspect<br />
|-<br />
| 0x5398a3b4 || 2014-06-11 18:45:08 GMT || Enemy Front<br />
|-<br />
| 0x5398cbe8 || 2014-06-11 21:36:40 GMT || Heldric - The legend of the shoemaker<br />
|-<br />
| 0x5398d296 || 2014-06-11 22:05:10 GMT || Eterium<br />
|-<br />
| 0x5398df13 || 2014-06-11 22:58:27 GMT || Blackguards<br />
|-<br />
| 0x539a472e || 2014-06-13 0:34:54 GMT || Port Royale 3<br />
|-<br />
| 0x539f8bfb || 2014-06-17 0:29:47 GMT || Sniper Elite 3<br />
|-<br />
| 0x53ab4828 || 2014-06-25 22:07:36 GMT || GRID Autosport<br />
|}<br />
<br />
=== RunTimeName (0x701a8be4) - text ===<br />
Observed values:<br />
<br />
-007, ACS, armada, bzone, Client, CLIENT, Demo, Engine, FFORCE, game, Game, GameClient, heroes, launcher, LithTech, main, mainapp, NoName, PG3, PNOCOMP, Pool, Prism3d, program, rally, sw, SW, tm, UDK, wcdemo, WRUN,<br />
<br />
=== EnableConsumerStereoSupport (0x70cb9168) ===<br />
=== StereoViewer (0x704915a1) ===<br />
=== StereoViewerType (0x708f9ef7) ===<br />
=== ShowAllViewerTypes (0x708e5cb4) ===<br />
=== StereoAdjustEnable (0x70538ab1) ===<br />
=== StereoDisableTnL (0x70633bd9) ===<br />
=== StereoTransformationType (0x70c27e3c) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || ghost<br />
|}<br />
<br />
=== StereoSeparation (0x70933c00) ===<br />
This does not seem to have any affect on the separation in other games.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 2 || AngleLib<br />
|}<br />
<br />
=== StereoSeparationStep (0x7082555b) ===<br />
=== StereoConvergenceMultiplier (0x70efbb5b) ===<br />
Default value: 5.0<br />
<br />
=== RHW2DDetectionMin (0x7029432b) ===<br />
=== RHWGreaterAtScreen (0x702c861a) ===<br />
Floating point value<br />
<br />
=== RHWEqualAtScreen (0x70ab2e09) ===<br />
'''NOT''' a floating point value.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || V-Rally 2, h2wof<br />
|}<br />
<br />
=== RHWLessAtScreen (0x70381472) ===<br />
Floating point value<br />
<br />
=== AutoConvergence (0x702a0ab2) ===<br />
Looking over the list of games with this setting I suspect this is a very old feature that well and truly pre-dates DX9 and probably won't work in any modern game.<br />
<br />
<u> Known Values </u><br />
<br />
A considerable number of profiles have this set to 0, which may be meaningless if 0 is the default, but that would be unusual to have so many profiles specify the default.<br />
<br />
{| class="wikitable"<br />
| 0 || "Alien vs Predator 2", "Archlords", "Arcsoft Media Converter", "Armies of Exigo", "Army Men RTS", "BackyardBaseball2005", "Battlefield 1942", "Battlefield 2", "Battlefield Vietnam", "Black and White 2", "Black and White 2: Battle of the Gods", "Boarder Zone", "Colin McRae Rally 5", "Comanche 4", "Combat Flight Simulator 3", "Combat Mission", "Cricket 2005", "Dark Messiah of Might and Magic", "Delta Force 3: Land Warrior(Dflw.exe)", "Delta Force: Xtreme", "Diplomacy", "Driver 3", "Elder Scrolls 3: Morrowind", "Evolva", "Expert Pool", "ExtConverter", "F.E.A.R.", "FIFA Soccer 2004(fifa2004.exe)", "FIFA Soccer 2005", "FIFA Soccer 2006", "Fable: The Lost Chapters", "Far Cry", "Firestarter", "Freelancer", "GUN", "Ghost Recon: Advanced Warfighter(Demo)", "Godfather: The game", "Google Chrome", "Gothic 2", "Ground Control 2", "Gun Metal", "Harry Potter And The Goblet Of Fire", "Harry Potter Quidditch World Cup", "Harry Potter and the Prizoner of Azkaban", "Hidden & Dangerous 2", "High Heat Major League Baseball 2004", "Hitman: Blood Money", "Impossible Creatures", "Independence War 2 - Edge of Chaos", "Jetfighter 2015", "Joint Operations: Typhoon Rising", "Knight Shift", "Kohan 2", "LEGO Star Wars", "LOTR bat2", "Lock On", "Lord of the Rings: Return of the King", "Lords of the Realm 3", "MVP Baseball 2003", "MVP Baseball 2004", "MVP Baseball 2005", "Mafia", "Manhunt", "Massive Assault", "Max Payne 2", "MechWarrior IV Mercenaries", "Men of Valor:Vietnam", "Microsoft Flight Simulator 2004", "Microsoft Train Simulator", "Midnight Club II", "Motocross Madness 2", "Mount & Blade: With Fire & Sword", "Movavi Video Converter", "Myst 4", "NASCAR SimRacing", "NBA Live 2004", "NBA Live 2005", "NBA Live 2006", "NHL 2003(nhl2003.exe)", "NHL 2005", "NHL 2006", "Nexus: The Jupiter Incident (DX9 version)", "No One Lives Forever 2", "No man's land", "Painkiller", "Paradise Cracked", "Pariah", "Perimeter", "Psychonauts", "Rainbow Six 3: Raven Shield", "Red Faction II", "Republic", "Rise and Fall: Civilizations at War", "RollerCoaster Tycoon 3", "Rome - Total War", "Roo Goo", "Roxio Video Converter", "Rugby2004", "SHGame", "Sid Meier's Pirates!", "Silent Hunter III", "Sims 2 - University", "Sims 2", "Sims 2: Nightlife", "Space Station Manager", "Spellforce 2", "Spellforce", "Splinter Cell: Chaos Theory", "Splinter Cell: Pandora Tomorrow", "Squad Assault - West Front", "Star Wars: Battlefront (2004)", "Star Wars: Battlefront II", "Star Wars: Republic Commando", "SupremeRuler", "Syberia 2", "Teenage Mutant Ninja Turtles", "Temple of Elemental Evil", "Terminator 3: War of the Machines", "The Bard's Tale", "The Incredibles", "The Simpsons: Hit and Run", "Tiger Woods PGA Tour 05", "Tiger Woods PGA Tour 06", "Tony Hawk's Underground", "Trackmania - Sunrise", "Unreal 2", "Vampire The Masquerade - Bloodlines", "WARHAMMER 40k Fire Warrior", "Warcraft III", "Warhammer 40000: Dawn of War - Winter Assault", "Warhammer 40000: Dawn of War", "Warrior Kings - Battles", "Webhead", "Winning Eleven 7", "X-Men Legends II: Rise of Apocolypse", "X2: Wolverine's Revenge", "ffvt3rd", "grand theft auto_sa"<br />
|-<br />
| 1 || "Apache: Air Assault", "Archlords", "Arcsoft Media Converter", "BlackSite: Area 51", "Championship BASS", "Combat Mission", "Crusaders of Might and Magic", "Dagoth Moor Zoological Gardens", "Darkstone", "Descent FreeSpace 2", "End of Nations", "European Air War", "Exodus from the Earth", "Expert Pool", "ExtConverter", "Extreme Biker", "Flesh Feast", "G-Police", "Grandia2", "Hot Chix 'n' Gear Stix", "Incomming", "Interstate '82", "Legends of the Seers", "Luftwaffe Commander", "Madden NFL Games", "Michelle Kwan Figure Skating(kwandemo.exe)", "Microsoft Baseball 2001", "Mount & Blade: With Fire & Sword", "Movavi Video Converter", "NASCAR 2000(NASCAR 2000 Demo.exe)", "NASCAR 2000(NASCAR 2000.exe)", "NASCAR Heat", "NASCAR Legends", "Omikron: The Nomad Soul(Nomad.exe)", "Pong", "Professional Bull Rider", "Renegade Racers(rrDemo.exe)", "Rocketsled", "Roo Goo", "Roxio Video Converter", "Test Drive 6", "Topspin", "True Crime: Streets of LA", "Up", "Wartorn"<br />
|}<br />
<br />
=== AutoConvergenceAdjustPace (0x70bf3c6b) ===<br />
Floating point value, which is almost always set to 0.05 (except for Combat Mission, where it is set to 1.0). Note that this is present in a number of profiles that lack AutoConvergence.<br />
<br />
=== StereoToggleMode (0x70d76b8c) ===<br />
=== StereoSuggestSettings (0x706315af) ===<br />
=== StereoUnsuggestSettings (0x7017861c) ===<br />
=== FavorSZ (0x705faed7) ===<br />
=== StereoPointer (0x70364596) ===<br />
Only seen in "Sims 2 - University" and "Sims 2: Nightlife", where this is set to 1. Note that this is not present in the base Sims 2 profile or any of the other Sims 2 profiles.<br />
<br />
=== MonitorSize (0x7086ebe9) ===<br />
=== MaxMonitorSize (0x7032022c) ===<br />
=== MaxVertexCount (0x709e4a94) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000002 || Half-Life 2<br />
|-<br />
| 0x00010000 || Arabian Nights<br />
|}<br />
<br />
=== PartialClearMode (0x709794cc) ===<br />
=== StereoRefreshDefaultOn (0x702ba385) ===<br />
=== MixedTnL (0x70bd11e0) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark01", "3DMark03", "3DMark05", "James Bond Nightfire", "Need for Speed Hot Pursuit 2(Nfshp2.exe)", "Need for Speed Hot Pursuit 2(NFSHP2Demo.exe)"<br />
|}<br />
<br />
=== StereoGamma (0x70c8b5d1) ===<br />
=== LineCodeColor (0x70dc4a12) ===<br />
=== LeftAnaglyphFilter (0x70d51cd1) ===<br />
=== RightAnaglyphFilter (0x70f4a930) ===<br />
=== InterleavePattern0 (0x70b1c8cc) ===<br />
=== InterleavePattern1 (0x7091a772) ===<br />
=== StereoForceVSync (0x70aae185) ===<br />
=== StereoColorKey (0x70e5773b) ===<br />
Only present in the "NV Pinball" profile, where it is set to 0x00010101<br />
<br />
=== ZDirection (0x70b17872) ===<br />
=== StereoCompatibility (0x70a2000e) ===<br />
=== LeftColorFilter0 (0x70ac6888) ===<br />
=== LeftColorFilter1 (0x7090b6ca) ===<br />
=== RightColorFilter0 (0x70b9a2f7) ===<br />
=== RightColorFilter1 (0x70aca0cc) ===<br />
=== SharpVPI (0x706e0041) ===<br />
=== StereoMode (0x701baa09) ===<br />
=== Watchdog (0x700a5654) ===<br />
=== StereoOSDEnable (0x70f455aa) ===<br />
=== StereoOrthoEnable (0x703564f6) ===<br />
An Orthographic projection does not ordinarily involve a perspective divide, and therefore it stands to reason that these games may use a slightly different stereo correction formula.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Halo", "Midnight Club II(mc2_demo.exe)", "Port Royale", "Sims 2 - University", "Sims 2", "Sims 2: Nightlife"<br />
|}<br />
<br />
=== StereoNotSupported (0x709aa171) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark Ice Storm", "3DMark", "3DMark11", "3DMark14", "All Play-On-line Games", "Evolve", "Final Fantasy XIV: A Realm Reborn", "NVIDIA NVFBC Applications", "NVKeystone", "Resident Evil: Revelations 2 / Biohazard Revelations 2", "Ryse: Son of Rome", "Sid Meier's Civilization: Beyond Earth", "VRP", "Windows Live Mail", "Windows Live Photo Gallery", "Windows Movie Maker", "WLXPGSS"<br />
|}<br />
<br />
=== ModesetWarning (0x70969bb0) ===<br />
=== StereoFirstTime (0x70af6400) ===<br />
=== StereoRefreshRate (0x70ded3c0) ===<br />
=== GameConfigs (0x704a905a) ===<br />
=== CompareEyes (0x70729e58) ===<br />
=== CompareFrom (0x70efb726) ===<br />
=== StereoImageType (0x7097906c) ===<br />
=== SnapShotQuality (0x7004e7a6) ===<br />
=== NoLockSubstitute (0x7005ad16) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "3DMark03", "3DMark05", "Bumper to Bumper", "S.T.A.L.K.E.R.: Shadow of Chernobyl", "Star Wraith 3: Shadows of Orion", "World Dance"<br />
|}<br />
<br />
=== PushbufSubstituteSize (0x7054fbf8) ===<br />
=== DiscardHotkeys (0x70175566) ===<br />
=== StereoLCDPatternType (0x707cfb97) ===<br />
=== GlassesSwitchDelay (0x70057bb6) ===<br />
<br />
Valid values appear to be between 5 <= GlassesSwitchDelay < 95<br />
<br />
=== StartZBit (0x7044d7a6) ===<br />
=== DisableOnOutOfMemory (0x70c71508) ===<br />
=== StereoWindowedEnable (0x709b3484) ===<br />
=== AllowNonExclusiveStereo (0x702c7709) ===<br />
=== Rhwinf (0x706e1913 / 0x70cc286a / 0x70a3fee6) ===<br />
Floating point value set in 26 profiles with values ranging from 0.00003125 to 0.04<br />
<br />
RHW stands for Reciprocal of Homogeneous W, really just a fancy term for 1 / linear depth. inf is presumably short for infinite depth.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.00003125 || Gears of War<br />
|-<br />
| 0.000062500985 || Unreal Tournament III<br />
|-<br />
| 0.00006666667 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Modern Warfare 3, Damnation, F.E.A.R. Perseus Mandate, Frontlines: Fuel of War, Left 4 Dead 2, Left 4 Dead, Medal of Honor, Mirror's Edge, TimeShift, Tom Clancy's Rainbow Six: Vegas 2<br />
|-<br />
| 0.0001 || F.E.A.R. 2: Project Origin, Gears of War(wargame-g4wlive_DX10.exe), Half-Life 2, Mass Effect 2, Mass Effect, Shell Shock 2, Stranglehold<br />
|-<br />
| 0.00025 || The haunted Hells Reach<br />
|-<br />
| 0.00066666666 || Q.U.B.E.<br />
|-<br />
| 0.01 || Kane & Lynch: Dead man, Serious Sam III<br />
|-<br />
| 0.04 || The Club<br />
|}<br />
<br />
=== Rhwscr (0x70a4995c / 0x7030b071 / 0x70b57ed1) ===<br />
Floating point value set in 29 profiles with values ranging from 0.05 to 1.0<br />
<br />
Presumably related to Rhwinf, and "scr" is likely short for screen depth.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.05 || The Club, Tom Clancy's Rainbow Six: Vegas 2, Unreal Tournament III<br />
|-<br />
| 0.06666667 || Call of Duty 2, Call of Duty 4: Modern Warfare, Call of Duty: Modern Warfare 3, Gears of War, Medal of Honor, TimeShift<br />
|-<br />
| 0.1 || Damnation, F.E.A.R. 2: Project Origin, Frontlines: Fuel of War, Gears of War(wargame-g4wlive_DX10.exe), Half-Life 2, Mass Effect 2, Mass Effect, Mirror's Edge, Q.U.B.E., Shell Shock 2, Stranglehold, The haunted Hells Reach"<br />
|-<br />
| 0.11111111 || Left 4 Dead, Left 4 Dead 2<br />
|-<br />
| 0.125 || BlackSite: Area 51<br />
|-<br />
| 0.15 || TitanFall<br />
|-<br />
| 0.2 || Call of Duty: World at War, F.E.A.R. Perseus Mandate<br />
|-<br />
| 1.0 || Kane & Lynch: Dead man, Serious Sam III<br />
|}<br />
<br />
=== Zinf (0x70fc13ad) ===<br />
At a guess this is probably similar to Rhwinf, but uses the output Z coordinate of the vertex shader instead of the output W coordinate.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0.0 || Call of Duty: Ghosts<br />
|}<br />
<br />
=== Zscr (0x707f0e69) ===<br />
At a guess this is probably similar to Rhwscr, but uses the output Z coordinate of the vertex shader instead of the output W coordinate. Presumably related to Zinf in the same way Rhwscr is related to Rhwinf.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1.0 || Call of Duty: Ghosts<br />
|}<br />
<br />
=== EnableCE (0x702b8c95) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Age of Empires III", "Age of Empires III - The War Chiefs", "Age of Empires III: The Asian Dynasties"<br />
|}<br />
<br />
=== MediaPlayer (0x70a8fc7f) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "BaoFeng / Storm Player", "Cyberlink PowerDVD", "Cyberlink PowerDVD10", "Cyberlink PowerDVD9", "Movie Studio Platinum 12", "PixEVRComponentTest", "Sony Media Gallery", "Sony Vegas Pro", "Stereoscopic Player", "VFTV", "Vegas Movie Studio HD Platinum 11", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoDX9 (0x70d10d2b) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "AZMD! Scorepocalypse", "Adam's Venture Episode 1", "Afterfall: InSanity", "Alan Wake's American Nightmare", "All Zombies Must Die", "Battlefield: Bad Company 2", "Borderlands 2", "Bullet Run", "Choplifter HD", "Counter-strike: Global Offensive", "Crysis 2", "Da Vinci Online", "Dear Esther", "Deus Ex: Human Revolution", "Dishonored", "DmC-Devil May Cry", "Duke Nukem Forever", "End of Nations", "Far Cry 2", "Gears of War", "Hawken", "Mars", "Painkiller Hell & Damnation", "Q.U.B.E.", "Quan Qiu Shi Ming(MarsGame.exe)", "Red Orchestra 2: Heroes of Stalingrad", "Risen 2: Dark Waters", "Section 8: Prejudice", "Spec Ops: The Line", "The Ball", "The Witcher 2: Assassins of Kings", "The haunted Hells Reach", "Tony Hawk's Pro Skater HD", "Tribes Ascend", "WARP", "War of the Roses", "World in Conflict", "XCOM: Enemy Unknown"<br />
|}<br />
<br />
=== StereoMsgVerticalOffset (0x70160ebf) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 16 || Assassin's Creed(DX9)<br />
|}<br />
<br />
=== StereoEasyZCheck (0x70b6d6ed) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Half-Life 2", "Kane & Lynch: Dead man", "Mass Effect 2", "Mass Effect", "Shell Shock 2", "Stranglehold", "The Club", "TimeShift", "Tom Clancy's Rainbow Six: Vegas 2"<br />
|}<br />
<br />
=== StereoStrictLSCheck (0x709bc378) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "Half-Life 2", "Tom Clancy's Rainbow Six: Vegas 2"<br />
|}<br />
<br />
=== StereoDisableAsync (0x70de5533) ===<br />
=== EnablePartialStereoBlit (0x7096eced) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "BaoFeng / Storm Player", "Flash(Firefox)", "NVIDIA Stereoscopic 3D video player", "NVStWiz", "Sony Media Gallery", "Stereoscopic Player", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoNoDepthOverride (0x709dea62) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 1 || "NVIDIA Stereoscopic 3D video player", "Novlum Demes Editor", "NvStView", "Sony Media Gallery", "Stereoscopic Player", "Trine 3", "Windows Media Center", "Windows Media Player"<br />
|}<br />
<br />
=== StereoShaderMatrixCheck (0x7044f8fb) ===<br />
=== StereoLogShaders (0x7052bdd0) ===<br />
=== StereoEpsilon (0x70e5a749) ===<br />
Floating point value seen in 46 profiles. Observed values: 0.00000088, 0.0000088, 0.000088<br />
<br />
=== DelayedStereoDesktop (0x7042eef1) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000001 || Half-Life 2, Tom Clancy's H.A.W.X.<br />
|-<br />
| 0x00140002 || Fallout 3<br />
|}<br />
<br />
=== StereoMiscFlags (0x70ccb5f0) ===<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 0x00000006 || PixEVRComponentTest<br />
|-<br />
| 0x00000008 || Assassin's Creed: Unity, Diablo III<br />
|-<br />
| 0x00000010 || Depth Hunter, Elder Scrolls V: Skyrim, End of Nations, Strike Suit Zero, The Walking Dead 2, The Walking Dead<br />
|-<br />
| 0x00000020 || Star Trek<br />
|-<br />
| 0x00000080 || Stereoscopic Player<br />
|-<br />
| 0x00000086 || Cyberlink PowerDVD10, VFTV<br />
|-<br />
| 0x00000100 || Biohazard 5, Devil May Cry 4(DX9), Lost Planet 2, Resident Evil 5<br />
|-<br />
| 0x00000400 || Homefront: The Revolution<br />
|-<br />
| 0x00000c06 || Cyberlink PowerDVD<br />
|-<br />
| 0x00000c86 || Cyberlink PowerDVD9<br />
|}<br />
<br />
=== StereoHiddenProfile (0x70e46f20) ===<br />
<u> Known Values </u><br />
<br />
A considerable number of profiles have this set to 0, which may be meaningless if 0 is the default, but that would be unusual to have so many profiles specify the default.<br />
<br />
{| class="wikitable"<br />
| 0 || "ACS", "armada", "bzone", "Client.exe", "Crysis", "Demo", "Dragon : MMORPG", "Freedom Force", "Game.exe", "GameClient.exe", "Google Chrome", "Hunting 4", "LithTech", "Madden NFL Games", "Microsoft Internet Explorer", "Mozilla FireFox - Plugin Container", "Mozilla Firefox", "Nations", "nfs", "NoName", "Novlum Demes Editor", "Panzer General 3 Scorched Earth(PG3.exe)", "Pencil Whipped", "Prince of Persia", "program", "rally", "S.T.A.L.K.E.R.: Clear Sky", "Safari Congo", "Ship Simulator 2006", "SW", "Ultimate 8 Ball", "WRUN"<br />
|- <br />
| 1 || "AngleLib", "engine", "heroes", "launcher", "UDK (Unreal Development Kit) based games"<br />
|}<br />
<br />
=== StereoLinkDll (0x70e46f2a) - text ===<br />
<br />
Appears to be a comma separated list of files to search for. At a guess, if this setting is present these files either must or must not exist for stereo to engage.<br />
<br />
=== EnableStereoCursor (0x70e46f2b) ===<br />
=== CreateStereoDTAfterPresentNum (0x70a7fc7f) ===<br />
To confirm, but presumably delays initialising 3D Vision until the game has drawn this number of frames, possibly to work around crashes on launch or other issues caused by 3D Vision being enabled when the game is launched, but works if enabled later.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| 3 || Cyberlink PowerDVD9<br />
|-<br />
| 50 || Call of Duty Online<br />
|}<br />
<br />
=== Date_Rel (0x705fafec) - text ===<br />
May contain the release date in the form YYYY-MM-DD 00:00:00<br />
<br />
=== Game (0x70c8d48e) - text ===<br />
=== Style (0x709cc5e0) - text ===<br />
<br />
Contains the game's genre, such as "Action", etc.<br />
<br />
=== Publisher (0x706c7030) - text ===<br />
<br />
Lists the game's publisher.<br />
<br />
=== Developer (0x703c4026) - text ===<br />
<br />
Lists the game's developer.<br />
<br />
=== API (0x70b5603f) - text ===<br />
Usually contains "D3D", other observed values include "d3d", "D3d", "D3D_", "OGL_" and "S/W"<br />
<br />
=== Value (0x7049c7ec) ===<br />
Observed values: "0", "0.0", "1", "1.0", "2", "2.0", "3", "3.0", "4", "4.0", "5", "5.0", "101.0", "102.0"<br />
<br />
=== P1SH0 (0x70998683) - text ===<br />
=== V1SH0 (0x70e6a3cf) - text ===<br />
=== PSH0 (0x7046516e) - text ===<br />
=== VSH0 (0x708b7af8) - text ===<br />
At a guess this might stand for "Vertex Shader Hash 0" and define some kind of override for a specific vertex shader, perhaps to force the stereo correction on or off for a particular shader.<br />
<br />
<u> Known Values </u><br />
<br />
{| class="wikitable"<br />
| "1162e513 0 1" || Gears of War<br />
|-<br />
| "6e34f93f 0x01 0 0 0 0 0" || AngleLib<br />
|-<br />
| "D162E513 0 1" || Batman: Arkham Asylum<br />
|}<br />
<br />
=== VSH1 (0x708b7af9) - text ===<br />
=== VSH2 (0x708b7afa) - text ===<br />
=== VSH3 (0x708b7afb) - text ===<br />
=== VSH4 (0x708b7afc) - text ===<br />
=== VSH5 (0x708b7afd) - text ===<br />
=== VSH6 (0x708b7afe) - text ===<br />
=== VSH7 (0x708b7aff) - text ===<br />
=== VSH8 (0x708b7b00) - text ===<br />
=== VSH9 (0x708b7b01) - text ===<br />
=== VSH10 (0x708b7b02) - text ===<br />
<br />
== Registry Settings ==<br />
<br />
These are settings discovered in the 3D Vision driver that are not listed in the profile table, meaning they can only be set via the registry or (in some cases) control panel. Other settings on this page may (or may not) also be placed in the registry.<br />
<br />
On a 64bit OS these settings are under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\NVIDIA Corporation\Global\Stereo3D<br />
<br />
This section is incomplete.<br />
<br />
=== MonitorSizeOverride ===<br />
Overrides MonitorSize, but is not reset constantly making it a superior option to depth hacks.<br />
<br />
=== DrsEnable ===<br />
Enables the use of driver profiles.<br />
<br />
=== 0x1800babe ===<br />
That's not a hex value - that's a literal name of a possible registry key, including the "0x".<br />
<br />
=== StereoAdvancedHKConfig ===<br />
=== StereoFullHKConfig ===<br />
=== StereoCompatibility ===<br />
=== EnablePersistentStereoDesktop ===<br />
=== EnableWindowedMode ===<br />
=== StereoIROutput ===<br />
=== StereoFlywheelCycleState ===<br />
=== StereoFlywheelCycle ===<br />
=== StereoVBIOverride ===<br />
=== ContrastOverride ===<br />
=== MultiheadMode ===<br />
=== SOLPerf ===<br />
=== EnableAPILog ===<br />
=== EnableHDMICheckerboard ===<br />
=== ContrastOverrideLog ===<br />
=== StereoKiosk ===<br />
=== DisablePatternWindowedMode ===<br />
=== StereoForcePairFlip ===<br />
=== __S ===<br />
=== SDStereoType ===<br />
=== StereoAnaglyphType ===<br />
=== StereoDisabled ===<br />
=== HDMIBroadcast ===<br />
=== Broadcast3way ===<br />
=== IGBroadcast ===<br />
=== SLIOverride ===<br />
=== UseCE ===<br />
=== ResourceTracking ===<br />
=== EnableIE9HTML5 ===<br />
=== IE9HTML5Width ===<br />
=== IE9HTML5Height ===<br />
=== IE9HTML5Layout ===<br />
<br />
== More Registry Settings ==<br />
On a 64bit OS these settings are under HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\NVIDIA Corporation\Global\Stereo3DPersistent<br />
<br />
=== 3D Vision ===<br />
=== Count ===</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Canonical_Stereo_CodeCanonical Stereo Code2016-10-28T23:29:01Z<p>Bo3b admin: </p>
<hr />
<div>=== Prime Directive ===<br />
<br />
This is the ''prime directive'' code in ASM for DX9 and HelixMod. And the HLSL version for 3Dmigoto. In all cases, we are implementing the NVidia specified formula of: <br><br><br />
<code>clipPos.x += EyeSign * Separation * ( clipPos.w – Convergence )</code><br />
<br />
<br />
''''' ASM (both HelixMod and 3Dmigoto ASM) '''''<br />
<br />
This is the wordy version with extra comments to make it more clear what is happening.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// The required constant for txldl in c200.z<br />
def c200, 1.0, 600, 0.0625, 0<br />
// Sampler used to fetch stereo params, <br />
// s0 sampler is default for VS<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
// Fetch the Separation (r30.x) and Convergence (r30.y) <br />
// using the Helix NVapi trick<br />
texldl r30, c200.z, s0<br />
<br />
// (W - Convergence)<br />
add r30.w, r0.w, -r30.y<br />
<br />
// multiply that times Separation for:<br />
// Separation * (W - Convergence)<br />
mul r30.z, r30.x, r30.w<br />
<br />
// Add that to Xold for the complete:<br />
// Xold + Separation * (W - Convergence)<br />
add r0.x, r0.x, r30.z<br />
<br />
</syntaxhighlight><br />
<br />
<br />
Another variant that is more concise, but less clear. As you get more accustomed to seeing this sequence of code, or are sharing with an expert crowd, it's less necessary to fully document this part, as it is always the same sequence and easy to recognize because of the texldl of 0.0625.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mad r0.x, r30.x, r30.w, r0.x<br />
</syntaxhighlight><br />
<br />
<br />
Another very common variant you'll see in HelixMod fixes is the four line version, with no comments. This is less optimal than the two above, but is worth seeing to be able to recognize it.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mul r30.z, r30.x, r30.w<br />
add r0.x, r0.x, r30.z<br />
</syntaxhighlight><br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The HLSL version is very similar, but since it's a compile language there is no need to be terse when writing the code. We can make it "self-documenting" by using good variable names.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// .Load should only be done once, but can be done anywhere in the code.<br />
<br />
float4 stereo = StereoParams.Load(0);<br />
float separation = stereo.x; float convergence = stereo.y;<br />
<br />
// At this point, "location" is the output position, but missing stereo.<br />
<br />
location.x += separation * (location.w - convergence);<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
=== Matrix Inversion ===<br />
<br />
We often need to invert a ViewProjectionMatrix, in order to be able to stereo correct a location in the proper viewspace (usually projection space for deferred rendering).<br />
<br />
We only need to do this in cases where the inverted matrix is not available. A lot of games have both matrices available, and can be used directly. <br />
<br />
We have code samples for both ASM, and for HLSL. It's worth noting that for HelixMod fixes in DX9, that HelixMod already supports [[HelixMod_Feature_List#InverseMatrix.2C_InverseMatrix1|inverted matrices]] directly, and this code should not be used there, because all this extra code will impact performance. Try to avoid using it in PS in particular, because inverting a matrix for every pixel is very costly.<br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The '''best''' way to invert a matrix is to use the runtime shader feature from d3dx.ini. This is best because it runs once per frame, which keeps a performance impact low. This was created by ''DarkStarSword''.<br />
<br />
[https://github.com/bo3b/3Dmigoto/wiki/Injecting-custom-shaders Described here] The actual shader is found [https://github.com/DarkStarSword/3d-fixes/blob/e0f67a3bed5fa90d8823a31b014e607f51c4fefc/inverse-cs.hlsl here] And, how to use it, described [https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4909267/#4909267 here]<br />
<br />
<br />
If that doesn't work for some reason (not all games are compatible), it's possible to do it in HLSL directly. This example is backwards in that it starts with an inverted matrix, then creates the forward matrix from that. Used in an example [https://github.com/DarkStarSword/3d-fixes/blob/master/Mad%20Max/ShaderFixes/01037617f0200a5c-ps_replace.txt here] Again, it's worth noting that doing this in a PS shader is sub-optimal.<br />
<br />
<br />
This version is found in matrix.hlsl, created by ''DarkStarSword''. It can be added into the header of any HLSL file, or #included.<br />
<br />
An original can be found [https://github.com/DarkStarSword/3d-fixes/blob/master/ABZU/ShaderFixes/matrix.hlsl here]<br />
<syntaxhighlight lang="c"><br />
matrix inverse(matrix m)<br />
{<br />
matrix inv;<br />
<br />
float det = determinant(m);<br />
inv[0].x = m[1].y*(m[2].z*m[3].w - m[2].w*m[3].z) + m[1].z*(m[2].w*m[3].y - m[2].y*m[3].w) + m[1].w*(m[2].y*m[3].z - m[2].z*m[3].y);<br />
inv[0].y = m[0].y*(m[2].w*m[3].z - m[2].z*m[3].w) + m[0].z*(m[2].y*m[3].w - m[2].w*m[3].y) + m[0].w*(m[2].z*m[3].y - m[2].y*m[3].z);<br />
inv[0].z = m[0].y*(m[1].z*m[3].w - m[1].w*m[3].z) + m[0].z*(m[1].w*m[3].y - m[1].y*m[3].w) + m[0].w*(m[1].y*m[3].z - m[1].z*m[3].y);<br />
inv[0].w = m[0].y*(m[1].w*m[2].z - m[1].z*m[2].w) + m[0].z*(m[1].y*m[2].w - m[1].w*m[2].y) + m[0].w*(m[1].z*m[2].y - m[1].y*m[2].z);<br />
inv[1].x = m[1].x*(m[2].w*m[3].z - m[2].z*m[3].w) + m[1].z*(m[2].x*m[3].w - m[2].w*m[3].x) + m[1].w*(m[2].z*m[3].x - m[2].x*m[3].z);<br />
inv[1].y = m[0].x*(m[2].z*m[3].w - m[2].w*m[3].z) + m[0].z*(m[2].w*m[3].x - m[2].x*m[3].w) + m[0].w*(m[2].x*m[3].z - m[2].z*m[3].x);<br />
inv[1].z = m[0].x*(m[1].w*m[3].z - m[1].z*m[3].w) + m[0].z*(m[1].x*m[3].w - m[1].w*m[3].x) + m[0].w*(m[1].z*m[3].x - m[1].x*m[3].z);<br />
inv[1].w = m[0].x*(m[1].z*m[2].w - m[1].w*m[2].z) + m[0].z*(m[1].w*m[2].x - m[1].x*m[2].w) + m[0].w*(m[1].x*m[2].z - m[1].z*m[2].x);<br />
inv[2].x = m[1].x*(m[2].y*m[3].w - m[2].w*m[3].y) + m[1].y*(m[2].w*m[3].x - m[2].x*m[3].w) + m[1].w*(m[2].x*m[3].y - m[2].y*m[3].x);<br />
inv[2].y = m[0].x*(m[2].w*m[3].y - m[2].y*m[3].w) + m[0].y*(m[2].x*m[3].w - m[2].w*m[3].x) + m[0].w*(m[2].y*m[3].x - m[2].x*m[3].y);<br />
inv[2].z = m[0].x*(m[1].y*m[3].w - m[1].w*m[3].y) + m[0].y*(m[1].w*m[3].x - m[1].x*m[3].w) + m[0].w*(m[1].x*m[3].y - m[1].y*m[3].x);<br />
inv[2].w = m[0].x*(m[1].w*m[2].y - m[1].y*m[2].w) + m[0].y*(m[1].x*m[2].w - m[1].w*m[2].x) + m[0].w*(m[1].y*m[2].x - m[1].x*m[2].y);<br />
inv[3].x = m[1].x*(m[2].z*m[3].y - m[2].y*m[3].z) + m[1].y*(m[2].x*m[3].z - m[2].z*m[3].x) + m[1].z*(m[2].y*m[3].x - m[2].x*m[3].y);<br />
inv[3].y = m[0].x*(m[2].y*m[3].z - m[2].z*m[3].y) + m[0].y*(m[2].z*m[3].x - m[2].x*m[3].z) + m[0].z*(m[2].x*m[3].y - m[2].y*m[3].x);<br />
inv[3].z = m[0].x*(m[1].z*m[3].y - m[1].y*m[3].z) + m[0].y*(m[1].x*m[3].z - m[1].z*m[3].x) + m[0].z*(m[1].y*m[3].x - m[1].x*m[3].y);<br />
inv[3].w = m[0].x*(m[1].y*m[2].z - m[1].z*m[2].y) + m[0].y*(m[1].z*m[2].x - m[1].x*m[2].z) + m[0].z*(m[1].x*m[2].y - m[1].y*m[2].x);<br />
inv /= det;<br />
<br />
return inv;<br />
}<br />
<br />
matrix inverse(float4 m0, float4 m1, float4 m2, float4 m3)<br />
{<br />
return inverse(matrix(m0, m1, m2, m3));<br />
}<br />
<br />
#define MATRIX(cb, idx) matrix(cb[idx], cb[idx+1], cb[idx+2], cb[idx+3])<br />
</syntaxhighlight><br />
<br />
<br />
<br />
<br />
The original version of this came from ''Mike_ar69''.<br />
<syntaxhighlight lang="c"><br />
...<br />
matrix ivp, vp;<br />
ivp = matrix(InstanceConsts[1], InstanceConsts[2], InstanceConsts[3], InstanceConsts[4]);<br />
<br />
// Work out the view-projection matrix from it's inverse:<br />
vp[0].x = ivp[1].y*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[1].z*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[1].w*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y);<br />
vp[0].y = ivp[0].y*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[0].z*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[0].w*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z);<br />
vp[0].z = ivp[0].y*(ivp[1].z*ivp[3].w - ivp[1].w*ivp[3].z) + ivp[0].z*(ivp[1].w*ivp[3].y - ivp[1].y*ivp[3].w) + ivp[0].w*(ivp[1].y*ivp[3].z - ivp[1].z*ivp[3].y);<br />
vp[0].w = ivp[0].y*(ivp[1].w*ivp[2].z - ivp[1].z*ivp[2].w) + ivp[0].z*(ivp[1].y*ivp[2].w - ivp[1].w*ivp[2].y) + ivp[0].w*(ivp[1].z*ivp[2].y - ivp[1].y*ivp[2].z);<br />
vp[1].x = ivp[1].x*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[1].z*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[1].w*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z);<br />
vp[1].y = ivp[0].x*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[0].z*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[0].w*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x);<br />
vp[1].z = ivp[0].x*(ivp[1].w*ivp[3].z - ivp[1].z*ivp[3].w) + ivp[0].z*(ivp[1].x*ivp[3].w - ivp[1].w*ivp[3].x) + ivp[0].w*(ivp[1].z*ivp[3].x - ivp[1].x*ivp[3].z);<br />
vp[1].w = ivp[0].x*(ivp[1].z*ivp[2].w - ivp[1].w*ivp[2].z) + ivp[0].z*(ivp[1].w*ivp[2].x - ivp[1].x*ivp[2].w) + ivp[0].w*(ivp[1].x*ivp[2].z - ivp[1].z*ivp[2].x);<br />
vp[2].x = ivp[1].x*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[1].y*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[1].w*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[2].y = ivp[0].x*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[0].y*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[0].w*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[2].z = ivp[0].x*(ivp[1].y*ivp[3].w - ivp[1].w*ivp[3].y) + ivp[0].y*(ivp[1].w*ivp[3].x - ivp[1].x*ivp[3].w) + ivp[0].w*(ivp[1].x*ivp[3].y - ivp[1].y*ivp[3].x);<br />
vp[2].w = ivp[0].x*(ivp[1].w*ivp[2].y - ivp[1].y*ivp[2].w) + ivp[0].y*(ivp[1].x*ivp[2].w - ivp[1].w*ivp[2].x) + ivp[0].w*(ivp[1].y*ivp[2].x - ivp[1].x*ivp[2].y);<br />
vp[3].x = ivp[1].x*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z) + ivp[1].y*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x) + ivp[1].z*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[3].y = ivp[0].x*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y) + ivp[0].y*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z) + ivp[0].z*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[3].z = ivp[0].x*(ivp[1].z*ivp[3].y - ivp[1].y*ivp[3].z) + ivp[0].y*(ivp[1].x*ivp[3].z - ivp[1].z*ivp[3].x) + ivp[0].z*(ivp[1].y*ivp[3].x - ivp[1].x*ivp[3].y);<br />
vp[3].w = ivp[0].x*(ivp[1].y*ivp[2].z - ivp[1].z*ivp[2].y) + ivp[0].y*(ivp[1].z*ivp[2].x - ivp[1].x*ivp[2].z) + ivp[0].z*(ivp[1].x*ivp[2].y - ivp[1].y*ivp[2].x);<br />
vp /= determinant(ivp);<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM (3Dmigoto ASM) '''''<br />
<br />
This one hasn't been fully tested, but should work. This is created by ''mx-2'' and found on his [https://github.com/mx-2/3d-fix/blob/master/_tools_/inverseMatrix.asm GitHub]<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
//<br />
// inverseMatrix.asm<br />
//<br />
// Matrix inversion with Gauss-Jordan elimination<br />
// algorithm on GPU.<br />
//<br />
// This algorithm uses 128 instructions, from which<br />
// 83 (best case) to 110 (worst case) are executed.<br />
//<br />
// input matrix is in r0-r3<br />
// output will be in r4-r7<br />
// r8, r9 are used as temporary registers<br />
// c200 = (1,0,0,0) is required<br />
//<br />
// r0.x r0.y r0.z r0.w | r4.x, r4.y, r4.z, r4.w<br />
// r1.x r1.y r1.z r1.w | r5.x, r5.y, r5.z, r5.w<br />
// r2.x r2.y r2.z r2.w | r6.x, r6.y, r6.z, r6.w<br />
// r3.x r3.y r3.z r3.w | r7.x, r7.y, r7.z, r7.w<br />
//<br />
// Test:<br />
// SETR r0, 0, 2, 3, 4<br />
// SETR r1, 1, 0, 5, 4<br />
// SETR r2,-1, 2, 3, 4<br />
// SETR r3, 0, 2, 3, 5<br />
//<br />
// Should produce<br />
// r4 = 1.0, 0.0, -1.0, 0.0<br />
// r5 = 1.6, -0.3, -0.3, -0.8<br />
// r6 = 0.6, 0.2, 0.2, -0.8<br />
// r7 = -1.0, 0.0, 0.0, 1.0<br />
//<br />
<br />
// Init registers<br />
def c200, 1, 0, 0, 0<br />
mov r4, c200.xyzw<br />
mov r5, c200.wxyz<br />
mov r6, c200.zwxy<br />
mov r7, c200.yzwx<br />
<br />
// Pivot first column<br />
mov r8, c200<br />
if_eq r0.x, r8.y<br />
if_eq r1.x, r8.y<br />
if_eq r2.x, r8.y<br />
mov r9, r0<br />
mov r0, r3<br />
mov r3, r9<br />
mov r9, r4<br />
mov r4, r7<br />
mov r7, r9<br />
else<br />
mov r9, r0<br />
mov r0, r2<br />
mov r2, r9<br />
mov r9, r4<br />
mov r4, r6<br />
mov r6, r9<br />
endif<br />
else<br />
mov r9, r0<br />
mov r0, r1<br />
mov r1, r9<br />
mov r9, r4<br />
mov r4, r5<br />
mov r5, r9<br />
endif<br />
endif<br />
<br />
// First column<br />
rcp r8.x, r0.x<br />
mul r8.y, r8.x, r1.x<br />
mul r9, r0, r8.y<br />
add r1, r1, -r9<br />
mul r9, r4, r8.y<br />
add r5, r5, -r9<br />
<br />
mul r8.y, r8.x, r2.x<br />
mul r9, r0, r8.y<br />
add r2, r2, -r9<br />
mul r9, r4, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.x<br />
mul r9, r0, r8.y<br />
add r3, r3, -r9<br />
mul r9, r4, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot second column<br />
mov r8, c200<br />
if_eq r1.y, r8.y<br />
if_eq r2.y, r8.y<br />
mov r9, r1<br />
mov r1, r3<br />
mov r3, r9<br />
mov r9, r5<br />
mov r5, r7<br />
mov r7, r9<br />
else<br />
mov r9, r1<br />
mov r1, r2<br />
mov r2, r9<br />
mov r9, r5<br />
mov r5, r6<br />
mov r6, r9<br />
endif<br />
endif<br />
<br />
// Second column<br />
rcp r8.x, r1.y<br />
mul r8.y, r8.x, r2.y<br />
mul r9, r1, r8.y<br />
add r2, r2, -r9<br />
mul r9, r5, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.y<br />
mul r9, r1, r8.y<br />
add r3, r3, -r9<br />
mul r9, r5, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot third column<br />
mov r8, c200<br />
if_eq r2.z, r8.y<br />
mov r9, r2<br />
mov r2, r3<br />
mov r3, r9<br />
mov r9, r6<br />
mov r6, r7<br />
mov r7, r9<br />
endif<br />
<br />
// Third column<br />
rcp r8.x, r2.z<br />
mul r8.y, r8.x, r3.z<br />
mul r9, r2, r8.y<br />
add r3, r3, -r9<br />
mul r9, r6, r8.y<br />
add r7, r7, -r9<br />
<br />
// Normalize r3.w<br />
rcp r8.x, r3.w<br />
mul r3, r3, r8.x<br />
mul r7, r7, r8.x<br />
<br />
// Fourth column<br />
mul r8, r3, r2.w<br />
mul r9, r7, r2.w<br />
add r2, r2, -r8<br />
add r6, r6, -r9<br />
<br />
mul r8, r3, r1.w<br />
mul r9, r7, r1.w<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r3, r0.w<br />
mul r9, r7, r0.w<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r2.z<br />
rcp r8.x, r2.z<br />
mul r2, r2, r8.x<br />
mul r6, r6, r8.x<br />
<br />
// Third column (upper part)<br />
mul r8, r2, r1.z<br />
mul r9, r6, r1.z<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r2, r0.z<br />
mul r9, r6, r0.z<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r1.y<br />
rcp r8.x, r1.y<br />
mul r1, r1, r8.x<br />
mul r5, r5, r8.x<br />
<br />
// Second column (upper part)<br />
mul r8, r1, r0.y<br />
mul r9, r5, r0.y<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize first column<br />
rcp r8.x, r0.x<br />
mul r0, r0, r8.x<br />
mul r4, r4, r8.x<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
Two more variants, both from Helifax. In case those previous ones don't seem quite right.<br />
<br />
''''' HLSL '''''<br />
<br />
<syntaxhighlight lang="c"><br />
//Work out Inverse<br />
//...Variables<br />
float4 a1, a2, a3, a4;<br />
float4 b1, b2, b3, b4;<br />
float det;<br />
//...Original Matrix<br />
a1 = g_invViewProjMatrix._m00_m10_m20_m30;<br />
a2 = g_invViewProjMatrix._m01_m11_m21_m31;<br />
a3 = g_invViewProjMatrix._m02_m12_m22_m32;<br />
a4 = g_invViewProjMatrix._m03_m13_m23_m33;<br />
//...Determinant<br />
det = a1.x*(a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y));<br />
det += a1.y*(a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.z) + a2.w*(a3.z*a4.x - a3.x*a4.z));<br />
det += a1.z*(a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x));<br />
det += a1.w*(a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y));<br />
//...Inverse Matrix Elements<br />
b1.x = a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y);<br />
b1.y = a1.y*(a3.w*a4.z - a3.z*a4.w) + a1.z*(a3.y*a4.w - a3.w*a4.y) + a1.w*(a3.z*a4.y - a3.y*a4.z);<br />
b1.z = a1.y*(a2.z*a4.w - a2.w*a4.z) + a1.z*(a2.w*a4.y - a2.y*a4.w) + a1.w*(a2.y*a4.z - a2.z*a4.y);<br />
b1.w = a1.y*(a2.w*a3.z - a2.z*a3.w) + a1.z*(a2.y*a3.w - a2.w*a3.y) + a1.w*(a2.z*a3.y - a2.y*a3.z);<br />
b2.x = a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.x) + a2.w*(a3.z*a4.x - a3.x*a4.z);<br />
b2.y = a1.x*(a3.z*a4.w - a3.w*a4.z) + a1.z*(a3.w*a4.x - a3.x*a4.w) + a1.w*(a3.x*a4.z - a3.z*a4.x);<br />
b2.z = a1.x*(a2.w*a4.z - a2.z*a4.w) + a1.z*(a2.x*a4.w - a2.w*a4.x) + a1.w*(a2.z*a4.x - a2.x*a4.z);<br />
b2.w = a1.x*(a2.z*a3.w - a2.w*a3.z) + a1.z*(a2.w*a3.x - a2.x*a3.w) + a1.w*(a2.x*a3.z - a2.z*a3.x);<br />
b3.x = a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x);<br />
b3.y = a1.x*(a3.w*a4.y - a3.y*a4.w) + a1.y*(a3.x*a4.w - a3.w*a4.x) + a1.w*(a3.y*a4.x - a3.x*a4.y);<br />
b3.z = a1.x*(a2.y*a4.w - a2.w*a4.y) + a1.y*(a2.w*a4.x - a2.x*a4.w) + a1.w*(a2.x*a4.y - a2.y*a4.x);<br />
b3.w = a1.x*(a2.w*a3.y - a2.y*a3.w) + a1.y*(a2.x*a3.w - a2.w*a3.x) + a1.w*(a2.y*a3.x - a2.x*a3.y);<br />
b4.x = a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y);<br />
b4.y = a1.x*(a3.y*a4.z - a3.z*a4.y) + a1.y*(a3.z*a4.x - a3.x*a4.z) + a1.z*(a3.x*a4.y - a3.y*a4.x);<br />
b4.z = a1.x*(a2.z*a4.y - a2.y*a4.z) + a1.y*(a2.x*a4.z - a2.z*a4.x) + a1.z*(a2.y*a4.x - a2.x*a4.y);<br />
b4.w = a1.x*(a2.y*a3.z - a2.z*a3.y) + a1.y*(a2.z*a3.x - a2.x*a3.z) + a1.z*(a2.x*a3.y - a2.y*a3.x);<br />
b1.xyzw /= det;<br />
b2.xyzw /= det;<br />
b3.xyzw /= det;<br />
b4.xyzw /= det;<br />
//End Inverse<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM '''''<br />
<br />
Generated from the HLSL, using fxc.<br />
<syntaxhighlight lang="c"><br />
// Declare how many registers ww use<br />
// The code uses registers from r38 to r53.<br />
dcl_temps 60<br />
<br />
// 3DMigoto StereoParams:<br />
dcl_resource_texture1d (float,float,float,float) t120<br />
dcl_resource_texture2d (float,float,float,float) t125<br />
ld_indexable(texture1d)(float,float,float,float) r41.xyzw, l(0, 0, 0, 0), t120.xyzw<br />
ld_indexable(texture2d)(float,float,float,float) r40.xyzw, l(0, 0, 0, 0), t125.xyzw<br />
<br />
// Inverse<br />
// cb0[0], etc is the inverseMatrix<br />
mov r0.xyzw, cb0[0].xyzw<br />
mov r1.xyzw, cb0[1].xyzw<br />
mov r2.xyzw, cb0[2].xyzw<br />
mov r3.xyzw, cb0[3].xyzw<br />
mul r4.x, r2.z, r3.w<br />
mul r4.y, r2.w, r3.z<br />
mov r4.y, -r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r1.y, r4.x<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.z<br />
mul r4.z, r2.z, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r0.x, r4.x<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.y<br />
mul r4.z, r2.y, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.y, r4.y<br />
mul r4.z, r2.w, r3.y<br />
mul r4.w, r2.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.z<br />
mul r4.w, r2.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r5.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r2.y, r3.w<br />
mul r4.w, r2.w, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.y<br />
mul r4.w, r2.y, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.y, r4.z, r4.y<br />
mul r4.y, r1.z, r3.w<br />
mul r4.z, r1.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.w, r3.y<br />
mul r4.w, r1.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.y, r3.z<br />
mul r4.w, r1.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.z, r4.z, r4.y<br />
mul r4.y, r1.w, r2.z<br />
mul r4.z, r1.z, r2.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.y, r2.w<br />
mul r4.w, r1.w, r2.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r2.y<br />
mul r4.w, r1.y, r2.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.w, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r6.x, r4.z, r4.y<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.y, r4.z, r4.y<br />
mul r4.y, r1.w, r3.z<br />
mul r4.z, r1.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.x, r3.w<br />
mul r4.w, r1.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r3.x<br />
mul r4.w, r1.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.z, r4.z, r4.y<br />
mul r4.y, r1.z, r2.w<br />
mul r4.z, r1.w, r2.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r2.x<br />
mul r4.w, r1.x, r2.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.x, r2.z<br />
mul r4.w, r1.z, r2.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.w, r4.z, r4.y<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r7.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r7.y, r4.z, r4.y<br />
mul r4.y, r1.y, r3.w<br />
mul r4.z, r1.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r3.x<br />
mul r3.w, r1.x, r3.w<br />
mov r3.w, -r3.w<br />
add r3.w, r3.w, r4.z<br />
mul r3.w, r0.y, r3.w<br />
add r3.w, r3.w, r4.y<br />
mul r4.y, r1.x, r3.y<br />
mul r4.z, r1.y, r3.x<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r7.z, r3.w, r4.y<br />
mul r3.w, r1.w, r2.y<br />
mul r4.y, r1.y, r2.w<br />
mov r4.y, -r4.y<br />
add r3.w, r3.w, r4.y<br />
mul r3.w, r0.x, r3.w<br />
mul r2.w, r1.x, r2.w<br />
mul r1.w, r1.w, r2.x<br />
mov r1.w, -r1.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r1.w, r1.w, r3.w<br />
mul r2.w, r1.y, r2.x<br />
mul r3.w, r1.x, r2.y<br />
mov r3.w, -r3.w<br />
add r2.w, r2.w, r3.w<br />
mul r0.w, r0.w, r2.w<br />
add r7.w, r0.w, r1.w<br />
mul r0.w, r2.z, r3.y<br />
mul r1.w, r2.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r1.x<br />
mul r1.w, r2.x, r3.z<br />
mul r2.w, r2.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.y<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.y, r3.x<br />
mul r2.w, r2.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.z<br />
add r8.x, r0.w, r1.w<br />
mul r0.w, r2.y, r3.z<br />
mul r1.w, r2.z, r3.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r2.z, r3.x<br />
mul r2.w, r2.x, r3.z<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.x, r3.y<br />
mul r2.w, r2.y, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.y, r0.w, r1.w<br />
mul r0.w, r1.z, r3.y<br />
mul r1.w, r1.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r1.x, r3.z<br />
mul r2.w, r1.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r1.y, r3.x<br />
mul r2.w, r1.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.z, r0.w, r1.w<br />
mul r0.w, r1.y, r2.z<br />
mul r1.w, r1.z, r2.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.x, r0.w, r0.x<br />
mul r0.w, r1.z, r2.x<br />
mul r1.z, r1.x, r2.z<br />
mov r1.z, -r1.z<br />
add r0.w, r0.w, r1.z<br />
mul r0.y, r0.w, r0.y<br />
add r0.x, r0.y, r0.x<br />
mul r0.y, r1.x, r2.y<br />
mul r0.w, r1.y, r2.x<br />
mov r0.w, -r0.w<br />
add r0.y, r0.w, r0.y<br />
mul r0.y, r0.y, r0.z<br />
add r8.w, r0.y, r0.x<br />
div r0.xyzw, r5.xyzw, r4.xxxx<br />
div r1.xyzw, r6.xyzw, r4.xxxx<br />
div r2.xyzw, r7.xyzw, r4.xxxx<br />
div r3.xyzw, r8.xyzw, r4.xxxx<br />
<br />
// Store results for later use as r0-r4 are most <br />
// likely to be used by the default shader code.<br />
// r50 equivalent of matrix._m00_m01_m02_m03<br />
// r51 equivalent of matrix._m10_m11_m12_m13<br />
// r52 equivalent of matrix._m20_m21_m22_m23<br />
// r53 equivalent of matrix._m30_m31_m32_m33<br />
<br />
mov r50.xyzw, r0.xyzw <br />
mov r51.xyzw, r1.xyzw <br />
mov r52.xyzw, r2.xyzw <br />
mov r53.xyzw, r3.xyzw<br />
</syntaxhighlight></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Canonical_Stereo_CodeCanonical Stereo Code2016-10-28T01:11:13Z<p>Bo3b admin: </p>
<hr />
<div>=== Prime Directive ===<br />
<br />
This is the ''prime directive'' code in ASM for DX9 and HelixMod. And the HLSL version for 3Dmigoto. In all cases, we are implementing the NVidia specified formula of: <br><br><br />
<code>clipPos.x += EyeSign * Separation * ( clipPos.w – Convergence )</code><br />
<br />
<br />
''''' ASM (both HelixMod and 3Dmigoto ASM) '''''<br />
<br />
This is the wordy version with extra comments to make it more clear what is happening.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// The required constant for txldl in c200.z<br />
def c200, 1.0, 600, 0.0625, 0<br />
// Sampler used to fetch stereo params, <br />
// s0 sampler is default for VS<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
// Fetch the Separation (r30.x) and Convergence (r30.y) <br />
// using the Helix NVapi trick<br />
texldl r30, c200.z, s0<br />
<br />
// (W - Convergence)<br />
add r30.w, r0.w, -r30.y<br />
<br />
// multiply that times Separation for:<br />
// Separation * (W - Convergence)<br />
mul r30.z, r30.x, r30.w<br />
<br />
// Add that to Xold for the complete:<br />
// Xold + Separation * (W - Convergence)<br />
add r0.x, r0.x, r30.z<br />
<br />
</syntaxhighlight><br />
<br />
<br />
Another variant that is more concise, but less clear. As you get more accustomed to seeing this sequence of code, or are sharing with an expert crowd, it's less necessary to fully document this part, as it is always the same sequence and easy to recognize because of the texldl of 0.0625.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mad r0.x, r30.x, r30.w, r0.x<br />
</syntaxhighlight><br />
<br />
<br />
Another very common variant you'll see in HelixMod fixes is the four line version, with no comments. This is less optimal than the two above, but is worth seeing to be able to recognize it.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mul r30.z, r30.x, r30.w<br />
add r0.x, r0.x, r30.z<br />
</syntaxhighlight><br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The HLSL version is very similar, but since it's a compile language there is no need to be terse when writing the code. We can make it "self-documenting" by using good variable names.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// .Load should only be done once, but can be done anywhere in the code.<br />
<br />
float4 stereo = StereoParams.Load(0);<br />
float separation = stereo.x; float convergence = stereo.y;<br />
<br />
// At this point, "location" is the output position, but missing stereo.<br />
<br />
location.x += separation * (location.w - convergence);<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
=== Matrix Inversion ===<br />
<br />
We often need to invert a ViewProjectionMatrix, in order to be able to stereo correct a location in the proper viewspace (usually projection space for deferred rendering).<br />
<br />
We only need to do this in cases where the inverted matrix is not available. A lot of games have both matrices available, and can be used directly. <br />
<br />
We have code samples for both ASM, and for HLSL. It's worth noting that for HelixMod fixes in DX9, that HelixMod already supports [[HelixMod_Feature_List#InverseMatrix.2C_InverseMatrix1|inverted matrices]] directly, and this code should not be used there, because all this extra code will impact performance. Try to avoid using it in PS in particular, because inverting a matrix for every pixel is very costly.<br />
<br />
<br />
''''' HLSL (3Dmigoto only) '''''<br />
<br />
The '''best''' way to invert a matrix is to use the runtime shader feature from d3dx.ini. This is best because it runs once per frame, which keeps a performance impact low. This was created by ''DarkStarSword''.<br />
<br />
[https://github.com/bo3b/3Dmigoto/wiki/Injecting-custom-shaders Described here] The actual shader is found [https://github.com/DarkStarSword/3d-fixes/blob/e0f67a3bed5fa90d8823a31b014e607f51c4fefc/inverse-cs.hlsl here] And, how to use it, described [https://forums.geforce.com/default/topic/685657/3d-vision/3dmigoto-now-open-source-/post/4909267/#4909267 here]<br />
<br />
<br />
If that doesn't work for some reason (not all games are compatible), it's possible to do it in HLSL directly. This example is backwards in that it starts with an inverted matrix, then creates the forward matrix from that. Used in an example [https://github.com/DarkStarSword/3d-fixes/blob/master/Mad%20Max/ShaderFixes/01037617f0200a5c-ps_replace.txt here] Again, it's worth noting that doing this in a PS shader is sub-optimal.<br />
<br />
The original version of this came from ''Mike_ar69''.<br />
<syntaxhighlight lang="c"><br />
...<br />
matrix ivp, vp;<br />
ivp = matrix(InstanceConsts[1], InstanceConsts[2], InstanceConsts[3], InstanceConsts[4]);<br />
<br />
// Work out the view-projection matrix from it's inverse:<br />
vp[0].x = ivp[1].y*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[1].z*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[1].w*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y);<br />
vp[0].y = ivp[0].y*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[0].z*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[0].w*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z);<br />
vp[0].z = ivp[0].y*(ivp[1].z*ivp[3].w - ivp[1].w*ivp[3].z) + ivp[0].z*(ivp[1].w*ivp[3].y - ivp[1].y*ivp[3].w) + ivp[0].w*(ivp[1].y*ivp[3].z - ivp[1].z*ivp[3].y);<br />
vp[0].w = ivp[0].y*(ivp[1].w*ivp[2].z - ivp[1].z*ivp[2].w) + ivp[0].z*(ivp[1].y*ivp[2].w - ivp[1].w*ivp[2].y) + ivp[0].w*(ivp[1].z*ivp[2].y - ivp[1].y*ivp[2].z);<br />
vp[1].x = ivp[1].x*(ivp[2].w*ivp[3].z - ivp[2].z*ivp[3].w) + ivp[1].z*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[1].w*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z);<br />
vp[1].y = ivp[0].x*(ivp[2].z*ivp[3].w - ivp[2].w*ivp[3].z) + ivp[0].z*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[0].w*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x);<br />
vp[1].z = ivp[0].x*(ivp[1].w*ivp[3].z - ivp[1].z*ivp[3].w) + ivp[0].z*(ivp[1].x*ivp[3].w - ivp[1].w*ivp[3].x) + ivp[0].w*(ivp[1].z*ivp[3].x - ivp[1].x*ivp[3].z);<br />
vp[1].w = ivp[0].x*(ivp[1].z*ivp[2].w - ivp[1].w*ivp[2].z) + ivp[0].z*(ivp[1].w*ivp[2].x - ivp[1].x*ivp[2].w) + ivp[0].w*(ivp[1].x*ivp[2].z - ivp[1].z*ivp[2].x);<br />
vp[2].x = ivp[1].x*(ivp[2].y*ivp[3].w - ivp[2].w*ivp[3].y) + ivp[1].y*(ivp[2].w*ivp[3].x - ivp[2].x*ivp[3].w) + ivp[1].w*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[2].y = ivp[0].x*(ivp[2].w*ivp[3].y - ivp[2].y*ivp[3].w) + ivp[0].y*(ivp[2].x*ivp[3].w - ivp[2].w*ivp[3].x) + ivp[0].w*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[2].z = ivp[0].x*(ivp[1].y*ivp[3].w - ivp[1].w*ivp[3].y) + ivp[0].y*(ivp[1].w*ivp[3].x - ivp[1].x*ivp[3].w) + ivp[0].w*(ivp[1].x*ivp[3].y - ivp[1].y*ivp[3].x);<br />
vp[2].w = ivp[0].x*(ivp[1].w*ivp[2].y - ivp[1].y*ivp[2].w) + ivp[0].y*(ivp[1].x*ivp[2].w - ivp[1].w*ivp[2].x) + ivp[0].w*(ivp[1].y*ivp[2].x - ivp[1].x*ivp[2].y);<br />
vp[3].x = ivp[1].x*(ivp[2].z*ivp[3].y - ivp[2].y*ivp[3].z) + ivp[1].y*(ivp[2].x*ivp[3].z - ivp[2].z*ivp[3].x) + ivp[1].z*(ivp[2].y*ivp[3].x - ivp[2].x*ivp[3].y);<br />
vp[3].y = ivp[0].x*(ivp[2].y*ivp[3].z - ivp[2].z*ivp[3].y) + ivp[0].y*(ivp[2].z*ivp[3].x - ivp[2].x*ivp[3].z) + ivp[0].z*(ivp[2].x*ivp[3].y - ivp[2].y*ivp[3].x);<br />
vp[3].z = ivp[0].x*(ivp[1].z*ivp[3].y - ivp[1].y*ivp[3].z) + ivp[0].y*(ivp[1].x*ivp[3].z - ivp[1].z*ivp[3].x) + ivp[0].z*(ivp[1].y*ivp[3].x - ivp[1].x*ivp[3].y);<br />
vp[3].w = ivp[0].x*(ivp[1].y*ivp[2].z - ivp[1].z*ivp[2].y) + ivp[0].y*(ivp[1].z*ivp[2].x - ivp[1].x*ivp[2].z) + ivp[0].z*(ivp[1].x*ivp[2].y - ivp[1].y*ivp[2].x);<br />
vp /= determinant(ivp);<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM (3Dmigoto ASM) '''''<br />
<br />
This one hasn't been fully tested, but should work. This is created by ''mx-2'' and found on his [https://github.com/mx-2/3d-fix/blob/master/_tools_/inverseMatrix.asm GitHub]<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
//<br />
// inverseMatrix.asm<br />
//<br />
// Matrix inversion with Gauss-Jordan elimination<br />
// algorithm on GPU.<br />
//<br />
// This algorithm uses 128 instructions, from which<br />
// 83 (best case) to 110 (worst case) are executed.<br />
//<br />
// input matrix is in r0-r3<br />
// output will be in r4-r7<br />
// r8, r9 are used as temporary registers<br />
// c200 = (1,0,0,0) is required<br />
//<br />
// r0.x r0.y r0.z r0.w | r4.x, r4.y, r4.z, r4.w<br />
// r1.x r1.y r1.z r1.w | r5.x, r5.y, r5.z, r5.w<br />
// r2.x r2.y r2.z r2.w | r6.x, r6.y, r6.z, r6.w<br />
// r3.x r3.y r3.z r3.w | r7.x, r7.y, r7.z, r7.w<br />
//<br />
// Test:<br />
// SETR r0, 0, 2, 3, 4<br />
// SETR r1, 1, 0, 5, 4<br />
// SETR r2,-1, 2, 3, 4<br />
// SETR r3, 0, 2, 3, 5<br />
//<br />
// Should produce<br />
// r4 = 1.0, 0.0, -1.0, 0.0<br />
// r5 = 1.6, -0.3, -0.3, -0.8<br />
// r6 = 0.6, 0.2, 0.2, -0.8<br />
// r7 = -1.0, 0.0, 0.0, 1.0<br />
//<br />
<br />
// Init registers<br />
def c200, 1, 0, 0, 0<br />
mov r4, c200.xyzw<br />
mov r5, c200.wxyz<br />
mov r6, c200.zwxy<br />
mov r7, c200.yzwx<br />
<br />
// Pivot first column<br />
mov r8, c200<br />
if_eq r0.x, r8.y<br />
if_eq r1.x, r8.y<br />
if_eq r2.x, r8.y<br />
mov r9, r0<br />
mov r0, r3<br />
mov r3, r9<br />
mov r9, r4<br />
mov r4, r7<br />
mov r7, r9<br />
else<br />
mov r9, r0<br />
mov r0, r2<br />
mov r2, r9<br />
mov r9, r4<br />
mov r4, r6<br />
mov r6, r9<br />
endif<br />
else<br />
mov r9, r0<br />
mov r0, r1<br />
mov r1, r9<br />
mov r9, r4<br />
mov r4, r5<br />
mov r5, r9<br />
endif<br />
endif<br />
<br />
// First column<br />
rcp r8.x, r0.x<br />
mul r8.y, r8.x, r1.x<br />
mul r9, r0, r8.y<br />
add r1, r1, -r9<br />
mul r9, r4, r8.y<br />
add r5, r5, -r9<br />
<br />
mul r8.y, r8.x, r2.x<br />
mul r9, r0, r8.y<br />
add r2, r2, -r9<br />
mul r9, r4, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.x<br />
mul r9, r0, r8.y<br />
add r3, r3, -r9<br />
mul r9, r4, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot second column<br />
mov r8, c200<br />
if_eq r1.y, r8.y<br />
if_eq r2.y, r8.y<br />
mov r9, r1<br />
mov r1, r3<br />
mov r3, r9<br />
mov r9, r5<br />
mov r5, r7<br />
mov r7, r9<br />
else<br />
mov r9, r1<br />
mov r1, r2<br />
mov r2, r9<br />
mov r9, r5<br />
mov r5, r6<br />
mov r6, r9<br />
endif<br />
endif<br />
<br />
// Second column<br />
rcp r8.x, r1.y<br />
mul r8.y, r8.x, r2.y<br />
mul r9, r1, r8.y<br />
add r2, r2, -r9<br />
mul r9, r5, r8.y<br />
add r6, r6, -r9<br />
<br />
mul r8.y, r8.x, r3.y<br />
mul r9, r1, r8.y<br />
add r3, r3, -r9<br />
mul r9, r5, r8.y<br />
add r7, r7, -r9<br />
<br />
// Pivot third column<br />
mov r8, c200<br />
if_eq r2.z, r8.y<br />
mov r9, r2<br />
mov r2, r3<br />
mov r3, r9<br />
mov r9, r6<br />
mov r6, r7<br />
mov r7, r9<br />
endif<br />
<br />
// Third column<br />
rcp r8.x, r2.z<br />
mul r8.y, r8.x, r3.z<br />
mul r9, r2, r8.y<br />
add r3, r3, -r9<br />
mul r9, r6, r8.y<br />
add r7, r7, -r9<br />
<br />
// Normalize r3.w<br />
rcp r8.x, r3.w<br />
mul r3, r3, r8.x<br />
mul r7, r7, r8.x<br />
<br />
// Fourth column<br />
mul r8, r3, r2.w<br />
mul r9, r7, r2.w<br />
add r2, r2, -r8<br />
add r6, r6, -r9<br />
<br />
mul r8, r3, r1.w<br />
mul r9, r7, r1.w<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r3, r0.w<br />
mul r9, r7, r0.w<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r2.z<br />
rcp r8.x, r2.z<br />
mul r2, r2, r8.x<br />
mul r6, r6, r8.x<br />
<br />
// Third column (upper part)<br />
mul r8, r2, r1.z<br />
mul r9, r6, r1.z<br />
add r1, r1, -r8<br />
add r5, r5, -r9<br />
<br />
mul r8, r2, r0.z<br />
mul r9, r6, r0.z<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize r1.y<br />
rcp r8.x, r1.y<br />
mul r1, r1, r8.x<br />
mul r5, r5, r8.x<br />
<br />
// Second column (upper part)<br />
mul r8, r1, r0.y<br />
mul r9, r5, r0.y<br />
add r0, r0, -r8<br />
add r4, r4, -r9<br />
<br />
// Normalize first column<br />
rcp r8.x, r0.x<br />
mul r0, r0, r8.x<br />
mul r4, r4, r8.x<br />
...<br />
</syntaxhighlight><br />
<br />
<br />
----<br />
<br />
Two more variants, both from Helifax. In case those previous ones don't seem quite right.<br />
<br />
''''' HLSL '''''<br />
<br />
<syntaxhighlight lang="c"><br />
//Work out Inverse<br />
//...Variables<br />
float4 a1, a2, a3, a4;<br />
float4 b1, b2, b3, b4;<br />
float det;<br />
//...Original Matrix<br />
a1 = g_invViewProjMatrix._m00_m10_m20_m30;<br />
a2 = g_invViewProjMatrix._m01_m11_m21_m31;<br />
a3 = g_invViewProjMatrix._m02_m12_m22_m32;<br />
a4 = g_invViewProjMatrix._m03_m13_m23_m33;<br />
//...Determinant<br />
det = a1.x*(a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y));<br />
det += a1.y*(a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.z) + a2.w*(a3.z*a4.x - a3.x*a4.z));<br />
det += a1.z*(a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x));<br />
det += a1.w*(a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y));<br />
//...Inverse Matrix Elements<br />
b1.x = a2.y*(a3.z*a4.w - a3.w*a4.z) + a2.z*(a3.w*a4.y - a3.y*a4.w) + a2.w*(a3.y*a4.z - a3.z*a4.y);<br />
b1.y = a1.y*(a3.w*a4.z - a3.z*a4.w) + a1.z*(a3.y*a4.w - a3.w*a4.y) + a1.w*(a3.z*a4.y - a3.y*a4.z);<br />
b1.z = a1.y*(a2.z*a4.w - a2.w*a4.z) + a1.z*(a2.w*a4.y - a2.y*a4.w) + a1.w*(a2.y*a4.z - a2.z*a4.y);<br />
b1.w = a1.y*(a2.w*a3.z - a2.z*a3.w) + a1.z*(a2.y*a3.w - a2.w*a3.y) + a1.w*(a2.z*a3.y - a2.y*a3.z);<br />
b2.x = a2.x*(a3.w*a4.z - a3.z*a4.w) + a2.z*(a3.x*a4.w - a3.w*a4.x) + a2.w*(a3.z*a4.x - a3.x*a4.z);<br />
b2.y = a1.x*(a3.z*a4.w - a3.w*a4.z) + a1.z*(a3.w*a4.x - a3.x*a4.w) + a1.w*(a3.x*a4.z - a3.z*a4.x);<br />
b2.z = a1.x*(a2.w*a4.z - a2.z*a4.w) + a1.z*(a2.x*a4.w - a2.w*a4.x) + a1.w*(a2.z*a4.x - a2.x*a4.z);<br />
b2.w = a1.x*(a2.z*a3.w - a2.w*a3.z) + a1.z*(a2.w*a3.x - a2.x*a3.w) + a1.w*(a2.x*a3.z - a2.z*a3.x);<br />
b3.x = a2.x*(a3.y*a4.w - a3.w*a4.y) + a2.y*(a3.w*a4.x - a3.x*a4.w) + a2.w*(a3.x*a4.y - a3.y*a4.x);<br />
b3.y = a1.x*(a3.w*a4.y - a3.y*a4.w) + a1.y*(a3.x*a4.w - a3.w*a4.x) + a1.w*(a3.y*a4.x - a3.x*a4.y);<br />
b3.z = a1.x*(a2.y*a4.w - a2.w*a4.y) + a1.y*(a2.w*a4.x - a2.x*a4.w) + a1.w*(a2.x*a4.y - a2.y*a4.x);<br />
b3.w = a1.x*(a2.w*a3.y - a2.y*a3.w) + a1.y*(a2.x*a3.w - a2.w*a3.x) + a1.w*(a2.y*a3.x - a2.x*a3.y);<br />
b4.x = a2.x*(a3.z*a4.y - a3.y*a4.z) + a2.y*(a3.x*a4.z - a3.z*a4.x) + a2.z*(a3.y*a4.x - a3.x*a4.y);<br />
b4.y = a1.x*(a3.y*a4.z - a3.z*a4.y) + a1.y*(a3.z*a4.x - a3.x*a4.z) + a1.z*(a3.x*a4.y - a3.y*a4.x);<br />
b4.z = a1.x*(a2.z*a4.y - a2.y*a4.z) + a1.y*(a2.x*a4.z - a2.z*a4.x) + a1.z*(a2.y*a4.x - a2.x*a4.y);<br />
b4.w = a1.x*(a2.y*a3.z - a2.z*a3.y) + a1.y*(a2.z*a3.x - a2.x*a3.z) + a1.z*(a2.x*a3.y - a2.y*a3.x);<br />
b1.xyzw /= det;<br />
b2.xyzw /= det;<br />
b3.xyzw /= det;<br />
b4.xyzw /= det;<br />
//End Inverse<br />
</syntaxhighlight><br />
<br />
<br />
''''' ASM '''''<br />
<br />
Generated from the HLSL, using fxc.<br />
<syntaxhighlight lang="c"><br />
// Declare how many registers ww use<br />
// The code uses registers from r38 to r53.<br />
dcl_temps 60<br />
<br />
// 3DMigoto StereoParams:<br />
dcl_resource_texture1d (float,float,float,float) t120<br />
dcl_resource_texture2d (float,float,float,float) t125<br />
ld_indexable(texture1d)(float,float,float,float) r41.xyzw, l(0, 0, 0, 0), t120.xyzw<br />
ld_indexable(texture2d)(float,float,float,float) r40.xyzw, l(0, 0, 0, 0), t125.xyzw<br />
<br />
// Inverse<br />
// cb0[0], etc is the inverseMatrix<br />
mov r0.xyzw, cb0[0].xyzw<br />
mov r1.xyzw, cb0[1].xyzw<br />
mov r2.xyzw, cb0[2].xyzw<br />
mov r3.xyzw, cb0[3].xyzw<br />
mul r4.x, r2.z, r3.w<br />
mul r4.y, r2.w, r3.z<br />
mov r4.y, -r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r1.y, r4.x<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.z<br />
mul r4.z, r2.z, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.x, r0.x, r4.x<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.z, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.y<br />
mul r4.z, r2.y, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r4.x, r4.y, r4.x<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.y, r4.y<br />
mul r4.z, r2.w, r3.y<br />
mul r4.w, r2.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.z<br />
mul r4.w, r2.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r5.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r2.y, r3.w<br />
mul r4.w, r2.w, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.y<br />
mul r4.w, r2.y, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.y, r4.z, r4.y<br />
mul r4.y, r1.z, r3.w<br />
mul r4.z, r1.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.w, r3.y<br />
mul r4.w, r1.y, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.y, r3.z<br />
mul r4.w, r1.z, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.z, r4.z, r4.y<br />
mul r4.y, r1.w, r2.z<br />
mul r4.z, r1.z, r2.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.y, r4.y<br />
mul r4.z, r1.y, r2.w<br />
mul r4.w, r1.w, r2.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r2.y<br />
mul r4.w, r1.y, r2.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r5.w, r4.z, r4.y<br />
mul r4.y, r2.w, r3.z<br />
mul r4.z, r2.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.z, r3.x<br />
mul r4.w, r2.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r6.x, r4.z, r4.y<br />
mul r4.y, r2.z, r3.w<br />
mul r4.z, r2.w, r3.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.z<br />
mul r4.w, r2.z, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.y, r4.z, r4.y<br />
mul r4.y, r1.w, r3.z<br />
mul r4.z, r1.z, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.x, r3.w<br />
mul r4.w, r1.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.z, r3.x<br />
mul r4.w, r1.x, r3.z<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.z, r4.z, r4.y<br />
mul r4.y, r1.z, r2.w<br />
mul r4.z, r1.w, r2.z<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r2.x<br />
mul r4.w, r1.x, r2.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.z, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r1.x, r2.z<br />
mul r4.w, r1.z, r2.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r6.w, r4.z, r4.y<br />
mul r4.y, r2.y, r3.w<br />
mul r4.z, r2.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r1.x, r4.y<br />
mul r4.z, r2.w, r3.x<br />
mul r4.w, r2.x, r3.w<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.x, r3.y<br />
mul r4.w, r2.y, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r1.w, r4.z<br />
add r7.x, r4.z, r4.y<br />
mul r4.y, r2.w, r3.y<br />
mul r4.z, r2.y, r3.w<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r2.x, r3.w<br />
mul r4.w, r2.w, r3.x<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.y, r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.z, r2.y, r3.x<br />
mul r4.w, r2.x, r3.y<br />
mov r4.w, -r4.w<br />
add r4.z, r4.w, r4.z<br />
mul r4.z, r0.w, r4.z<br />
add r7.y, r4.z, r4.y<br />
mul r4.y, r1.y, r3.w<br />
mul r4.z, r1.w, r3.y<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.x, r4.y<br />
mul r4.z, r1.w, r3.x<br />
mul r3.w, r1.x, r3.w<br />
mov r3.w, -r3.w<br />
add r3.w, r3.w, r4.z<br />
mul r3.w, r0.y, r3.w<br />
add r3.w, r3.w, r4.y<br />
mul r4.y, r1.x, r3.y<br />
mul r4.z, r1.y, r3.x<br />
mov r4.z, -r4.z<br />
add r4.y, r4.z, r4.y<br />
mul r4.y, r0.w, r4.y<br />
add r7.z, r3.w, r4.y<br />
mul r3.w, r1.w, r2.y<br />
mul r4.y, r1.y, r2.w<br />
mov r4.y, -r4.y<br />
add r3.w, r3.w, r4.y<br />
mul r3.w, r0.x, r3.w<br />
mul r2.w, r1.x, r2.w<br />
mul r1.w, r1.w, r2.x<br />
mov r1.w, -r1.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r1.w, r1.w, r3.w<br />
mul r2.w, r1.y, r2.x<br />
mul r3.w, r1.x, r2.y<br />
mov r3.w, -r3.w<br />
add r2.w, r2.w, r3.w<br />
mul r0.w, r0.w, r2.w<br />
add r7.w, r0.w, r1.w<br />
mul r0.w, r2.z, r3.y<br />
mul r1.w, r2.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r1.x<br />
mul r1.w, r2.x, r3.z<br />
mul r2.w, r2.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.y<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.y, r3.x<br />
mul r2.w, r2.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r1.w, r1.z<br />
add r8.x, r0.w, r1.w<br />
mul r0.w, r2.y, r3.z<br />
mul r1.w, r2.z, r3.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r2.z, r3.x<br />
mul r2.w, r2.x, r3.z<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r2.x, r3.y<br />
mul r2.w, r2.y, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.y, r0.w, r1.w<br />
mul r0.w, r1.z, r3.y<br />
mul r1.w, r1.y, r3.z<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.w, r0.w, r0.x<br />
mul r1.w, r1.x, r3.z<br />
mul r2.w, r1.z, r3.x<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.y, r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r1.w, r1.y, r3.x<br />
mul r2.w, r1.x, r3.y<br />
mov r2.w, -r2.w<br />
add r1.w, r1.w, r2.w<br />
mul r1.w, r0.z, r1.w<br />
add r8.z, r0.w, r1.w<br />
mul r0.w, r1.y, r2.z<br />
mul r1.w, r1.z, r2.y<br />
mov r1.w, -r1.w<br />
add r0.w, r0.w, r1.w<br />
mul r0.x, r0.w, r0.x<br />
mul r0.w, r1.z, r2.x<br />
mul r1.z, r1.x, r2.z<br />
mov r1.z, -r1.z<br />
add r0.w, r0.w, r1.z<br />
mul r0.y, r0.w, r0.y<br />
add r0.x, r0.y, r0.x<br />
mul r0.y, r1.x, r2.y<br />
mul r0.w, r1.y, r2.x<br />
mov r0.w, -r0.w<br />
add r0.y, r0.w, r0.y<br />
mul r0.y, r0.y, r0.z<br />
add r8.w, r0.y, r0.x<br />
div r0.xyzw, r5.xyzw, r4.xxxx<br />
div r1.xyzw, r6.xyzw, r4.xxxx<br />
div r2.xyzw, r7.xyzw, r4.xxxx<br />
div r3.xyzw, r8.xyzw, r4.xxxx<br />
<br />
// Store results for later use as r0-r4 are most <br />
// likely to be used by the default shader code.<br />
// r50 equivalent of matrix._m00_m01_m02_m03<br />
// r51 equivalent of matrix._m10_m11_m12_m13<br />
// r52 equivalent of matrix._m20_m21_m22_m23<br />
// r53 equivalent of matrix._m30_m31_m32_m33<br />
<br />
mov r50.xyzw, r0.xyzw <br />
mov r51.xyzw, r1.xyzw <br />
mov r52.xyzw, r2.xyzw <br />
mov r53.xyzw, r3.xyzw<br />
</syntaxhighlight></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=DarkStarSword_example_fixesDarkStarSword example fixes2016-09-06T06:50:56Z<p>Bo3b admin: </p>
<hr />
<div>Whether you need to apply a fix in a vertex shader or a pixel shader depends on the effect you are trying to fix (and some can be fixed in either, and some need adjustments in both).<br />
<br />
Halos are often (but not always) possible to fix in either, but are almost always easier to fix in the vertex shader (the biggest exception where a halo fix has had to go in the pixel shader has been water, but only in a few games). Shadows almost always need a fix in the pixel shader.<br />
<br />
When we talk about patterns we're usually talking about fixing an effect in an engine that someone has already worked out how to fix. Generally games using the same engine will have effects broken in the same way, so studying how we have fixed another game using the same engine will show you the patterns to fix that engine.<br />
<br />
You can look at any of the fixes on the blog, or go through the history of my 3d-fixes repository to find these patterns - if you find the first time I fixed a given effect in the history I'll have included some extra notes in the commit message and usually have added the original shader in a separate commit so that the diff will show what I actually changed:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/commits/master<br />
<br />
I also have a database of all DX9 shaders running on one of my servers - you can use the lookup_shader.py script in my 3d-fixes repository to look up any shader's CRC to see if it has been used in any fixes (DX9 games only for now) and show the difference between your local copy and any fixed versions.<br />
<br />
<br />
Asside from halos (which are an almost universal problem with an almost equally universal solution), here's a few other examples of patterns (some easy, some difficult, some insane):<br />
<br />
<br />
Move skybox to infinity (pattern applies to most, but not all games):<br />
https://github.com/DarkStarSword/3d-fixes/commit/7622a2940530d3a14b4bb1b556cdbbbfb0e3dec6<br />
<br />
<br />
<br />
Shadows in Unreal Engine 3 (fairly simple):<br />
https://github.com/DarkStarSword/3d-fixes/commit/3cbebd0e4b5af11729fa9db6959acc71623ee3b7<br />
<br />
However you will notice that any of my more recent DX9 UE3 fixes use a script (shadertool.py) that knows how to recognise the pattern and apply the fix automatically, including dealing with slight variations in registers/components selected by the compiler:<br />
https://github.com/DarkStarSword/3d-fixes/commit/82181b842fe6cf3e0d087a58d6a7309b0b5a134d<br />
<br />
<br />
<br />
God rays in Unreal Engine 3 (simple):<br />
https://github.com/DarkStarSword/3d-fixes/commit/ad6535c0534b68638dd2411a2ad770ccec3ba9f6<br />
<br />
God rays in CryEngine 3 (simple):<br />
https://github.com/DarkStarSword/3d-fixes/commit/76af7b96a19723172520f61cd778a79fedf970cc<br />
<br />
God rays in Euro Truck Simulator 2 (moderate - no headers):<br />
https://github.com/DarkStarSword/3d-fixes/commit/67b31c856c08a4d563eebd0901cd91b67ff6de1a<br />
<br />
God rays in Unity 4 (simple once headers were extracted):<br />
https://github.com/DarkStarSword/3d-fixes/commit/54831b2f00a9912daa514ac6df384376eecc1f97<br />
<br />
God rays + underwater crepuscular rays in Stranded Deep (also Unity, but more complex than the above):<br />
https://github.com/DarkStarSword/3d-fixes/commit/83d50b1eac65ebbb938a697ae4ef2e2882c2cfcb<br />
<br />
God rays in Witcher 3 (moderate - no headers):<br />
https://github.com/bo3b/3DMigoto/commit/dde106498b06455133af025afe21a9147efaae18<br />
<br />
You might notice that the god ray pattern is similar for all the above engines... but things can get quite a bit more complicated:<br />
<br />
NVIDIA "Enhanced" god rays in Far Cry 4 (relatively simple for an approximation):<br />
https://github.com/bo3b/3DMigoto/commit/c713fad554177eca9d90c3f2840e0c05f326caa1<br />
<br />
Regular god rays in Far Cry 4 (very difficult):<br />
https://github.com/bo3b/3DMigoto/commit/007e1a26eb68f12dbc5e7c1f3ad3b887160361bb<br />
<br />
God rays in Miasmata (insanely difficult):<br />
https://github.com/DarkStarSword/3d-fixes/commit/8c8f51d2e0b8e583b09c3fe12d64ebbf1c9fa7e5<br />
https://github.com/DarkStarSword/3d-fixes/commit/d4a11aeae8bd69e04fa489f5acad80565e765f37<br />
<br />
<br />
<br />
<br />
Alternate Unity 4 shadow fix for games where the usual technique in my template doesn't work:<br />
https://github.com/DarkStarSword/3d-fixes/commit/da1483c728398e9c355dfad42cb550e9434557bb<br />
<br />
CryEngine 3 point lights/shadows:<br />
https://github.com/DarkStarSword/3d-fixes/commit/d26e85d9461af07875021cef97e6627f326f5e0b<br />
<br />
CryEngine 3 directional lights/shadows:<br />
https://github.com/DarkStarSword/3d-fixes/commit/06805484e6b65d6c52380f9271346f36ae232a27<br />
<br />
CryEngine 3 decales:<br />
https://github.com/DarkStarSword/3d-fixes/commit/8af18a481baffcf616bb0ea62f42135c51fd6cc4<br />
<br />
Multipass fog in Unreal Engine 3 (needs adjustments to *four* shaders to fix accurately):<br />
https://github.com/DarkStarSword/3d-fixes/commit/d4d9f63f8fd30c1b4e7e44cda743e6d2483b0cb6<br />
<br />
HBAO+ in Far Cry 4:<br />
https://forums.geforce.com/default/topic/897529/3d-vision/3d-hbao-normal-map-artefact-fix/<br />
<br />
Far Cry 4 underwater caustics:<br />
https://github.com/bo3b/3DMigoto/commit/87e48ff8ff3831511c99ecbab17e8286873dda91<br />
<br />
<br />
I could go on, but I think you get the idea.<br />
<br />
===== Moving to infinity =====<br />
https://forums.geforce.com/default/topic/882500/3d-vision/elite-dangerous-fix/post/4688379/#4688379</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Mike_notesMike notes2016-08-26T09:17:50Z<p>Bo3b admin: </p>
<hr />
<div><br />
==== Shadows ====<br />
<br />
<br />
Hi bo3b - yeah this is not the right shader for shadow rendering ;-) It's not always obvious, but a few clues are:<br />
<br />
- There is a ShadowMap sampler in there somewhere<br />
<br />
- There is a SomethingXXXToShadow or SomethinXXXToLight matrix in there (or the reverse!)<br />
<br />
- A World Coordinate is contructed from EyePos or CamPos, and a 3-comp texcoord<br />
<br />
- There is an InvView or InvProjView in there (usually generating something in world coords)<br />
<br />
- Recognize that you may not see the word "shadow" in a shader that actually plots shadows. As noted above you often need to look for matrices with "light" in them. This makes more sense because these matrices do a coordinate transformation to the "view" of where the light source is that either casts shadows or enhances the light on a surface, say like a spotlight (very much the same as the View transformation moving to the POV of the camera).<br />
<br />
I hope this stuff helps, I basically don't realize consciously nowadays what it is that I look for so writing this stuff down is useful for me too :-)<br />
<br />
Good link from Mike_ar69: [https://forums.geforce.com/default/topic/513190/3d-vision/how-to-fix-disable-shaders-in-games-dll-guide-and-fixes-/post/4069271/#4069271 Shadows.]<br />
<br />
Related awesome post from DarkStarSword regarding fixing shadows:[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4715553/#4715553 Shadow fixing]<br />
And [https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4722833/#4722833 The followup.]<br />
<br />
==== Basic learning ====<br />
+=================================================================================================<br />
The general "roadmap" for learning should be something like this:<br />
<br />
BEGINNER 1<br />
Beginner fixes do not require shader knowledge, or DX9 knowledge. You just need to learn "what to do". You will need to get familiar with the basic assembly syntax, but that's all. Studying other peoples fixes will help you absorb it pretty quickly, and bo3bs references above have loads of stuff. These beginner fixes are NOT using "full stereo correction", but more are 'moving things to fixed locations/depths' etc.<br />
1. Read the stuff on what the helixmod dll is, the difference between the debug and the releae<br />
2. Learn how to disable problematic shaders. This will crystalize your understanding of the basics of using the helixmod wrapper, stepping through shaders, editing them etc.<br />
3. Find a game (even if it's already been fixed!) that has a skybox at the wrong depth. Fix it using the instructions in the original Helix guides.<br />
4. Similarly, find a game with a 2D hud. Practice moving the hud elements to different depths.<br />
** When you can do the above 3 things, you will actually be in a great position to start creating fixes that make games playable. This is not insignificant!<br />
<br />
BEGINNER 2<br />
5. Next step would be spending a bit more time looking at how you "separate textures" - this is really useful for HUD fixes, so you can move some parts of the hud and not others. It's also essential for some games where fixing one part of the game (e.g. moving a HUD element to depth) also affects some entirely unrelated part of the game (objects in the world).<br />
** With the above, you can now do some fancy stuff :-)<br />
<br />
INTERMEDIATE 1<br />
Intermediate fixes start to require some knowledge of what is going on in the vertex shaders, and they start to use "full stereo correction" i.e. the actual formula that Nvidia uses to inject stereo in the drivers. Only Vertex shaders are involved.<br />
6. Haloing: A lot of the really nasty looking issues in games are caused when things "halo" or "double/triple image". There is an absolute (almost universal) reason for, pattern to fixing, all of these issues. I will state it here for when you are ready to tray this out. In a VS the "output position" variable is calculated from a View Projection transformation (you need to read about what that is), and this is what defines the coordinates of objects in the scene - the nvidia drivers specifically stereoizes these output variables. However, what often happens in games is that a temporary variable is used for the result of the VPM transform, and then used to set the output position variable. The problem comes when this same temporary position variable is additionally output to other "texcoords" that get used in later Pixel Shaders. These texcoords do not get stereoized by the Nvidia driver, and so in the pixel shaders they are the wrong coordinates. The fix is to manually stereoize the temp position variable before outputting to the texcoord. There are loads of example fixes for this<br />
7. Water: Many (but not all) water effects are vertex shader issues, and this is where you would start looking for a solution. Main issues are haloing and reflections. Both of these are often fixed the same way as above in point 6.<br />
<br />
ADVANCED <br />
These fixes require Pixel Shader correction. They require you to understand much better the graphics rendering stages, the coordinate systems, and the transformations between them, including what the stereo correction is doing - this background is actually the most important part. You still do *not* need to know much about shader programming, though it will start to help a teeny bit to understand how to apply matrix transforms. I am not going to go into detail right now, but there are a few levels at which PS correction is relevant:<br />
- Accepting a newly defined replacement variable from a parent VS and using that (e.g. a stereoized version of some texcoord that is needed in only one part of the PS, but not everwhere)<br />
- What is called "texture coordinate" corrections to offset where sample maps are sampled (often a texture coordinate needs to be "built' form something call vPos)<br />
- Direct correction of projection space coordinates (easiest) <br />
- Indirect correction of world space coordinates for deferred rendered shaders (hardest)<br />
<br />
+=================================================================================================<br />
<br />
==== SkyBox ====<br />
<br />
Hi bo3b. In a nutshell, it is whatever looks best :-) The standard formula almost never applies to skyboxes.<br />
<br />
That formula applies a correction where one has not been applied by the driver, or 'un-applies' a correction that should not have happened. Skyboxes are at the "correct" depth its just that the developer made that depth stupidly small. The usual way to fix a skybox is to just multiply stereoParams.x by a constant value (between 0-1). Sometimes that just does not seem to work well, or sometimes you need to multiply by a much bigger number than one, and oftentimes the skybox may still exhibit dependence on convergence. <br />
<br />
The fix "r10.x += stereoParams.x * (stereoParams.y);" basically removes the driver level convergence correction, leaving only whatever the depth correction was - so if the depth of the box was "1", this is equivalent to the usual correction of just multiplying stereoParams.x by a number between 0-1 (and in this case actually "1"). This fix will now be independent of convergence. If you look in other shaders you will see things like (r10.x += stereoParams.x * (-r10.w + stereoParams.y + 1); and what this is doing is completely offsetting the driver correction, "(-r10.w + stereoParams.y)" (making it at 2d screen depth) and then applying the max depth correction with the "1").<br />
<br />
Like I say it's all trial and error because it depends what arbitrary depth they set the skybox at. In AC3/4, they don't use the same depth for skybox, clouds, stars, sun or moon, hence the variation in ways to correct them, and hence the variation in lining them up.<br />
<br />
Sorry that was a bit longwinded, but the upshot is you try one of 4 approaches, in this order, and see what works best:<br />
<br />
# r10.x += stereoParams.x * [0-1] or [0-inf...];<br />
# r10.x += stereoParams.x * (stereoParams.y);<br />
# r10.x += stereoParams.x * (stereoParams.y) * [0-1];<br />
# r10.x += stereoParams.x * (- r10.w + stereoParams.y + [0-1]);<br />
<br />
- by 'works best' that means stays in the same place when separation and convergence are adjusted, or scales perfectly with the scene when they are adjusted. If the skybox goes in and out of depth as convergence is adjusted, that's generally not good unless the 'playing range' of convergence is such that not much movement happens.<br />
<br />
Hope that helps.</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Mike_notesMike notes2016-08-26T08:58:28Z<p>Bo3b admin: /* Shadows */</p>
<hr />
<div><br />
==== Shadows ====<br />
<br />
<br />
Hi bo3b - yeah this is not the right shader for shadow rendering ;-) It's not always obvious, but a few clues are:<br />
<br />
- There is a ShadowMap sampler in there somewhere<br />
<br />
- There is a SomethingXXXToShadow or SomethinXXXToLight matrix in there (or the reverse!)<br />
<br />
- A World Coordinate is contructed from EyePos or CamPos, and a 3-comp texcoord<br />
<br />
- There is an InvView or InvProjView in there (usually generating something in world coords)<br />
<br />
- Recognize that you may not see the word "shadow" in a shader that actually plots shadows. As noted above you often need to look for matrices with "light" in them. This makes more sense because these matrices do a coordinate transformation to the "view" of where the light source is that either casts shadows or enhances the light on a surface, say like a spotlight (very much the same as the View transformation moving to the POV of the camera).<br />
<br />
I hope this stuff helps, I basically don't realize consciously nowadays what it is that I look for so writing this stuff down is useful for me too :-)<br />
<br />
Good link from Mike_ar69: [https://forums.geforce.com/default/topic/513190/3d-vision/how-to-fix-disable-shaders-in-games-dll-guide-and-fixes-/post/4069271/#4069271 Shadows.]<br />
<br />
Related awesome post from DarkStarSword regarding fixing shadows:[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4715553/#4715553 Shadow fixing]<br />
And [https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4722833/#4722833 The followup.]<br />
<br />
==== Basic learning ====<br />
+=================================================================================================<br />
The general "roadmap" for learning should be something like this:<br />
<br />
BEGINNER 1<br />
Beginner fixes do not require shader knowledge, or DX9 knowledge. You just need to learn "what to do". You will need to get familiar with the basic assembly syntax, but that's all. Studying other peoples fixes will help you absorb it pretty quickly, and bo3bs references above have loads of stuff. These beginner fixes are NOT using "full stereo correction", but more are 'moving things to fixed locations/depths' etc.<br />
1. Read the stuff on what the helixmod dll is, the difference between the debug and the releae<br />
2. Learn how to disable problematic shaders. This will crystalize your understanding of the basics of using the helixmod wrapper, stepping through shaders, editing them etc.<br />
3. Find a game (even if it's already been fixed!) that has a skybox at the wrong depth. Fix it using the instructions in the original Helix guides.<br />
4. Similarly, find a game with a 2D hud. Practice moving the hud elements to different depths.<br />
** When you can do the above 3 things, you will actually be in a great position to start creating fixes that make games playable. This is not insignificant!<br />
<br />
BEGINNER 2<br />
5. Next step would be spending a bit more time looking at how you "separate textures" - this is really useful for HUD fixes, so you can move some parts of the hud and not others. It's also essential for some games where fixing one part of the game (e.g. moving a HUD element to depth) also affects some entirely unrelated part of the game (objects in the world).<br />
** With the above, you can now do some fancy stuff :-)<br />
<br />
INTERMEDIATE 1<br />
Intermediate fixes start to require some knowledge of what is going on in the vertex shaders, and they start to use "full stereo correction" i.e. the actual formula that Nvidia uses to inject stereo in the drivers. Only Vertex shaders are involved.<br />
6. Haloing: A lot of the really nasty looking issues in games are caused when things "halo" or "double/triple image". There is an absolute (almost universal) reason for, pattern to fixing, all of these issues. I will state it here for when you are ready to tray this out. In a VS the "output position" variable is calculated from a View Projection transformation (you need to read about what that is), and this is what defines the coordinates of objects in the scene - the nvidia drivers specifically stereoizes these output variables. However, what often happens in games is that a temporary variable is used for the result of the VPM transform, and then used to set the output position variable. The problem comes when this same temporary position variable is additionally output to other "texcoords" that get used in later Pixel Shaders. These texcoords do not get stereoized by the Nvidia driver, and so in the pixel shaders they are the wrong coordinates. The fix is to manually stereoize the temp position variable before outputting to the texcoord. There are loads of example fixes for this<br />
7. Water: Many (but not all) water effects are vertex shader issues, and this is where you would start looking for a solution. Main issues are haloing and reflections. Both of these are often fixed the same way as above in point 6.<br />
<br />
ADVANCED <br />
These fixes require Pixel Shader correction. They require you to understand much better the graphics rendering stages, the coordinate systems, and the transformations between them, including what the stereo correction is doing - this background is actually the most important part. You still do *not* need to know much about shader programming, though it will start to help a teeny bit to understand how to apply matrix transforms. I am not going to go into detail right now, but there are a few levels at which PS correction is relevant:<br />
- Accepting a newly defined replacement variable from a parent VS and using that (e.g. a stereoized version of some texcoord that is needed in only one part of the PS, but not everwhere)<br />
- What is called "texture coordinate" corrections to offset where sample maps are sampled (often a texture coordinate needs to be "built' form something call vPos)<br />
- Direct correction of projection space coordinates (easiest) <br />
- Indirect correction of world space coordinates for deferred rendered shaders (hardest)<br />
<br />
+=================================================================================================</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2016-01-02T06:30:54Z<p>Bo3b admin: /* HelixMod */</p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
* Gotcha - Any [VSxxxxxxxx] section must come ''after'' any key and preset definitions. Otherwise key functions will be silently disabled.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constant registers in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail. But ''add r30.x, c250.y, c250.x'' will work. Use temp registers as a workaround.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
* Gotcha - Reading from a masked component of an input register can cause strange results (in some cases fixing the issue is insufficient to make the weirdness go away and the game has to be restarted). e.g. if an input register was declared ''dcl_texcoord5 v6.xy'', then doing a ''mov r30, v6'' is illegal as it tries to read from all four components of v6, the z and w of which are invalid.<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. The alternate CRC is calculated by disassembling and reassembling the shader, which has the result of stripping any headers.<br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
If this is true there are a couple of things to keep in mind in the shader dumps:<br />
* Dumps/AllShaders/PixelShaders - files named by original CRC, headers intact<br />
* Dumps/AllShaders/VertexShaders - files named by original CRC, headers intact<br />
* Dumps/SingleShaders/PixelShasers - files named by '''alternate CRC''', '''headers removed'''<br />
* Dumps/SingleShaders/VertexShaders - files named by original CRC, '''headers removed'''<br />
<br />
It is unknown whether the original or alternate CRC must be used in the ShaderOverride directory for vertex shaders and/or pixel shaders. The fact that vertex shaders are still dumped using the original CRC suggests they may need to use the original CRC, but it is unclear.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. This enables wrapping games that use the Direct3DCreate9Ex() call instead of the regular call.<br />
<br />
If Helix mod does not work with a game and the LOG.txt contains only the following lines, you need this option:<br />
<br />
Start logging..<br />
Direct3DCreate9Ex Created<br />
<br />
It is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
UseDefinedOnly = false<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Logs any calls to SetViewport before the first Present call.<br />
<br />
Type: Boolean<br />
<br />
===== CalcMatrixOncePerFrame =====<br />
Limits the number of times that GetMatrixFromReg and GetMatrixFromReg1 will work in a frame (unconfirmed if working at all).<br />
<br />
BUG: If both GetMatrixFromReg and GetMatrixFromReg1 are used, only the first matrix will be copied, rendering the second copy slot useless.<br />
<br />
Type: Boolean<br />
<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Creates a new depth texture that can be passed into shaders. The texture will not automatically get depth information, but it can be passed into a shader as an extra render target with DepthWRT to allow the shader to copy depth (or presumably any other) information to it. It can then be added to another shader as a texture with DepthWReg.<br />
<br />
Note that it is important that the depth texture resolution matches other render targets when using DepthWRT. DepthGetDepthResFrom can be used to set this, but there may be situations where the only option is to use DepthForceWidth and DepthForceHeight.<br />
<br />
Note that in some cases this texture may be created in mono instead of stereo! To work around this (and related bugs) in Montague's Mount, I had to use DepthGetDepthResFrom = 2 and DefSurfaceCreationMode = 1 (since there is no way to force the surface creation mode with the default DepthGetDepthResFrom) to force it to stereo, then manually set DepthForceWidth and DepthForceHeight to match the resolution so it would not break the lighting shaders.<br />
<br />
The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
<br />
===== DepthGetDepthResFrom =====<br />
Determines how to get the resolution to use for the depth texture created with MakeWTexture=true and not using DepthForceWidth/Height.<br />
<br />
0 = use the back buffer resolution<br />
<br />
1 = use the resolution of a render target created with CreateRenderTarget(), provided it is *greater than* 800x600<br />
<br />
2 = use the resolution of a depth surface created with CreateDepthStencilSurface(), provided it is *greater than* 800x600<br />
<br />
Note that the texture may be created in mono instead of stereo depending on a number of factors. Setting this to 2 and using DefSurfaceCreationMode=1 can indirectly force it to stereo.<br />
<br />
===== DepthForceWidth =====<br />
Use to override the width of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthForceHeight =====<br />
Use to override the height of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthWFormat =====<br />
The D3DFORMAT of the depth texture created with MakeWTexture=true<br />
<br />
Default: 114 (D3DFMT_R32F)<br />
<br />
Type: Integer<br />
<br />
===== CheckDepthResolution =====<br />
If true, the resolution of the depth texture must match the resolution of an active render target in order to set it as an extra render target with DepthWRT.<br />
<br />
If false, the depth texture will be injected unconditionally as an extra render target on any shader with DepthWRT set (and if the size does not match the shader will stop working).<br />
<br />
Note that for vertex shaders, this checks the first *render target*, while for pixel shaders this checks the *depth/stencil target*. In practice this means that in some cases the check will not be performed as expected.<br />
<br />
Type: Boolean<br />
<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only be used when a texture in DefinedTexturesVS is in use, otherwise it will be disabled (skipped?). It is almost always a good idea to set this to false and do the filtering in the shader, if for no other reason than you will still see it if it uses a new texture that you haven't seen yet.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
Setting this between 500 and 508 (inclusive) will copy the corresponding render target 0-8 instead of a texture. -1 also appears to be a special value, though it's not clear for what.<br />
<br />
GetSampler3FromReg only works with pixel shaders, vertex shaders must use the first two.<br />
<br />
BUG: Using GetSampler3FromReg with a render target (ie. 500-508), will set sampler 1 instead!<br />
<br />
BUG: If using with a vertex shader OR a render target, the texture's width must match the resolution to be copied. See note below under S*TexW.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Filters the textures copied with GetSamplerNFromReg to textures that match a specific format.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
-1 to disable the filter and copy textures regardless of format.<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Supposed to filter the textures copied with GetSamplerNFromReg to textures matching the corresponding width & height, however is broken due to a bug.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
BUG: Can only match screen resolution, making it impossible to copy textures / render targets of other sizes.<br />
<br />
Set both to -2 to match the current resolution<br />
<br />
Supposed to use -1 to ignore one of the width/height and match on the other<br />
<br />
Other values supposed to match a given width & height<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number for vertex shaders.<br />
<br />
The depth texture will be blank unless it has been filled out by another shader using DepthWRT.<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DepthWRT ====<br />
Injects the depth texture created with MakeWTexture = true into this shader as an additional render target. The shader can then be modified to write information to this new render which can be copied to other shaders later. Note that if the depth texture does not match the resolution of other render targets assigned to the shader the whole shader will stop working (and Helix Mod has several bugs that can complicate this)!<br />
<br />
This option could be useful in e.g. a full-screen deferred lighting shader that can copy the depth buffer to the new render target (if copying the depth buffer directly with Helix Mod did not work).<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Note that if you have matched a texture using DefinedTexturesVS, this will be ignored for that draw call and the one in the matching [TEXnnnnnnnn] section will be used instead. In this case, the vertex buffer section must have the same hash as the matched TEXTURE.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Stores the contents of the first entry of the first vertex in this constant register. This will usually be the input position of one one of the vertices.<br />
<br />
It can be useful to get a consistent position across an entire icon/word for auto depth adjustments (used in Dreamfall Chapters), or to compare against to determine which corner a particular vertex is since DX9 has no SV_VertexID semantic.<br />
<br />
To get the screen position you will need to duplicate any code in the shader that derives the output position from the input position - this may be as simple as copying a matrix multiplication.<br />
<br />
I have observed that the input W may be 0, whereas the input W to dcl_position would usually be 1, which may throw out some calculations that depend on it.<br />
<br />
Requires CheckTexCRC = true, UseDefinedOnly = false, GetVertex = true (either in the VS section, or possibly in a TEX, VB or PT section if they match the draw call), VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] section to work.<br />
<br />
NOTE: If you are using this in conjunction with a DefinedTexturesVS list, you must also define [TEXnnnnnnnn] sections for all matched textures, which must contain a VBOffsetList = 0; and then you must define a (possibly empty) [VBnnnnnnnn.0] section with the hash of the texture. In that case the VB section with the hash of the shader will be used when the texture did not match the list.<br />
<br />
==== FirstTexVertexPosReg ====<br />
This is similar to FirstVertexPosReg, but it will only be updated when a texture in the DefinedTexturesVS list is matched, and only when the texture changes.<br />
<br />
The same requirements as FirstVertexPosReg apply here, and since this can only be used with DefinedTexturesVS it will always require the extra sections [TEX] and [VB] sections matching the texture hash.<br />
<br />
==== GetVertex ====<br />
Necessary to use FirstVertexPosReg, FirstTexVertexPosReg or GetMatrixTexFromReg. Possibly others.<br />
<br />
Type: Boolean<br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
This will copy a matrix from the shader, but only when the same constraints as described in FirstTexVertexPosReg are met. (untested)<br />
<br />
==== MatrixTexReg ====<br />
This will copy the matrix copied via GetMatrixTexFromReg into the shader.<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] or [TEXnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
The nnnnnnnn will usually match the hash of the corresponding shader section, BUT if a texture in a DefinedTextureVS section has been matched it must match that texture hash instead (and in that case VBOffsetList must be set in the [TEXnnnnnnnn] section).<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
Unknown exactly what this does. Appears to affect the offset into the vertex buffer used in some sort of comparison with the points list.<br />
<br />
Valid Values: 0, 1 (multiplies offset by 2), 2 (multiplies offset by 4)<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
This replaces the VBOffsetList in the shader section when the texture from this section is matched. The [VBnnnnnnnn.m] section it refers to uses the hash of the TEXTURE, not the shader.<br />
<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== Index =====<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces. The information for these surfaces comes from the LOG.txt file in lines starting with CreateDepthStencilSurface.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
<br />
----<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
<br />
Release versions from newest to oldest:<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Releasev2.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.upd.zip<br />
<br />
<br />
Debug From newest to oldest <br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Debug.zip<br />
<br />
<br />
DarkStarSword's binary patched version of the 140302 debug DLL:<br />
* Allows the LOG.txt to be opened while the game is running<br />
: 32bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/d3d9.dll<br />
: 64bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/x64/d3d9.dll<br />
<br />
<br><br />
<br><br />
<br />
<u>List of versions by date</u><br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2016-01-02T04:30:28Z<p>Bo3b admin: /* HelixMod */</p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
* Gotcha - Any [VSxxxxxxxx] section ''must'' come after any key and preset definitions. Otherwise key functions will be silently disabled.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constant registers in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail. But ''add r30.x, c250.y, c250.x'' will work. Use temp registers as a workaround.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
* Gotcha - Reading from a masked component of an input register can cause strange results (in some cases fixing the issue is insufficient to make the weirdness go away and the game has to be restarted). e.g. if an input register was declared ''dcl_texcoord5 v6.xy'', then doing a ''mov r30, v6'' is illegal as it tries to read from all four components of v6, the z and w of which are invalid.<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. The alternate CRC is calculated by disassembling and reassembling the shader, which has the result of stripping any headers.<br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
If this is true there are a couple of things to keep in mind in the shader dumps:<br />
* Dumps/AllShaders/PixelShaders - files named by original CRC, headers intact<br />
* Dumps/AllShaders/VertexShaders - files named by original CRC, headers intact<br />
* Dumps/SingleShaders/PixelShasers - files named by '''alternate CRC''', '''headers removed'''<br />
* Dumps/SingleShaders/VertexShaders - files named by original CRC, '''headers removed'''<br />
<br />
It is unknown whether the original or alternate CRC must be used in the ShaderOverride directory for vertex shaders and/or pixel shaders. The fact that vertex shaders are still dumped using the original CRC suggests they may need to use the original CRC, but it is unclear.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. This enables wrapping games that use the Direct3DCreate9Ex() call instead of the regular call.<br />
<br />
If Helix mod does not work with a game and the LOG.txt contains only the following lines, you need this option:<br />
<br />
Start logging..<br />
Direct3DCreate9Ex Created<br />
<br />
It is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
UseDefinedOnly = false<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Logs any calls to SetViewport before the first Present call.<br />
<br />
Type: Boolean<br />
<br />
===== CalcMatrixOncePerFrame =====<br />
Limits the number of times that GetMatrixFromReg and GetMatrixFromReg1 will work in a frame (unconfirmed if working at all).<br />
<br />
BUG: If both GetMatrixFromReg and GetMatrixFromReg1 are used, only the first matrix will be copied, rendering the second copy slot useless.<br />
<br />
Type: Boolean<br />
<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Creates a new depth texture that can be passed into shaders. The texture will not automatically get depth information, but it can be passed into a shader as an extra render target with DepthWRT to allow the shader to copy depth (or presumably any other) information to it. It can then be added to another shader as a texture with DepthWReg.<br />
<br />
Note that it is important that the depth texture resolution matches other render targets when using DepthWRT. DepthGetDepthResFrom can be used to set this, but there may be situations where the only option is to use DepthForceWidth and DepthForceHeight.<br />
<br />
Note that in some cases this texture may be created in mono instead of stereo! To work around this (and related bugs) in Montague's Mount, I had to use DepthGetDepthResFrom = 2 and DefSurfaceCreationMode = 1 (since there is no way to force the surface creation mode with the default DepthGetDepthResFrom) to force it to stereo, then manually set DepthForceWidth and DepthForceHeight to match the resolution so it would not break the lighting shaders.<br />
<br />
The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
<br />
===== DepthGetDepthResFrom =====<br />
Determines how to get the resolution to use for the depth texture created with MakeWTexture=true and not using DepthForceWidth/Height.<br />
<br />
0 = use the back buffer resolution<br />
<br />
1 = use the resolution of a render target created with CreateRenderTarget(), provided it is *greater than* 800x600<br />
<br />
2 = use the resolution of a depth surface created with CreateDepthStencilSurface(), provided it is *greater than* 800x600<br />
<br />
Note that the texture may be created in mono instead of stereo depending on a number of factors. Setting this to 2 and using DefSurfaceCreationMode=1 can indirectly force it to stereo.<br />
<br />
===== DepthForceWidth =====<br />
Use to override the width of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthForceHeight =====<br />
Use to override the height of the injected depth texture created with MakeWTexture=true<br />
<br />
===== DepthWFormat =====<br />
The D3DFORMAT of the depth texture created with MakeWTexture=true<br />
<br />
Default: 114 (D3DFMT_R32F)<br />
<br />
Type: Integer<br />
<br />
===== CheckDepthResolution =====<br />
If true, the resolution of the depth texture must match the resolution of an active render target in order to set it as an extra render target with DepthWRT.<br />
<br />
If false, the depth texture will be injected unconditionally as an extra render target on any shader with DepthWRT set (and if the size does not match the shader will stop working).<br />
<br />
Note that for vertex shaders, this checks the first *render target*, while for pixel shaders this checks the *depth/stencil target*. In practice this means that in some cases the check will not be performed as expected.<br />
<br />
Type: Boolean<br />
<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only be used when a texture in DefinedTexturesVS is in use, otherwise it will be disabled (skipped?). It is almost always a good idea to set this to false and do the filtering in the shader, if for no other reason than you will still see it if it uses a new texture that you haven't seen yet.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
Setting this between 500 and 508 (inclusive) will copy the corresponding render target 0-8 instead of a texture. -1 also appears to be a special value, though it's not clear for what.<br />
<br />
GetSampler3FromReg only works with pixel shaders, vertex shaders must use the first two.<br />
<br />
BUG: Using GetSampler3FromReg with a render target (ie. 500-508), will set sampler 1 instead!<br />
<br />
BUG: If using with a vertex shader OR a render target, the texture's width must match the resolution to be copied. See note below under S*TexW.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Filters the textures copied with GetSamplerNFromReg to textures that match a specific format.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
-1 to disable the filter and copy textures regardless of format.<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Supposed to filter the textures copied with GetSamplerNFromReg to textures matching the corresponding width & height, however is broken due to a bug.<br />
<br />
Applies when copying a texture from a vertex shader, or when copying a render target. NOT USED WHEN COPYING A TEXTURE FROM A PIXEL SHADER.<br />
<br />
BUG: Can only match screen resolution, making it impossible to copy textures / render targets of other sizes.<br />
<br />
Set both to -2 to match the current resolution<br />
<br />
Supposed to use -1 to ignore one of the width/height and match on the other<br />
<br />
Other values supposed to match a given width & height<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number for vertex shaders.<br />
<br />
The depth texture will be blank unless it has been filled out by another shader using DepthWRT.<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DepthWRT ====<br />
Injects the depth texture created with MakeWTexture = true into this shader as an additional render target. The shader can then be modified to write information to this new render which can be copied to other shaders later. Note that if the depth texture does not match the resolution of other render targets assigned to the shader the whole shader will stop working (and Helix Mod has several bugs that can complicate this)!<br />
<br />
This option could be useful in e.g. a full-screen deferred lighting shader that can copy the depth buffer to the new render target (if copying the depth buffer directly with Helix Mod did not work).<br />
<br />
The Montague's Mount fix uses this feature.<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Note that if you have matched a texture using DefinedTexturesVS, this will be ignored for that draw call and the one in the matching [TEXnnnnnnnn] section will be used instead. In this case, the vertex buffer section must have the same hash as the matched TEXTURE.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Stores the contents of the first entry of the first vertex in this constant register. This will usually be the input position of one one of the vertices.<br />
<br />
It can be useful to get a consistent position across an entire icon/word for auto depth adjustments (used in Dreamfall Chapters), or to compare against to determine which corner a particular vertex is since DX9 has no SV_VertexID semantic.<br />
<br />
To get the screen position you will need to duplicate any code in the shader that derives the output position from the input position - this may be as simple as copying a matrix multiplication.<br />
<br />
I have observed that the input W may be 0, whereas the input W to dcl_position would usually be 1, which may throw out some calculations that depend on it.<br />
<br />
Requires CheckTexCRC = true, UseDefinedOnly = false, GetVertex = true (either in the VS section, or possibly in a TEX, VB or PT section if they match the draw call), VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] section to work.<br />
<br />
NOTE: If you are using this in conjunction with a DefinedTexturesVS list, you must also define [TEXnnnnnnnn] sections for all matched textures, which must contain a VBOffsetList = 0; and then you must define a (possibly empty) [VBnnnnnnnn.0] section with the hash of the texture. In that case the VB section with the hash of the shader will be used when the texture did not match the list.<br />
<br />
==== FirstTexVertexPosReg ====<br />
This is similar to FirstVertexPosReg, but it will only be updated when a texture in the DefinedTexturesVS list is matched, and only when the texture changes.<br />
<br />
The same requirements as FirstVertexPosReg apply here, and since this can only be used with DefinedTexturesVS it will always require the extra sections [TEX] and [VB] sections matching the texture hash.<br />
<br />
==== GetVertex ====<br />
Necessary to use FirstVertexPosReg, FirstTexVertexPosReg or GetMatrixTexFromReg. Possibly others.<br />
<br />
Type: Boolean<br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
This will copy a matrix from the shader, but only when the same constraints as described in FirstTexVertexPosReg are met. (untested)<br />
<br />
==== MatrixTexReg ====<br />
This will copy the matrix copied via GetMatrixTexFromReg into the shader.<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] or [TEXnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
The nnnnnnnn will usually match the hash of the corresponding shader section, BUT if a texture in a DefinedTextureVS section has been matched it must match that texture hash instead (and in that case VBOffsetList must be set in the [TEXnnnnnnnn] section).<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
Unknown exactly what this does. Appears to affect the offset into the vertex buffer used in some sort of comparison with the points list.<br />
<br />
Valid Values: 0, 1 (multiplies offset by 2), 2 (multiplies offset by 4)<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
This replaces the VBOffsetList in the shader section when the texture from this section is matched. The [VBnnnnnnnn.m] section it refers to uses the hash of the TEXTURE, not the shader.<br />
<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== Index =====<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces. The information for these surfaces comes from the LOG.txt file in lines starting with CreateDepthStencilSurface.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
<br />
----<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
<br />
Release versions from newest to oldest:<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Releasev2.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Release.upd.zip<br />
<br />
<br />
Debug From newest to oldest <br />
: https://s3.amazonaws.com/-HeliX-/DLLS/DllsModPack1.zip<br />
: https://s3.amazonaws.com/-HeliX-/DllsModPack.zip<br />
: https://s3.amazonaws.com/Helixfix/DllsModPack.zip<br />
: https://s3.amazonaws.com/-HeliX-/DLLS/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Mainfiles/Debug.zip<br />
: https://s3.amazonaws.com/HelixMods/*Oldversion/Debug.zip<br />
<br />
<br />
DarkStarSword's binary patched version of the 140302 debug DLL:<br />
* Allows the LOG.txt to be opened while the game is running<br />
: 32bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/d3d9.dll<br />
: 64bit: https://github.com/DarkStarSword/3d-fixes/raw/master/__HELIX__/2014-03-02-DEBUG-BINARY-PATCHED/x64/d3d9.dll<br />
<br />
<br><br />
<br><br />
<br />
<u>List of versions by date</u><br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Mike_notesMike notes2015-12-20T10:37:31Z<p>Bo3b admin: </p>
<hr />
<div><br />
==== Shadows ====<br />
<br />
<br />
Hi bo3b - yeah this is not the right shader for shadow rendering ;-) It's not always obvious, but a few clues are:<br />
<br />
- There is a ShadowMap sampler in there somewhere<br />
<br />
- There is a SomethingXXXToShadow or SomethinXXXToLight matrix in there (or the reverse!)<br />
<br />
- A World Coordinate is contructed from EyePos or CamPos, and a 3-comp texcoord<br />
<br />
- There is an InvView or InvProjView in there (usually generating something in world coords)<br />
<br />
- Recognize that you may not see the word "shadow" in a shader that actually plots shadows. As noted above you often need to look for matrices with "light" in them. This makes more sense because these matrices do a coordinate transformation to the "view" of where the light source is that either casts shadows or enhances the light on a surface, say like a spotlight (very much the same as the View transformation moving to the POV of the camera).<br />
<br />
I hope this stuff helps, I basically don't realize consciously nowadays what it is that I look for so writing this stuff down is useful for me too :-)<br />
<br />
Good link from Mike_ar69: [https://forums.geforce.com/default/topic/513190/3d-vision/how-to-fix-disable-shaders-in-games-dll-guide-and-fixes-/post/4069271/#4069271 Shadows.]<br />
<br />
Related awesome post from DarkStarSword regarding fixing shadows:[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4715553/#4715553 Shadow fixing]<br />
And [https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4722833/#4722833 The followup.]</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Mike_notesMike notes2015-12-20T08:41:21Z<p>Bo3b admin: </p>
<hr />
<div><br />
==== Shadows ====<br />
<br />
<br />
Hi bo3b - yeah this is not the right shader for shadow rendering ;-) It's not always obvious, but a few clues are:<br />
<br />
- There is a ShadowMap sampler in there somewhere<br />
<br />
- There is a SomethingXXXToShadow or SomethinXXXToLight matrix in there (or the reverse!)<br />
<br />
- A World Coordinate is contructed from EyePos or CamPos, and a 3-comp texcoord<br />
<br />
- There is an InvView or InvProjView in there (usually generating something in world coords)<br />
<br />
- Recognize that you may not see the word "shadow" in a shader that actually plots shadows. As noted above you often need to look for matrices with "light" in them. This makes more sense because these matrices do a coordinate transformation to the "view" of where the light source is that either casts shadows or enhances the light on a surface, say like a spotlight (very much the same as the View transformation moving to the POV of the camera).<br />
<br />
I hope this stuff helps, I basically don't realize consciously nowadays what it is that I look for so writing this stuff down is useful for me too :-)<br />
<br />
<br />
Related awesome post from DarkStarSword regarding fixing shadows:[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4715553/#4715553 Shadow fixing]<br />
And [https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4722833/#4722833 The followup.]</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Mike_notesMike notes2015-12-20T08:17:07Z<p>Bo3b admin: /* Shadows */</p>
<hr />
<div><br />
==== Shadows ====<br />
<br />
<br />
Hi bo3b - yeah this is not the right shader for shadow rendering ;-) It's not always obvious, but a few clues are:<br />
<br />
- There is a ShadowMap sampler in there somewhere<br />
<br />
- There is a SomethingXXXToShadow or SomethinXXXToLight matrix in there (or the reverse!)<br />
<br />
- A World Coordinate is contructed from EyePos or CamPos, and a 3-comp texcoord<br />
<br />
- There is an InvView or InvProjView in there (usually generating something in world coords)<br />
<br />
- Recognize that you may not see the word "shadow" in a shader that actually plots shadows. As noted above you often need to look for matrices with "light" in them. This makes more sense because these matrices do a coordinate transformation to the "view" of where the light source is that either casts shadows or enhances the light on a surface, say like a spotlight (very much the same as the View transformation moving to the POV of the camera).<br />
<br />
I hope this stuff helps, I basically don't realize consciously nowadays what it is that I look for so writing this stuff down is useful for me too :-)<br />
<br />
<br />
Related awesome post from DarkStarSword regarding fixing shadows:[https://forums.geforce.com/default/topic/766890/3d-vision/bo3bs-school-for-shaderhackers/post/4715553/#4715553 Shadow fixing]</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=DarkStarSword_example_fixesDarkStarSword example fixes2015-11-24T11:03:33Z<p>Bo3b admin: Created page with "Whether you need to apply a fix in a vertex shader or a pixel shader depends on the effect you are trying to fix (and some can be fixed in either, and some need adjustments in..."</p>
<hr />
<div>Whether you need to apply a fix in a vertex shader or a pixel shader depends on the effect you are trying to fix (and some can be fixed in either, and some need adjustments in both).<br />
<br />
Halos are often (but not always) possible to fix in either, but are almost always easier to fix in the vertex shader (the biggest exception where a halo fix has had to go in the pixel shader has been water, but only in a few games). Shadows almost always need a fix in the pixel shader.<br />
<br />
When we talk about patterns we're usually talking about fixing an effect in an engine that someone has already worked out how to fix. Generally games using the same engine will have effects broken in the same way, so studying how we have fixed another game using the same engine will show you the patterns to fix that engine.<br />
<br />
You can look at any of the fixes on the blog, or go through the history of my 3d-fixes repository to find these patterns - if you find the first time I fixed a given effect in the history I'll have included some extra notes in the commit message and usually have added the original shader in a separate commit so that the diff will show what I actually changed:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/commits/master<br />
<br />
I also have a database of all DX9 shaders running on one of my servers - you can use the lookup_shader.py script in my 3d-fixes repository to look up any shader's CRC to see if it has been used in any fixes (DX9 games only for now) and show the difference between your local copy and any fixed versions.<br />
<br />
<br />
Asside from halos (which are an almost universal problem with an almost equally universal solution), here's a few other examples of patterns (some easy, some difficult, some insane):<br />
<br />
<br />
Move skybox to infinity (pattern applies to most, but not all games):<br />
https://github.com/DarkStarSword/3d-fixes/commit/7622a2940530d3a14b4bb1b556cdbbbfb0e3dec6<br />
<br />
<br />
<br />
Shadows in Unreal Engine 3 (fairly simple):<br />
https://github.com/DarkStarSword/3d-fixes/commit/3cbebd0e4b5af11729fa9db6959acc71623ee3b7<br />
<br />
However you will notice that any of my more recent DX9 UE3 fixes use a script (shadertool.py) that knows how to recognise the pattern and apply the fix automatically, including dealing with slight variations in registers/components selected by the compiler:<br />
https://github.com/DarkStarSword/3d-fixes/commit/82181b842fe6cf3e0d087a58d6a7309b0b5a134d<br />
<br />
<br />
<br />
God rays in Unreal Engine 3 (simple):<br />
https://github.com/DarkStarSword/3d-fixes/commit/ad6535c0534b68638dd2411a2ad770ccec3ba9f6<br />
<br />
God rays in CryEngine 3 (simple):<br />
https://github.com/DarkStarSword/3d-fixes/commit/76af7b96a19723172520f61cd778a79fedf970cc<br />
<br />
God rays in Euro Truck Simulator 2 (moderate - no headers):<br />
https://github.com/DarkStarSword/3d-fixes/commit/67b31c856c08a4d563eebd0901cd91b67ff6de1a<br />
<br />
God rays in Unity 4 (simple once headers were extracted):<br />
https://github.com/DarkStarSword/3d-fixes/commit/54831b2f00a9912daa514ac6df384376eecc1f97<br />
<br />
God rays + underwater crepuscular rays in Stranded Deep (also Unity, but more complex than the above):<br />
https://github.com/DarkStarSword/3d-fixes/commit/83d50b1eac65ebbb938a697ae4ef2e2882c2cfcb<br />
<br />
God rays in Witcher 3 (moderate - no headers):<br />
https://github.com/bo3b/3DMigoto/commit/dde106498b06455133af025afe21a9147efaae18<br />
<br />
You might notice that the god ray pattern is similar for all the above engines... but things can get quite a bit more complicated:<br />
<br />
NVIDIA "Enhanced" god rays in Far Cry 4 (relatively simple for an approximation):<br />
https://github.com/bo3b/3DMigoto/commit/c713fad554177eca9d90c3f2840e0c05f326caa1<br />
<br />
Regular god rays in Far Cry 4 (very difficult):<br />
https://github.com/bo3b/3DMigoto/commit/007e1a26eb68f12dbc5e7c1f3ad3b887160361bb<br />
<br />
God rays in Miasmata (insanely difficult):<br />
https://github.com/DarkStarSword/3d-fixes/commit/8c8f51d2e0b8e583b09c3fe12d64ebbf1c9fa7e5<br />
https://github.com/DarkStarSword/3d-fixes/commit/d4a11aeae8bd69e04fa489f5acad80565e765f37<br />
<br />
<br />
<br />
<br />
Alternate Unity 4 shadow fix for games where the usual technique in my template doesn't work:<br />
https://github.com/DarkStarSword/3d-fixes/commit/da1483c728398e9c355dfad42cb550e9434557bb<br />
<br />
CryEngine 3 point lights/shadows:<br />
https://github.com/DarkStarSword/3d-fixes/commit/d26e85d9461af07875021cef97e6627f326f5e0b<br />
<br />
CryEngine 3 directional lights/shadows:<br />
https://github.com/DarkStarSword/3d-fixes/commit/06805484e6b65d6c52380f9271346f36ae232a27<br />
<br />
CryEngine 3 decales:<br />
https://github.com/DarkStarSword/3d-fixes/commit/8af18a481baffcf616bb0ea62f42135c51fd6cc4<br />
<br />
Multipass fog in Unreal Engine 3 (needs adjustments to *four* shaders to fix accurately):<br />
https://github.com/DarkStarSword/3d-fixes/commit/d4d9f63f8fd30c1b4e7e44cda743e6d2483b0cb6<br />
<br />
HBAO+ in Far Cry 4:<br />
https://forums.geforce.com/default/topic/897529/3d-vision/3d-hbao-normal-map-artefact-fix/<br />
<br />
Far Cry 4 underwater caustics:<br />
https://github.com/bo3b/3DMigoto/commit/87e48ff8ff3831511c99ecbab17e8286873dda91<br />
<br />
<br />
<br />
I could go on, but I think you get the idea.</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Skybox_notesSkybox notes2015-09-13T00:04:53Z<p>Bo3b admin: Created page with "Hi bo3b. In a nutshell, it is whatever looks best :-) The standard formula almost never applies to skyboxes. That formula applies a correction where one has not been applied..."</p>
<hr />
<div>Hi bo3b. In a nutshell, it is whatever looks best :-) The standard formula almost never applies to skyboxes. <br />
<br />
That formula applies a correction where one has not been applied by the driver, or 'un-applies' a correction that should not have happened. Skyboxes are at the "correct" depth its just that the developer made that depth stupidly small. The usual way to fix a skybox is to just multiply stereoParams.x by a constant value (between 0-1). Sometimes that just does not seem to work well, or sometimes you need to multiply by a much bigger number than one, and oftentimes the skybox may still exhibit dependence on convergence. The fix "r10.x += stereoParams.x * (stereoParams.y);" basically removes the driver level convergence correction, leaving only whatever the depth correction was - so if the depth of the box was "1", this is equivalent to the usual correction of just multiplying stereoParams.x by a number between 0-1 (and in this case actually "1"). This fix will now be independent of convergence. If you look in other shaders you will see things like (r10.x += stereoParams.x * (-r10.w + stereoParams.y + 1); and what this is doing is completely offsetting the driver correction, "(-r10.w + stereoParams.y)" (making it at 2d screen depth) and then applying the max depth correction with the "1").<br />
Like I say it's all trial and error because it depends what arbitrary depth they set the skybox at. In AC3/4, they don't use the same depth for skybox, clouds, stars, sun or moon, hence the variation in ways to correct them, and hence the variation in lining them up.<br />
<br />
Sorry that was a bit longwinded, but the upshot is you try one of 4 approaches, in this order, and see what works best:<br />
1. r10.x += stereoParams.x * [0-1] or [0-inf...];<br />
2. r10.x += stereoParams.x * (stereoParams.y);<br />
3. r10.x += stereoParams.x * (stereoParams.y) * [0-1];<br />
4. r10.x += stereoParams.x * (- r10.w + stereoParams.y + [0-1]);<br />
<br />
- by 'works best' that means stays in the same place when separation and convergence are adjusted, or scales perfectly with the scene when they are adjusted. If the skybox goes in and out of depth as convergence is adjusted, that's generally not good unless the 'playing range' of convergence is such that not much movement happens.<br />
<br />
Hope that helps.</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Mike_notesMike notes2015-08-16T09:36:15Z<p>Bo3b admin: Created page with " ==== Shadows ==== Hi bo3b - yeah this is not the right shader for shadow rendering ;-) It's not always obvious, but a few clues are: - There is a ShadowMap sampler in the..."</p>
<hr />
<div><br />
==== Shadows ====<br />
<br />
<br />
Hi bo3b - yeah this is not the right shader for shadow rendering ;-) It's not always obvious, but a few clues are:<br />
<br />
- There is a ShadowMap sampler in there somewhere<br />
<br />
- There is a SomethingXXXToShadow or SomethinXXXToLight matrix in there (or the reverse!)<br />
<br />
- A World Coordinate is contructed from EyePos or CamPos, and a 3-comp texcoord<br />
<br />
- There is an InvView or InvProjView in there (usually generating something in world coords)<br />
<br />
- Recognize that you may not see the word "shadow" in a shader that actually plots shadows. As noted above you often need to look for matrices with "light" in them. This makes more sense because these matrices do a coordinate transformation to the "view" of where the light source is that either casts shadows or enhances the light on a surface, say like a spotlight (very much the same as the View transformation moving to the POV of the camera).<br />
<br />
I hope this stuff helps, I basically don't realize consciously nowadays what it is that I look for so writing this stuff down is useful for me too :-)</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=MediaWiki:SidebarMediaWiki:Sidebar2015-05-19T06:09:27Z<p>Bo3b admin: </p>
<hr />
<div><br />
* navigation<br />
** mainpage|mainpage-description<br />
** Levels of Fixing|Levels of fixes<br />
** List of glitches|List of glitches<br />
** HelixMod Feature List|HelixMod Feature List<br />
** Default_DX9Settings.ini|Default_DX9Settings.ini<br />
** Canonical Stereo Code|Canonical Stereo Code<br />
** Game Fixing Strategy|Game Fixing Strategy<br />
** Driver Profile Settings|Driver Profile Settings<br />
* wiki<br />
** recentchanges-url|recentchanges<br />
** randompage-url|randompage<br />
** helppage|help<br />
* SEARCH<br />
* TOOLBOX<br />
* LANGUAGES</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2015-01-05T02:54:31Z<p>Bo3b admin: </p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constant registers in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail. But ''add r30.x, c250.y, c250.x'' will work. Use temp registers as a workaround.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. <br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. ExtInterface is an internal programmatic thing with an "extended" set of capabilities that some newer games require. <br />
It is unclear when you would know to use this option, however it is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DepthForceWidth =====<br />
Type: Integer<br />
===== DepthForceHeight =====<br />
Type: Integer<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Type: Boolean<br />
===== CalcMatrixOncePerFrame =====<br />
Type: Boolean<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Appears to create a depth texture that can be passed into shaders. I have successfully injected it to a shader, but it was blank. The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
===== CheckDepthResolution =====<br />
Type: Boolean<br />
===== DepthWFormat =====<br />
The FourCC format of the depth texture created if MakeWTexture=true?<br />
<br />
Type: Integer<br />
===== DepthGetDepthResFrom =====<br />
Somehow related to MakeWTexture. At least 0, 1 and 2 appear to be valid values, possibly others.<br />
<br />
Type: Integer<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only have a valid stereo sampler when a texture in DefinedTexturesVS is in use, otherwise the stereo texture won't exist, effectively setting separation & convergence to 0 in the shader.<br />
<br />
Set this to false to always use the stereo sampler, to allow for more advanced filtering in the shader.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number.<br />
<br />
Note: I have only managed to inject a blank texture with this so far, it is unknown how to get this to work. Further analysis suggests that DepthWRT must be set for this to work.<br />
<br />
==== DepthWRT ====<br />
Unknown. Possibly related to MakeWTexture and DepthWReg? Appears to set a render target index to be used for the depth texture, and likely necessary to make it work.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Unknown. Presumably related to GetSamplerNFromReg<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Unknown. Presumably related to the width & height of the textures copied with GetSamplerNFromReg<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Unconfirmed: Stores the contents of the first entry of the vertex buffer in this constant register. Probably needs a VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] to work.<br />
<br />
==== FirstTexVertexPosReg ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
<br />
==== MatrixTexReg ====<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2015-01-05T02:53:50Z<p>Bo3b admin: /* ASM */</p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constant registers in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail. But ''add r30.x, c250.y, c250.x'' will work. Use temp registers as a workaround.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. <br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. ExtInterface is an internal programmatic thing with an "extended" set of capabilities that some newer games require. <br />
It is unclear when you would know to use this option, however it is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DepthForceWidth =====<br />
Type: Integer<br />
===== DepthForceHeight =====<br />
Type: Integer<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Type: Boolean<br />
===== CalcMatrixOncePerFrame =====<br />
Type: Boolean<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Appears to create a depth texture that can be passed into shaders. I have successfully injected it to a shader, but it was blank. The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
===== CheckDepthResolution =====<br />
Type: Boolean<br />
===== DepthWFormat =====<br />
The FourCC format of the depth texture created if MakeWTexture=true?<br />
<br />
Type: Integer<br />
===== DepthGetDepthResFrom =====<br />
Somehow related to MakeWTexture. At least 0, 1 and 2 appear to be valid values, possibly others.<br />
<br />
Type: Integer<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only have a valid stereo sampler when a texture in DefinedTexturesVS is in use, otherwise the stereo texture won't exist, effectively setting separation & convergence to 0 in the shader.<br />
<br />
Set this to false to always use the stereo sampler, to allow for more advanced filtering in the shader.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number.<br />
<br />
Note: I have only managed to inject a blank texture with this so far, it is unknown how to get this to work. Further analysis suggests that DepthWRT must be set for this to work.<br />
<br />
==== DepthWRT ====<br />
Unknown. Possibly related to MakeWTexture and DepthWReg? Appears to set a render target index to be used for the depth texture, and likely necessary to make it work.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Unknown. Presumably related to GetSamplerNFromReg<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Unknown. Presumably related to the width & height of the textures copied with GetSamplerNFromReg<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Unconfirmed: Stores the contents of the first entry of the vertex buffer in this constant register. Probably needs a VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] to work.<br />
<br />
==== FirstTexVertexPosReg ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
<br />
==== MatrixTexReg ====<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2015-01-05T02:53:11Z<p>Bo3b admin: /* ASM */</p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constants in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail. ''add r30.x, c250.y, c250.x'' will work. Use temp registers as a workaround.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. <br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. ExtInterface is an internal programmatic thing with an "extended" set of capabilities that some newer games require. <br />
It is unclear when you would know to use this option, however it is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DepthForceWidth =====<br />
Type: Integer<br />
===== DepthForceHeight =====<br />
Type: Integer<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Type: Boolean<br />
===== CalcMatrixOncePerFrame =====<br />
Type: Boolean<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Appears to create a depth texture that can be passed into shaders. I have successfully injected it to a shader, but it was blank. The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
===== CheckDepthResolution =====<br />
Type: Boolean<br />
===== DepthWFormat =====<br />
The FourCC format of the depth texture created if MakeWTexture=true?<br />
<br />
Type: Integer<br />
===== DepthGetDepthResFrom =====<br />
Somehow related to MakeWTexture. At least 0, 1 and 2 appear to be valid values, possibly others.<br />
<br />
Type: Integer<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only have a valid stereo sampler when a texture in DefinedTexturesVS is in use, otherwise the stereo texture won't exist, effectively setting separation & convergence to 0 in the shader.<br />
<br />
Set this to false to always use the stereo sampler, to allow for more advanced filtering in the shader.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number.<br />
<br />
Note: I have only managed to inject a blank texture with this so far, it is unknown how to get this to work. Further analysis suggests that DepthWRT must be set for this to work.<br />
<br />
==== DepthWRT ====<br />
Unknown. Possibly related to MakeWTexture and DepthWReg? Appears to set a render target index to be used for the depth texture, and likely necessary to make it work.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Unknown. Presumably related to GetSamplerNFromReg<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Unknown. Presumably related to the width & height of the textures copied with GetSamplerNFromReg<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Unconfirmed: Stores the contents of the first entry of the vertex buffer in this constant register. Probably needs a VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] to work.<br />
<br />
==== FirstTexVertexPosReg ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
<br />
==== MatrixTexReg ====<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2015-01-05T02:41:51Z<p>Bo3b admin: </p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constants in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. <br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. ExtInterface is an internal programmatic thing with an "extended" set of capabilities that some newer games require. <br />
It is unclear when you would know to use this option, however it is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DepthForceWidth =====<br />
Type: Integer<br />
===== DepthForceHeight =====<br />
Type: Integer<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Type: Boolean<br />
===== CalcMatrixOncePerFrame =====<br />
Type: Boolean<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Appears to create a depth texture that can be passed into shaders. I have successfully injected it to a shader, but it was blank. The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
===== CheckDepthResolution =====<br />
Type: Boolean<br />
===== DepthWFormat =====<br />
The FourCC format of the depth texture created if MakeWTexture=true?<br />
<br />
Type: Integer<br />
===== DepthGetDepthResFrom =====<br />
Somehow related to MakeWTexture. At least 0, 1 and 2 appear to be valid values, possibly others.<br />
<br />
Type: Integer<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only have a valid stereo sampler when a texture in DefinedTexturesVS is in use, otherwise the stereo texture won't exist, effectively setting separation & convergence to 0 in the shader.<br />
<br />
Set this to false to always use the stereo sampler, to allow for more advanced filtering in the shader.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number.<br />
<br />
Note: I have only managed to inject a blank texture with this so far, it is unknown how to get this to work. Further analysis suggests that DepthWRT must be set for this to work.<br />
<br />
==== DepthWRT ====<br />
Unknown. Possibly related to MakeWTexture and DepthWReg? Appears to set a render target index to be used for the depth texture, and likely necessary to make it work.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Unknown. Presumably related to GetSamplerNFromReg<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Unknown. Presumably related to the width & height of the textures copied with GetSamplerNFromReg<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Unconfirmed: Stores the contents of the first entry of the vertex buffer in this constant register. Probably needs a VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] to work.<br />
<br />
==== FirstTexVertexPosReg ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
<br />
==== MatrixTexReg ====<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2015-01-05T02:40:33Z<p>Bo3b admin: /* Gotchas */</p>
<hr />
<div>== Gotchas ==<br />
<br />
===== HelixMod =====<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments (in fact - all lines the DLL does not understand) from the DX9Settings.ini. It seems that comments starting with a semicolon instead of a double slash are retained.<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
===== ASM =====<br />
<br />
* Gotcha - You cannot use two different constants in a given instruction. ''add r30.x, c250.y, c220.x'' will silently fail.<br />
<br />
* Gotcha - Output registers cannot be read. ''mov r3, o0'' will silently fail, but still assemble. Overwriting an output register works.<br />
<br />
== Helix Mod Advanced Techniques, Tips and Tricks ==<br />
<br />
This section is mostly for advanced techniques that may be useful in certain situations. For the basics of using Helix mod, refer to the lessons.<br />
<br />
=== Shader Hunting a Vertex Shader for a Given Pixel Shader (or vice versa) ===<br />
<br />
If you are having difficulty finding a pixel or vertex shader for a given effect, but you are able to find the other type of shader for the effect, you can look at the numbers next to VertexPair and PixelPair to work out possible shaders.<br />
<br />
e.g. If you are looking for a pixel shader for an effect, but can only identify the vertex shader, cycle until the vertex shader is disabled and look at the number next to VertexPair. Then cycle pixel shaders to that same number and you will be on the corresponding pixel shader.<br />
<br />
Note that these numbers may change while cycling shaders, so I'd suggest cycling both pixel and vertex shaders to different effects and back to make sure the numbers still match up.<br />
<br />
e.g. If you have successfully disabled both vertex and pixel shaders for the same effect, you will have VS = PixelPair and PS = VertexPair, like this:<br />
<br />
VS 36 CRC32 0xblah PS 28 CRC32 0xblah ... VertexPair 28 PixelPair 36<br />
<br />
Also, keep in mind that that some effects may have multiple layers, so you may need to check several shader pairs (and sometimes these even have the same CRCs for one of the shaders) to find the right one.<br />
<br />
=== Texture Hunting and Filtering ===<br />
<br />
If you have altered a shader and find it is affecting things that you would rather leave alone, you need to find a way to distinguish between the different effects it is used for. This is quite common for UI shaders, where you may only want to adjust the depth for part of the UI (e.g. crosshair), or where you find the UI shader also affects other non-UI things in the scene. One common technique do achieve this is by filtering on the CRC of the texture used for the effects.<br />
<br />
To get started you will need to identify the CRCs of the relevant textures. Helix mod supports hunting for textures in much the same way as it does for shaders. To get started you first need to add bCalcTexCRCatStart = true in the ini. The up/down arrow keys will cycle textures by default, but you can change them with PrevTexKey and NextTexKey if they interfere with the game.<br />
<br />
For the most part textures will go black while they are disabled, and once you have found the right one you should write down the CRC displayed in the red text (if they are shorter than 8 characters, pad them with zeros in the same way we do for shaders).<br />
<br />
You will need to add a section similar to the following to the ini file (replace nnnnnnnn with the CRC of the vertex shader you are filtering in):<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
ValForDefined = 1<br />
ValNotDefined = 0<br />
TexCounterReg = 251<br />
UseDefinedOnly = false<br />
DefinedTexturesVS = 01234567;89ABCDEF;<br />
<br />
The DefinedTexturesVS list needs to be filled out with the texture CRCs you found. You have two choices - you either need to list all the textures where you *DO* want the depth adjustment to be enabled (whitelisting), or list those where you *DON'T* want the adjustment to be enabled (blacklisting), but *not both*. If you can only find textures for some of the effects that might force your decision, or if you find that one way would require you to keep finding more and more textures it might be easier to go the other way (e.g. for a while in Dreamfall Chapters I was whitelisting every texture used on an inventory object, but that didn't seem smart as I'd have to keep finding more and more textures, so I blacklisted the inventory background instead).<br />
<br />
It's probably worthwhile leaving a comment in the ini with what CRC corresponds with what. It's also a good idea to leave a comment for the textures you didn't inlcude in the DefiendTexturesVS list as well, so if find you need to invert the test later on you don't have to hunt them all again.<br />
<br />
In the shader you will be able to determine if the texture was in the list or not by testing the x component of the constant register defined by TexCounterReg (c251.x in this example). If it is in the list, it will have the value in ValForDefined (1.0 in this example), otherwise it will have the value defined by ValNotDefined (0.0 in this example).<br />
<br />
Then, in the shader you add an if_eq around the stereo adjustment, something like:<br />
<br />
def c220, 0, 1, 0.0625, 0.5 // Added a 0 and 1 in .x and .y of this constant<br />
<br />
// ...<br />
<br />
// We can't use two constant registers in the same instruction, so copy<br />
// TexCounterReg to a temporary register first:<br />
mov r29.x, c251.x<br />
<br />
// Test if the texture is whitelisted if TexCounterReg.x == ValForDefined<br />
// For blacklisting, check if TexCounterReg.x == ValNotDefined instead<br />
if_eq r29.x, c220.y<br />
<br />
// Whatever needs to be conditional, e.g. a UI depth adjustment:<br />
texldl r31, c220.z, s0<br />
mad r30.x, r31.x, c200.z, r30.x<br />
<br />
endif<br />
<br />
// Anything that needs to always happen, e.g. copying the temporary position<br />
// register to the output position register:<br />
mov o1, r30<br />
<br />
Reliability: Sometimes a texture will have a different CRC every time the game is launched which will make it impossible to filter on. In this case the test should be inverted to avoid the need for that CRC, or an alternate filtering method will need to be employed.<br />
<br />
Pixel Shaders: Helix Mod appears to support texture filtering in pixel shaders as well (with DefinedTexturesPS and a TexCounterReg no higher than 223), however it appears that this may not work. One possible workaround might be to use the vertex shader to pass the TexCounterReg through to the pixel shader as an extra texcoord output.<br />
<br />
<br />
=== Overriding an Individual Instance of a Shader ===<br />
<br />
If you find multiple shaders with the same CRC and need to apply different fixes to each instance, you can add an index number to the filename, as in XXXXXXXX.txt.1, XXXXXXXX.txt.2 and so on.<br />
<br />
This technique was originally documented here:<br />
<br />
http://helixmod.blogspot.com/2012/03/dlls-update.html<br />
<br />
Examples of fixes using this technique:<br />
<br />
* http://helixmod.blogspot.com/2014/01/divinity-original-sin-alpha-3d-vision.html<br />
<br />
* http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
=== Overriding a Vertex Shader Based on the Matching Pixel Shader ===<br />
<br />
If you find a vertex shader that is used for multiple effects and you need to apply different fixes to different instances of the vertex shader you need to find a way to distinguish between them. If they use different pixel shaders you may be able to use this technique to do so.<br />
<br />
You will need to hunt down the pixel shaders for each of the effects you need to fix. These will all need to be added to the ShaderOverride\PixelShaders folder, though you do not need to alter them (except maybe to upgrade them to ps_3_0 if they are an earlier version).<br />
<br />
Then, rename your vertex shader to the CRC of the pixel shader and add a .txt.ps extension (e.g. if the pixel shader for the UI was 12345678.txt, you would rename the vertex shader to Shaderoverride\VetexShaders\12345678.txt.ps). Make a copy of this shader for each pixel shader and name it appropriately.<br />
<br />
Then, apply the appropriate fix for each of the vertex shaders for whichever pixel shader they correspond with.<br />
<br />
Default vertex shader:<br />
<br />
If you find a vertex shader used for a lot of effects and most of them need to be fixed in the same way, you may prefer to leave a default vertex shader with it's original filename for most of the effects, and use the pixel shader specific ones only where you need a different fix. Note that reliability issues have been noted in this case, where a pixel shader specific vertex shader may sometimes be used in other instances.<br />
<br />
Example:<br />
<br />
In Montague's Mount, one of the vertex shaders is used for three different effects - part of the UI, the lens flare and halos around lights. Originally I was using the texture filtering technique to distinguish between UI and flare/halos and depth to distinguish between flares and halos:<br />
<br />
https://github.com/DarkStarSword/3d-fixes/blob/c8956ee23d6ad7518dd31b1bbe6c2467b10c158c/Montague%27s%20Mount/ShaderOverride/VertexShaders/CD61F9B3.txt<br />
<br />
As an experiment, I replaced the texture filtering technique with these two separate vertex shaders (the flare and halos use the same pixel shader, so I still needed the depth test to distinguish between them):<br />
<br />
* UI: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/75DCC6F8.txt.ps<br />
<br />
* Lens flare/halo: https://github.com/DarkStarSword/3d-fixes/blob/acf86f567ef91cfc6e6d5557294f0bf47bc7d337/Montague%27s%20Mount/ShaderOverride/VertexShaders/4028F8B5.txt.ps<br />
<br />
* diff: https://github.com/DarkStarSword/3d-fixes/commit/acf86f567ef91cfc6e6d5557294f0bf47bc7d337<br />
<br />
<br />
=== Inserting a Missing Vertex Shader Before a Pixel Shader ===<br />
<br />
This is a variation on the above, but for the situation where you need to move the position of an effect, but no vertex shader exists for the effect, but a pixel shader does. In this case you will have to manufacture a new vertex shader that has the passes it's inputs straight through to it's outputs (except for the position which you are adjusting).<br />
<br />
Presumably you would need to pass through any inputs that the pixel shader uses, such as texcoords, colors, etc.<br />
<br />
This technique is known to be used in the X3 fix:<br />
<br />
http://helixmod.blogspot.com/2012/03/x3-terran-conflict-and-albion-prelude.html<br />
<br />
<br />
<br />
== Overview of DX9Settings.ini ==<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. <br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces & render targets:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface & render target declarations in the DX9Settings.ini file in sections labelled "[SFn]" (surfaces) and "[RTn]" (render targets), where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for all surfaces (except non-texture render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all non-square render targets:<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
Default rendering mode for square render targets are instead set by DefSquareSurfaceMode, and individual render targets may be overridden in "[RTn]" sections.<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is like "SurfaceCreationModeList" but for render targets. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. ExtInterface is an internal programmatic thing with an "extended" set of capabilities that some newer games require. <br />
It is unclear when you would know to use this option, however it is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
This key does several things:<br />
<br />
- Writes out TEXTURESLOG.txt, which can be used to find texture CRCs, as well as other information about the vertex buffers passed to the shader. In order to have useful information in the log, you need [VSnnnnnnnn] and [VBnnnnnnnn.m] sections for a shader, with at least:<br />
<br />
[VSnnnnnnnn]<br />
CheckTexCRC = true<br />
VBOffsetList = 0;<br />
<br />
[VBnnnnnnnn.0]<br />
<br />
<br />
- If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
- If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
If you get a crash when pressing this key, it may be due to a conflict with the screenshot feature of the Steam overlay. Remap one of the two functions to a different button, or kill the steam overlay.<br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DepthForceWidth =====<br />
Type: Integer<br />
===== DepthForceHeight =====<br />
Type: Integer<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Type: Boolean<br />
===== CalcMatrixOncePerFrame =====<br />
Type: Boolean<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Appears to create a depth texture that can be passed into shaders. I have successfully injected it to a shader, but it was blank. The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
===== CheckDepthResolution =====<br />
Type: Boolean<br />
===== DepthWFormat =====<br />
The FourCC format of the depth texture created if MakeWTexture=true?<br />
<br />
Type: Integer<br />
===== DepthGetDepthResFrom =====<br />
Somehow related to MakeWTexture. At least 0, 1 and 2 appear to be valid values, possibly others.<br />
<br />
Type: Integer<br />
===== DeptIsNilReg =====<br />
Unknown. Seems to define a constant register which can be used to query if the depth render target has been used (?). Appears to be related to MakeWTexture and DepthWRT. The x component is initially set to 1 and will be set to 0 when the depth texture created with MakeWTexture is first set as a render target. The register is never set back to 1.<br />
<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== CheckTexCRC ====<br />
Set to true to enable filtering by the textures in the DefinedTexturesVS list of this shader.<br />
<br />
==== DefinedTexturesVS ====<br />
Requires CheckTexCRC = true<br />
<br />
List the texture CRCs to filter on in this shader. Note that there are several ways you can filter, refer to UseDefinedOnly and TexCounterReg for more details.<br />
<br />
==== UseDefinedOnly ====<br />
If this is true (default), the shader will only have a valid stereo sampler when a texture in DefinedTexturesVS is in use, otherwise the stereo texture won't exist, effectively setting separation & convergence to 0 in the shader.<br />
<br />
Set this to false to always use the stereo sampler, to allow for more advanced filtering in the shader.<br />
<br />
==== TexCounterReg ====<br />
This defines a constant register with an X component that can be tested in the shader to determine whether a texure in DefinedTexturesVS is in use, and possibly which one. If using this you will almost certainly want to set UseDefinedOnly = false as well.<br />
<br />
e.g. TexCounterReg = 251 will allow you to test c251.x in the shader.<br />
<br />
Set ValForDefined and ValNotDefined to distinct values for simple cases where you need to filter based on the texture being in the list, or not in the list.<br />
<br />
If you need to know precisely which texture is in use, add [TEXnnnnnnnn] sections for the relevant texture CRCs and set index to a value in those sections. That index value will be accessible through TexCounterReg. You can use this in conjunction with ValForDefined/ValNotDefined to set a default value, and have specific textures override this with a different value.<br />
<br />
==== ValForDefined ====<br />
This will set the default value of the constant defined by TexCounterReg when the texture is in the DefinedTexturesVS list.<br />
<br />
May be overridden by the index setting in a [TEXnnnnnnnn] section for a specific texture.<br />
<br />
==== ValNotDefined ====<br />
This will set the value of the constant defined by TexCounterReg when the texture is NOT in the DefinedTexturesVS list.<br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler from this shader to be reused in a different shader.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<br />
'''WARNING:''' Setting these may cause the relevant constant to always be 0 (possibly dependent on the scene draw order), as the reset flag doesn't get cleared after the first successful SetConstNToReg (confirmed in World of Diving).<br />
<br />
After a constant copied from another shader has been set, this will clear it (set to 0) on the next DirectX Present call, effectively making them only have a non-zero value while the shader they were copied from is active in the scene.<br />
<br />
An alternative method to determine if a constant is currently valid, is to use PresIndex in the shader(s) it was taken from to set a ConstN register to 1.0 which can be tested in the destination shader(s). This has been used in the World of Diving fix to determine if the projection matrix is available, or must be calculated from the inverse model-view and model-view-projection matrices.<br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
'''NOTE:''' It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
'''NOTE:''' This will only work in games that do not grab the mouse.<br />
<br />
'''NOTE:''' This only works in vertex shaders. If you need it in a pixel shader, you will have to pass it from the vertex shader as an additional output.<br />
<br />
'''WARNING:''' It appears that in some games this can get out of sync with the real mouse position by moving it to the edge of the screen.<br />
<br />
==== DefVSSampler ====<br />
Used to override the global DefVSSampler in this vertex shader. Add 257 to the sampler number - e.g. DefVSSampler = 260 will use s3 in this shader.<br />
<br />
==== DefVSViewSizeConst ====<br />
Used to override the global DefVSViewSizeConst in this vertex shader.<br />
<br />
==== DefVSIdxConst ====<br />
Used to override the global DefVSIdxConst in this shader.<br />
<br />
==== PresetConst1 ====<br />
Used to override DefVSConst1 in this shader (unconfirmed)<br />
<br />
==== PresetConst2 ====<br />
Used to override DefVSConst2 in this shader (unconfirmed)<br />
<br />
==== PresIndex ====<br />
Used to activate a preset while this shader is active in the scene (unconfirmed). Note that this is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so these will need to be converted for values above 9.<br />
<br />
==== DepthWReg ====<br />
Defines the sampler register to inject the depth texture created with MakeWTexture = true. Add 257 to the sampler number.<br />
<br />
Note: I have only managed to inject a blank texture with this so far, it is unknown how to get this to work. Further analysis suggests that DepthWRT must be set for this to work.<br />
<br />
==== DepthWRT ====<br />
Unknown. Possibly related to MakeWTexture and DepthWReg? Appears to set a render target index to be used for the depth texture, and likely necessary to make it work.<br />
<br />
==== Sampler1RTType, Sampler2RTType, Sampler3RTType ====<br />
Unknown. Presumably related to GetSamplerNFromReg<br />
<br />
==== S1TexW, S1TexH, S2TexW, S2TexH, S3TexW, S3TexH ====<br />
Unknown. Presumably related to the width & height of the textures copied with GetSamplerNFromReg<br />
<br />
==== DefStage ====<br />
<br />
Appears to affect which surface level (mip-map?) of a texture is used for the CRC calculation (unconfirmed).<br />
<br />
==== VBOffsetList ====<br />
<br />
Exact meaning uncertain, but necessary to use the [VBnnnnnnnn.m] sections to work with vertex buffers (inputs to vertex shaders) - Fill this list out with all values of m you need.<br />
<br />
Usage: VBOffsetList = 0;1;<br />
<br />
==== FirstVertexPosReg ====<br />
<br />
Unconfirmed: Stores the contents of the first entry of the vertex buffer in this constant register. Probably needs a VBOffsetList = 0; and a (possibly empty) [VBnnnnnnnn.0] to work.<br />
<br />
==== FirstTexVertexPosReg ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== UseAsm ====<br />
<br />
==== GetMatrixTexFromReg ====<br />
<br />
==== MatrixTexReg ====<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== GroupsList ====<br />
It is unknown what this does, but it appears to be related to the [GPnnnnnnnn] sections.<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
==== CompareType ====<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== Index ====<br />
This replaces the value of the register defined by TexCounterReg in a [VSnnnnnnnn] section. It is used when a shader needs to know when a specific texture is in use.<br />
<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
NOTE: PresIndex is in *DECIMAL*, but the [PRES%X] sections are in *HEXADECIMAL*, so if you are using a preset number above 9 you will need to convert them. e.g. PresIndex = 512 will match [PRES200].<br />
<br />
==== AddOffset ====<br />
==== AddPoint ====<br />
==== GetVertex ====<br />
Unknown, but as a side effect it looks like the LOG.txt may print out a 'SecName4: PTnnnnnnn' for this section if this is true.<br />
<br />
=== [GPnnnnnnnn] ===<br />
Appears to be related to group lists. It is unknown how this works. Appears to support the following options, which seem to be similar to the standard ConstN options supported by Helix Mod, but are completely independent. Possibly provides a means for a shader to distinguish between different objects being drawn?<br />
<br />
* Def1Val<br />
* Def2Val<br />
* Const1Reg<br />
* Const2Reg<br />
* Const1X<br />
* Const1Y<br />
* Const1Z<br />
* Const1W<br />
* Const2X<br />
* Const2Y<br />
* Const2Z<br />
* Const2W<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (except non-texture render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file - look for lines starting with D3DUSAGE_RENDERTARGET/D3DUSAGE_DEPTHSTENCIL.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== Format ====<br />
This refers to the format of the surface and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular surface in pixels.<br />
<br />
==== Width ====<br />
The width of the particular surface in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is similar to [SFn], but for render targets rather than surfaces. These are individual sections that define a set of characteristics for different render targets which thus specifies a subset of all of the currently created render targets, and then defines the stereo render mode for this subset of render targets. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of render targets will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file in lines starting with CreateRenderTarget.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=HelixMod_Feature_ListHelixMod Feature List2014-12-13T09:04:18Z<p>Bo3b admin: /* Overview of DX9Settings.ini */</p>
<hr />
<div>== Overview of DX9Settings.ini ==<br />
<br />
* Gotcha - it's a good to add comments to your DX9Settings.ini, but beware that comments must go on their own separate lines. If you add them to the end of a line the entire line will be ignored.<br />
<br />
* Gotcha - Pressing F7 in the game (to save custom separation and convergence settings to a preset) will remove all comments from the DX9Settings.ini<br />
<br />
* Gotcha - Games can sometimes crash when moving the view with the mouse, when a particular shader is disabled while hunting. Press the Numpad- key to clear the disable list before moving to a new spot.<br />
<br />
=== [General] ===<br />
<br />
==== UseAlternateCRC ====<br />
This is either true or false. It is unclear if this was a general feature or specific to a given game. It is believed that it was provided to get round the issue whereby a game will write the installation directory to the shaders, so the CRCs are different depending on where the game is installed. <br />
<br />
Currently only know to be used in DarkSiders2.<br />
<br />
==== DefModuleName ====<br />
This is used in conjunction with the separate helix launcher tool to define the name of the game executable to hook to. It was introduced to get around issues some games had with Steam, Uplay etc.<br />
<br />
==== InitMouse ====<br />
This is either true or false.<br />
<br />
Set to false if you find a game where the mouse stops working.<br />
<br />
==== ProxyLib ====<br />
Used to specify another d3d9 proxy dll to pass onto after "finishing" the helix dll operation. Often used to specifiy other post-process injectors like sweetfx etc.<br />
<br />
==== UseRenderedShaders ====<br />
UseRenderedShaders=true is nearly always useful, because it trims the list of shaders seen while hunting down to just those active in the current scene. Disable this only if you get crashes during hunting.<br />
<br />
==== DumpAll ====<br />
DumpAll will generate ASM text files for every shader seen by the game. This is usually worth doing once, but not useful for every run.<br />
<br />
==== DefPSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from pixel shaders.<br />
<br />
Defaults to s13<br />
<br />
==== DefVSSampler ====<br />
Defines which sampler register is used to retrieve the stereo settings from vertex shaders.<br />
<br />
Note that you need to add 257 to the desired sampler number (this quirk only applies to vertex shaders).<br />
<br />
Defaults to s0<br />
<br />
==== DefVSConst1 ====<br />
Defines which c register Const1 through Const4 will end up in in vertex shaders.<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w. e.g. to access Const2 you would use c200.y if DefVSConst1 is set to 200.<br />
<br />
It's a good idea to search through the AllShaders dump to find a constant register that is not used by the game.<br />
<br />
==== DefPSConst1 ====<br />
Same as DefVSConst1, but for pixel shaders.<br />
<br />
==== DefVSConst2 ====<br />
Defines which c register Const5 through Const7 will end up in in vertex shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
Note that all four constant values end up in the one register as x, y, z and w.<br />
<br />
==== DefPSConst2 ====<br />
Same as DefVSConst2, but for pixel shaders.<br />
<br />
NOTE THAT THIS IS NOT WHERE Const2 ENDS UP - THAT IS IN DefVSConst1!<br />
<br />
==== PresetsKeysList ====<br />
Defines which KEY sections are used by the DLL. Note that every number in this list needs to be followed by a semicolon, including the last number.<br />
<br />
==== UseEndScene ====<br />
This can be "true" or "false". If you have issues with the rendering of the red CRC text, so either you can't see it, or on occasion it gets rendered *in game*, projected on objects, or perhaps it might be rendered as really large text, cycle these values.<br />
<br />
==== bCalcTexCRCatStart ====<br />
Enables cycling of textures using PrexTexKey and NextTexKey<br />
<br />
==== PrevTexKey ====<br />
Defines which key cycles backwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Down<br />
<br />
==== NextTexKey ====<br />
Defines which key cycles forwards through textures. Must have bCalcTexCRCatStart = true<br />
<br />
Default Value: Up<br />
<br />
==== DefPSViewSizeConst ====<br />
This has a default value of 221. It is used to store screen size in the x and y values, and the inverse screen sizes in the z and w values. <br />
This is primarilly useful when you need to map from x-y coordinates passed into a PS via the vPOS variable to "texture coordinates" for use in samplers.<br />
<br />
==== DefSquareSurfaceMode ====<br />
Sets the default stereoization rendering mode for all square surfaces (render targets):<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
This is most relevant for shadow maps, which are usually square, and which must be forced to mono.<br />
<br />
==== DefDepthStencilSurfaceMode ====<br />
Sets the default stereoization rendering mode for all depth surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefSurfaceCreationMode ====<br />
Sets the default stereoization rendering mode for ALL surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
This can be overridden by individual surface declaration in the DX9Settings.ini file in sections labelled "[SFn]", where n is a number.<br />
<br />
==== DefRtCreationMode ====<br />
Sets the default stereoization rendering mode for all Rectangular (specifcially non-square) surfaces (render targets):<br />
0 = render according to Nvidia automatic<br />
1 = render forcing this surface to be stereoized<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== SurfaceCreationModeList ====<br />
Defines a list of of which surface properties defined in the DX9Settings.ini to load in an use for override purposes in sections labelled [SFn], where n is one of the list values.<br />
Usage: SurfaceCreationModeList = 0;2;3;<br />
Note - you must use ";" and you must have a ";" at the end of the list.<br />
<br />
==== RtCreationModeList ====<br />
This is the same as "SurfaceCreationModeList" but just for the subset of surfaces that are non-square. Individual settings are defined in sections labelled [RTn], where n is one of the list values.<br />
<br />
==== DepthStencilSurfaceModeList ====<br />
Same as "SurfaceCreationModeList", but for all depth surfaces. Individual settings are defined in sections labelled [DSn], where n is one of the list values.<br />
<br />
==== SkipSetScissorRect ====<br />
This is set to either true or false. It is best to always default this to "true".<br />
It instructs the renderer to ignore (when it can) the application of a feature that tries to save memory by using a stencil cutout to limit the area that needs rendering. In 3D this leads to issues with parts of an object or effect being "cut-off" at the edges. It is not possible to always fix this in all games though.<br />
<br />
==== OverrideMethod ====<br />
Can have values of 0,1 or 2.<br />
It is unknown exactly what these are doing, and for most games it does not matter which one is used, but if any given game there seems to be an issue loading in shader fixes (e.g. if you press F10 and nothing happens), cycle through the options.<br />
The value of 2 seems to have been added to cater for preshaders. In this case you should be able to to just comment out the preshader sections in a shader. It is not clear if this always works.<br />
<br />
==== GetCurDirAtLoad ====<br />
Set to true if you want to force the dll to look in the game exe dir (where the dll is) for the settings file, shader folders etc.<br />
Set to false otherwise.<br />
Exists because some games get linked to the parent directory etc to look for shader folders. Mostly seems to work, and is a good default option.<br />
<br />
==== UseExtInterfaceOnly ====<br />
This can be either true or false. ExtInterface is an internal programmatic thing with an "extended" set of capabilities that some newer games require. <br />
It is unclear when you would know to use this option, however it is known to be necessary for newer Telltale games such as Wolf Among Us and Walking Dead.<br />
<br />
==== PSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through pixel shaders<br />
<br />
Default Value: Numpad 1<br />
<br />
==== PSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through pixel shaders<br />
<br />
Default Value: Numpad 2<br />
<br />
==== PSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled pixel shader to a file<br />
<br />
Default Value: Numpad 3<br />
<br />
==== VSPREVKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles backwards through vertex shaders<br />
<br />
Default Value: Numpad 4<br />
<br />
==== VSNEXTKEY ====<br />
DEBUG DLL ONLY - Defines which key cycles forwards through vertex shaders<br />
<br />
Default Value: Numpad 5<br />
<br />
==== VSSAVEKEY ====<br />
DEBUG DLL ONLY - Defines which key dumps the currently disabled vertex shader to a file<br />
<br />
Default Value: Numpad 6<br />
<br />
==== PSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled pixel shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Numpad 7<br />
<br />
==== PSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected pixel shader from the skip list<br />
<br />
Default Value: Numpad 8<br />
<br />
==== PSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all pixel shaders from the skip list<br />
<br />
Default Value: Numpad 9<br />
<br />
==== VSADDTOSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Add the currently disabled vertex shader to the skip list, to allow multiple shaders to be disabled simultaneously<br />
<br />
Default Value: Home<br />
<br />
==== VSRMFROMSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove the currently selected vertex shader from the skip list<br />
<br />
Default Value: End<br />
<br />
==== VSCLRSKIPLSTKEY ====<br />
DEBUG DLL ONLY - Remove all vertex shaders from the skip list<br />
<br />
Default Value: Insert<br />
<br />
==== RELOADSHADERSKEY ====<br />
DEBUG DLL ONLY - Defines which key reloads the shaders from the ShaderOverrides directory.<br />
<br />
Note: Shaders must have been succesfully overridden at launch for the reload to work, therefore it is a good idea to start the game with known working shaders if you intend to edit them while the game is running<br />
<br />
Default Value: F10<br />
<br />
==== SHOWTEXTKEY ====<br />
DEBUG DLL ONLY - Toggles the red debug text on and off<br />
<br />
Default Value: Pause<br />
<br />
==== SaveTextureLogKey ====<br />
Writes out TEXTURESLOG.txt. <!-- Can someone expand this? So far my log files have been pretty useless --><br />
<br />
If GetSamplerNFromReg is enabled on a shader, pressing this key will also save the texture captured from that sampler to TexN.dds.<br />
<br />
If MakeWTexture=true this will also save out Depth.dds, but so far I've only ended up with a blank texture.<br />
<br />
Note that these DDS files may not be readable by all tools, depending on what format (fourCC) the texture is in and what formats the tools support.<br />
<!-- Can someone add a list of uesful tools to view these files? gimp-dds can handle S3 compressed textures, but I'm not sure that is useful for anything dumped out using this - it didn't handle format 71 --><br />
<br />
Default Value: F12<br />
<br />
==== SaveSettingsKey ====<br />
Defines which key re-writes DX9Settings.ini with custom convergence and separation settings to the active preset.<br />
<br />
Must have UseSepSettings = true and SaveSepSettings = true in a preset to be useful.<br />
<br />
CAUTION: Comments are removed from the ini when this key is pressed!<br />
<br />
Default Value: F7<br />
<br />
==== GameProfile ====<br />
Set the default stereo profile for the game. Set to the name of the executable<br />
in the desired profile, not the name of the profile.<br />
<br />
This is useful to automate selecting an alternate stereo profile to enable<br />
various stereo tweaks in the driver, but should be considered potentially<br />
unreliable. If a game is already assigned to a profile this will be ignored,<br />
and further - a game can become assigned to a profile at any time (e.g. this<br />
happens when using Ctrl+F7 to save convergence settings) and may lose the<br />
desired settings from this profile.<br />
<br />
Notably, the setting to enable stereo in windowed mode for DX9 titles seems to<br />
be preserved even if a profile is created with Ctrl+F7, so it seems safe to use<br />
for that purpose. I recommend using the "3D-Hub Player" profile for that<br />
purpose, as in:<br />
<br />
GameProfile = fxdplayer<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered in Helix Mod, but need further testing to determine how and if they work. Please edit the page if you can fill in more details about them.<br />
<br />
===== TexToMonoKey =====<br />
Uncertain. Force the currently selected texture to mono?<br />
<br />
Default Value: U<br />
<br />
===== TexToStereoKey =====<br />
Uncertain. Force the currently selected texture to stereo?<br />
<br />
Default Value: I<br />
<br />
===== DefPSIdxConst =====<br />
Unknown. Probably defines which constant register the pixel shader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== DefVSIdxConst =====<br />
Unknown. Probably defines which constant register the vertexshader index can be read from?<br />
<br />
Default Value: 222<br />
<br />
===== SHOWINFOKEY =====<br />
Unknown.<br />
<br />
Default Value: F11<br />
<br />
===== DepthForceWidth =====<br />
Type: Integer<br />
===== DepthForceHeight =====<br />
Type: Integer<br />
===== ForceWidth =====<br />
Type: Integer<br />
===== ForceHeight =====<br />
Type: Integer<br />
===== BehaviourFlags =====<br />
Type: Integer<br />
===== UseAsm =====<br />
Type: Boolean<br />
===== StartDump =====<br />
Type: Boolean<br />
===== CalcMatrixOncePerFrame =====<br />
Type: Boolean<br />
===== CalcTexCRCatUpdate =====<br />
Type: Boolean<br />
===== MakeWTexture =====<br />
Appears to create a depth texture that can be passed into shaders. I have successfully injected it to a shader, but it was blank. The texture can be dumped out with F12 as Depth.dds.<br />
<br />
Type: Boolean<br />
===== CheckDepthResolution =====<br />
Type: Boolean<br />
===== DepthWFormat =====<br />
The FourCC format of the depth texture created if MakeWTexture=true?<br />
<br />
Type: Integer<br />
===== DepthGetDepthResFrom =====<br />
Somehow related to MakeWTexture. At least 0, 1 and 2 appear to be valid values, possibly others.<br />
<br />
Type: Integer<br />
===== DeptIsNilReg =====<br />
Note the misspelling of Depth as Dept.<br />
<br />
Type: Integer (-1 is disabled, valid values are unknown)<br />
===== ClearShaders =====<br />
Appears to change what Helix mod does on device reset.<br />
<br />
Type: Integer (1 to enable, "true" will not work)<br />
===== ForceRefRate =====<br />
Type: Boolean<br />
===== ResetCRCatReload =====<br />
Type: Boolean<br />
==== ReloadTexturesListKey ====<br />
Default Value: F8<br />
<br />
=== [KEY*] ===<br />
Replace * with a number. These sections are used to activate presets when pressing or holding various keys or mouse buttons.<br />
<br />
Note that you must include all of these sections in the PresetsKeysList under [General] otherwise they will be ignored by HelixMod. For instance, if you have defined sections for [KEY1], [KEY3] and [KEY7], then you must set PresetsKeysList = 1;3;7;<br />
<br />
==== Key ====<br />
This specifies the keycode in decimal.<br />
<br />
Microsoft virtual keycodes for Key= use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal:<br />
http://msdn.microsoft.com/en-us/library/ms927178.aspx<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column:<br />
http://www.asciitable.com/<br />
<br />
501 is the right mouse button, which is useful to switch presets while holding aim in some games.<br />
<br />
==== Type ====<br />
Type=1 will activate when the key is pressed down.<br />
<br />
Type=2 is momentary - it will activate the first preset when the key is pressed down, and the second preset when the key is released.<br />
<br />
==== Presets ====<br />
This specifies which PRES* sections are activated by this key.<br />
<br />
Each number in this list should end with a semicolon, including the last one.<br />
<br />
Note that the order in this list is unimportant, however the numerical value of each of the presets does!<br />
<br />
For type 2 keys, there should be exactly two entries in the list - the lower numbered entry will be activated while the button is held and the higher numbered entry will be activated when the button is released.<br />
<br />
For type 1 keys you can have one or more entries in this list. If you have more than one entry it will cycle through each of them in numerical order when the key is pressed, wrapping back to the first after the last one. A list of two presets would toggle between each of them.<br />
<br />
==== Delay ====<br />
Defines an optional delay in milliseconds before the next preset will be activated.<br />
<br />
Only seems to affect the 'to' and not the 'from' when using Type=2<br />
<br />
=== [PRES*] ===<br />
Replace * with a number. These sections define various presets that can be activated with key presses.<br />
<br />
These sections should be referenced from the Presets list in at least one KEY* section.<br />
<!-- Does it work if you have a preset section that isn't refered to from a KEY section at all? e.g. if you just want a UseByDef to set some initial values that you don't intend to be changed while the game is running? --><br />
<br />
==== Const1, Const2, Const3, Const4, Const5, Const6, Const7, & Const8 ====<br />
Each of these can be used to set a value that can be accessed from shaders through the c register defined by DefVSConst1 and DefPSConst1 (or DefVSConst2/DefPSConst2). The first four of these make up the x, y, z and w values of a single c register. The notation is confusing, as Const2 will be the y value of DefVSConst1.<br />
<br />
As an example:<br />
<nowiki><br />
DefVSConst1 = 240<br />
Const1 = 240.x<br />
Const2 = 240.y<br />
Const3 = 240.z<br />
Const4 = 240.w<br />
DefVSConst2 = 241<br />
Const5 = 241.x<br />
Const6 = 241.y<br />
Const7 = 241.z<br />
Const8 = 241.w<br />
</nowiki><br />
<br />
These must be specified in hex (see below).<br />
<br />
==== UseByDef ====<br />
If true, this preset will be activated when the game is started.<br />
<br />
If this preset can also be activated via a key press, it is recommended to make the numerically highest preset associated with that key the default. Otherwise the first time the key is pressed it may not appear to do anything as it activated the already active preset.<br />
<br />
UseByDef can be set on multiple presets. This is useful if you have several independent preset groups - e.g. one group to control the convergence settings, and another to select different UI depths.<br />
<br />
==== UseSepSettings ====<br />
Set to true to allow this preset to change the separation and/or convergence settings.<br />
<br />
==== SaveSepSettings ====<br />
Set to true to allow custom separation & convergence settings to be saved in this preset.<br />
<br />
To use it the preset must be activated in the game (UseByDef=true does not seem to be sufficient) while the user adjusts their settings via the normal keybindings for the driver. With the preset still active they then press F7 (not to be confused with Ctrl+F7) which will cause HelixMod to write the new settings to DX9Settings.ini<br />
<br />
CAUTION: Pressing F7 will strip all comments from DX9Settings.ini!<br />
<br />
==== Separation ====<br />
Set a custom separation value between 0.0 and 100.0 when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
==== Convergence ====<br />
Set a custom convergence value when this preset is activated. You must also set UseSepSettings=true for this to work. The value must be specified in hex (see below).<br />
<br />
=== [VSnnnnnnnn] ===<br />
These sections define custom settings for specific vertex shaders. Replace nnnnnnnn with the 8 digit CRC32 of the vertex shader.<br />
<br />
==== DefStage ====<br />
<!-- Can someone fill this out? --> <br />
<br />
==== CheckTexCRC ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== VBOffsetList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== ValForDefined ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== ValNotDefined ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== TexCounterReg ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== UseDefinedOnly ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== DefinedTexturesVS ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== FirstVertexPosReg ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== GetVertex ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== UseMatrix, UseMatrix1 ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg, MatrixReg1 ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg, GetMatrixFromReg1 ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix, InverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix, DoubleInverseMatrix1 ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConst1ToReg, SetConst2ToReg, SetConst3ToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader via GetConstNFromReg to be reused in this shader. <br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConst1FromReg, GetConst2FromReg, GetConst3FromReg ====<br />
These allow up to three constant registers defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
==== ResetConst1AfterSet, ResetConst2AfterSet, ResetConst3AfterSet ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== MousePosReg ====<br />
Specifies a constant register to store the X and Y coordinates of the mouse.<br />
<br />
The coordinates are scaled too high and need to be divided by 1000, e.g:<br />
<nowiki>[VS12345678]<br />
MousePosReg = 210<br />
<br />
ShaderOverride\VertexShaders\12345678.txt:<br />
def c220, 0, 0, 0.0625, 0.001<br />
...<br />
mov r13.xy, c210.xy<br />
mul r13.xy, r13.xy, c220.ww<br />
</nowiki><br />
<br />
InitMouse must be true (or not specified) for this to work.<br />
<br />
It may not work when the game is first launched - if it doesn't work alt+tab out of the game and back in.<br />
<br />
This will only work in games that do not grab the mouse.<br />
<br />
=== [VBnnnnnnnn.m] ===<br />
This is of the form [VBnnnnnnnn.m], where the "m" relates to the value set in the "VBOffsetList" field of the related [VSnnnnnnnn] section.<br />
The way textures are stored and accessed is through Vertex Buffers, which are lists. No one really knows how this works, but it is the syntax that is necessary for it to work.<br />
<br />
==== PointsList ====<br />
Set to a numeric value. Currently believed only to be a way to identify this override operation in the LOG and/or textures.log files.<br />
<br />
Usage: "PointsList = 554" OR "PointsList = 3E8B0000"<br />
<br />
==== Offset ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== IsDisabledList ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== StartResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResW ====<br />
<!-- Can someone fill this out? --><br />
<br />
==== EndResH ====<br />
<!-- Can someone fill this out? --><br />
<br />
<br />
=== [TEXnnnnnnnn] ===<br />
Used to identify one of the textures by the 8-digit CRC specified in the "DefinedTexturesVS" list for a vertex shader.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given texture is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
==== Index ====<br />
Usage: Index = n<br />
<br />
==== VBOffsetList ====<br />
Usage: VBOffsetList = 0;<br />
<br />
=== [PTnnnnnnnn] ===<br />
Used to identify one of the points lists (?) by the 8-digit CRC. It is unknown where this information comes from.<br />
<br />
==== PresIndex ====<br />
Usage: PresIndex = 8<br />
<br />
Used to specify a particular preset index that is to be activated when the given point list is active. Its used for things like setting automatic convergence in different games scenes.<br />
<br />
=== [PSnnnnnnnn] ===<br />
These sections define custom settings for specific pixel shaders. Replace nnnnnnnn with the 8 digit CRC32 of the pixel shader.<br />
<br />
==== UseMatrix ====<br />
Either "true" or "False".<br />
<br />
Specifies whether this VS will re-use a matrix from another shader.<br />
<br />
==== MatrixReg ====<br />
Usage MatrixReg = nnn<br />
<br />
where nnn is the register for a matrix that was specified in another shader subsection using the "GetMatrixFromReg" field. Note that this "get" statement can be in the same shader, it does not have to be a different shader - this is required if you want the inverse of a matrix.<br />
<br />
==== GetMatrixFromReg ====<br />
Usage: GetMatrixFromReg = nnn<br />
<br />
Sets the matrix with register nnn in *this* shader to be a re-usable constant register in all other shaders (including itself).<br />
<br />
==== InverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then the matrix specified in "MatrixReg" will actually be the inverse of the matrix that was re-used.<br />
<br />
==== DoubleInverseMatrix ====<br />
This is either true or false.<br />
<br />
If true then a *Second* register is created 4 values higher than the first one defined in "MatrixReg" which stores the Inverse of the Inverse i.e. gets back to the original matrix that was shared in the first place. This might seem odd but it provides significantly better numerical stability. An example would be that a shader "shares' its matrix that was in register 8. This is then set to register 200 in the shader that is reusing it. If both matrix inverse settings are true, the registers will be as follows: 200, 201, 202, 203 will have the inverse matrix; 204, 205, 206, 207 will have the original matrix.<br />
<br />
==== GetSampler1FromReg, GetSampler2FromReg, GetSampler3FromReg ====<br />
This allows a sampler register defined in this shader to be re-used in other shaders.<br />
<br />
Usage: GetSampler1FromReg = 12<br />
<br />
This means that the sampler s12 will be made available to other shaders, and identified as accessed using the "SetSampler1ToReg" field.<br />
<br />
The texture on these captured samplers can be dumped out by pressing the key assigned to SaveTextureLogKey (default F12) as Tex1.dds, Tex2.dds and Tex3.dds.<br />
<br />
==== SetSampler1ToReg, SetSampler2ToReg, SetSampler3ToReg ====<br />
This allows a sampler that has been shared in another shader to be reused in this shader. <br />
<br />
Usage: SetSampler1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a sampler "s10" that can be used as if it was defined in the shader itself.<br />
<br />
==== SetConstNToReg ====<br />
This allows a Constant (4-component) register that has been shared in another shader to be reused in this shader. <br />
<br />
"N" is an integer that identifies the specific register that has been shared in another shader. The starting value for N is "1", but it is not known what the max value of "N" is.<br />
<br />
Usage: SetConst1ToReg = 10<br />
<br />
This will mean that in this shader, there will be accessible a constant "c10" that can be used as if it was defined in the shader itself.<br />
<br />
==== GetConstNFromReg ====<br />
This allows a constant register defined in this shader to be re-used in other shaders.<br />
<br />
"N" is an integer that identifies the specific constant register that is to be shared. The starting value for N is "1", but it is not known what the max value of "N" is.<br />
<br />
Usage: GetConst1FromReg = 123<br />
<br />
This means that the register c123 will be made available to other shaders, and identified as accessed using the "SetConst1ToReg" field.<br />
<br />
=== [SFn] ===<br />
These are individual sections that define a set of characteristics for different surfaces (render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file.<br />
The value of "n" is an integer from 0 - 9. <br />
The question immediately arises as to how on earth you know what surfaces are doing what. Bascially you don't, so you usually just need to systematically go through all (unique) surfaces listed in the LOG.txt file, setting the DefMode parameter to 0 and 1 and see what happens. That being said, if you read up on MSDN, the "Format" field can be used to work out what type of effect/operation is being done i.e. some formats are used for depth surfaces, some for lights, some for water etc. There is also information on the resolutions that are common for different effects (though games with multiple quality levels may have different resolutions, and also if you change the game resolution you may need to cover more etc). On the whole though this is a bit of a grind with some guesswork.<br />
<br />
These sections must be referred to from the SurfaceCreationModeList or they will not be processed.<br />
<br />
==== DefMode ====<br />
This is the stereoization mode to apply to all surfaces that meet the criteria specified for this surface:<br />
<br />
0 = render according to Nvidia automatic<br />
<br />
1 = render forcing this surface to be stereoized<br />
<br />
2 = render forcing this surface to be monoscopic<br />
<br />
==== Format ====<br />
This refers to the format of the render target and how the different components are encoded. You don't need to know this, the LOG.txt file will specify what the format is for each surface created. You can find out what the different codes mean by looking on MSDN.<br />
Usege: "Format = 21"<br />
<br />
==== Usage ====<br />
This parameter is also identified for a given surface in the LOG.txt file. It refers to whether a given surface is used as a depth buffer or not.<br />
<br />
==== Height ====<br />
The height of the particular render target in pixels.<br />
<br />
==== Width ====<br />
The width of the particular render target in pixels.<br />
<br />
==== UseBackBufRes ====<br />
This is either true or false and refers to setting the width and height to be that of the current back buffer.<br />
<br />
==== Levels ====<br />
Usage: Levels = 1<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== Pool ====<br />
Usage: Pool = 0<br />
<br />
This parameter is also identified for a given surface in the LOG.txt file.<br />
<br />
==== UNKNOWN FEATURES ====<br />
These features have been discovered, but need testing to determine how/if they work.<br />
===== IndexList =====<br />
===== ResStartWidth =====<br />
===== ResStartHeight =====<br />
===== ResEndWidth =====<br />
===== ResEndHeight =====<br />
===== ExceptSquare =====<br />
===== ForceWidth =====<br />
===== ForceHeight =====<br />
===== IsDisabled =====<br />
<br />
=== [RTn] ===<br />
This is very similar to [SFn], but is pre-subsetted for non-square surfaces. These are individual sections that define a set of characteristics for different surfaces (render targets) which thus specifies a subset of all of the currently created surfaces, and then defines the stereo render mode for this subset of surfaces. There are a number of fields that can be set, and the more that are set, the more tightly defined and specific (and smaller) the subset of surfaces will be that are affected by the stereo setting. The information for these surfaces comes from the LOG.txt file.<br />
The value of "n" is an integer from 0 - 9. <br />
All fields are the same as for [SFn].<br />
<br />
These sections must be referred to in the RTCreationModeList to be processed.<br />
<br />
=== [DSn] ===<br />
Similar to [SFn] and [RTn], but for depth stencil surfaces.<br />
<br />
These sections must be referred to in the DepthStencilSurfaceModeList to be processed.<br />
<br />
== Hex to Float conversion ==<br />
Several values in the ini file are floating point values that must be specified in hex. These include Separation, Convergence, Const1, Const2, Const3 and Const4.<br />
<br />
You can use this online converter to convert between float and hex:<br />
http://gregstoll.dyndns.org/~gregstoll/floattohex/<br />
<br />
Alternatively, if you prefer working in a command line environment, you might considder this Python script:<br />
https://raw.githubusercontent.com/DarkStarSword/3d-fixes/master/float_to_hex.py<br />
<br />
== List of features supported by HelixMod, and all versions available. ==<br />
<br />
Horizontally across the top, we've got versions of the DLL, based on the mod-date found in the zip file. We are using the YYMMDD format.<br />
<br />
Going down vertically, we have the different features that are available. Not all features are available or work in all DLLs.<br />
<br />
<br />
Entries in the table are:<br />
* blank if untested or unknown to work.<br />
* '''OK''' if tested and known to work.<br />
* '''X''' if tested and known to fail.<br />
<br><br />
<br><br />
<br />
{| class="wikitable"<br />
|- <br />
! || 140302 || 130906 || 130305 || 120401 || 120304 <br />
|-<br />
!colspan="6" style="text-align:left;"|[General] <br />
|-<br />
! DumpAll || OK || OK || OK || OK || X<br />
|-<br />
! UseRenderedShaders || OK || OK || X || X || X<br />
|-<br />
! DefVSConst1 || OK || OK || || ||<br />
|-<br />
! DefPSConst1 || OK || OK || || ||<br />
|-<br />
! UseEndScene || OK || OK || OK || OK || OK<br />
|-<br />
! DefPSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! DefVSSampler || OK || OK || OK || OK || OK<br />
|-<br />
! bCalcTexCRCatStart || OK || OK || OK || X || X<br />
|-<br />
! PresetsKeysList || OK || OK || || ||<br />
|-<br />
! Preset1Key || X || X || || OK || OK<br />
|-<br />
! DefPSViewSizeConst || OK || || || ||<br />
|-<br />
! DefSquareSurfaceMode || OK || || || ||<br />
|-<br />
! DefDepthStencilSurfaceMode || || || || ||<br />
|-<br />
! DefSurfaceCreationMode || OK || || || ||<br />
|-<br />
! SkipSetScissorRect || OK || || || ||<br />
|-<br />
! DefRtCreationMode || OK || || || ||<br />
|-<br />
! RtCreationModeList || || || || ||<br />
|-<br />
! SurfaceCreationModeList || OK || || || ||<br />
|-<br />
! OverrideMethod || OK || || || ||<br />
|-<br />
! UseAlternateCRC || || || || ||<br />
|-<br />
! DefModuleName || || || || ||<br />
|-<br />
! InitMouse || || || || ||<br />
|-<br />
! ProxyLib || || || || ||<br />
|-<br />
! GetCurDirAtLoad || || || || ||<br />
|-<br />
! UseExtInterfaceOnly || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[Preset1] <br />
|-<br />
! Convergence || X || X || X || OK || OK<br />
|- <br />
! Separation || X || X || X || OK || OK<br />
|-<br />
! UseSepSettings || X || X || X || OK || OK<br />
|-<br />
!colspan="6" style="text-align:left;"|[KEY*] <br />
|-<br />
! Key || OK || OK || || || <br />
|-<br />
! Presets || OK || OK || || || <br />
|-<br />
! Type || OK || OK || || ||<br />
|-<br />
! Delay || OK || OK || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PRES*] <br />
|-<br />
! Const1 || OK || OK || || ||<br />
|-<br />
! UseByDef || OK || || || ||<br />
|-<br />
! Convergence || OK || || || ||<br />
|- <br />
! Separation || OK || || || ||<br />
|-<br />
! UseSepSettings || OK || || || ||<br />
|-<br />
! SaveSepSettings || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VSnnnnnnnn] <br />
|-<br />
! CheckTexCRC || OK || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
! ValForDefined || OK || || || ||<br />
|-<br />
! ValNotDefined || OK || || || ||<br />
|-<br />
! TexCounterReg || OK || || || ||<br />
|-<br />
! UseDefinedOnly || OK || || || ||<br />
|-<br />
! DefinedTexturesVS || OK || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! SetConst1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
! ResetConst1AfterSet || || || || ||<br />
|-<br />
! DefStage || || || || ||<br />
|-<br />
! FirstVertexPosReg || || || || ||<br />
|-<br />
! GetVertex || || || || ||<br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! MousePosReg || OK || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[VBnnnnnnnn.m] <br />
|-<br />
! PointsList || || || || ||<br />
|-<br />
! Offset || || || || ||<br />
|-<br />
! IsDisabledList || || || || ||<br />
|-<br />
! StartResW || || || || ||<br />
|-<br />
! StartResH || || || || ||<br />
|-<br />
! EndResW || || || || ||<br />
|-<br />
! EndResH || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[TEXnnnnnnnn] <br />
|-<br />
! PresIndex || || || || ||<br />
|-<br />
! Index || || || || ||<br />
|-<br />
! VBOffsetList || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[PSnnnnnnnn] <br />
|-<br />
! UseMatrix || || || || ||<br />
|-<br />
! MatrixReg || || || || ||<br />
|-<br />
! GetMatrixFromReg || || || || ||<br />
|-<br />
! InverseMatrix || || || || ||<br />
|-<br />
! DoubleInverseMatrix || || || || ||<br />
|-<br />
! GetSampler1FromReg || || || || ||<br />
|-<br />
! SetSampler1ToReg || || || || ||<br />
|-<br />
! GetConst1FromReg || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[SFn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
!colspan="6" style="text-align:left;"|[RTn] <br />
|-<br />
! DefMode || || || || ||<br />
|-<br />
! Format || || || || ||<br />
|-<br />
! Usage || || || || ||<br />
|-<br />
! Height || || || || ||<br />
|-<br />
! Width || || || || ||<br />
|-<br />
! UseBackBufRes || || || || ||<br />
|-<br />
! Levels || || || || ||<br />
|-<br />
! Pool || || || || ||<br />
|-<br />
|}<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Talk:Lesson_2_-_disable_effectTalk:Lesson 2 - disable effect2014-11-26T19:53:29Z<p>Bo3b admin: </p>
<hr />
<div>== To discuss Lesson 2 - ''disable effect'', please use Add topic in the upper right. ==<br />
__TOC__ <br />
<br />
== Optimal way to disable an effect ==<br />
<br />
When making a real fix, it might be valuable to consider other factors beyond just the easist way to do it, particularly because in general we'll just copy/paste the code. Let's copy/paste code that works better in all cases.<br />
<br />
It's also worth noting that sometimes we need to set the output to all 1 instead, if a PS is used as part of a masking operation. It's rare, but happens.<br />
<br />
<br />
When we disable an effect using the simplest case, the original shader is still fully executed, but the results thrown away by our last instruction where we assign zero to the output. There's not point in wasting the GPU cycles on stuff that is unused, so we can make it slightly better by making it so that original code is not executed.<br />
<br />
Secondly, maybe you or others want to play the game in 2D. The effect is still disabled in 2D, even though it doesn't cause problems there. We can make it so that the disable operation only happens in 3D.<br />
<br />
<br />
<nowiki><br />
...<br />
// Texture2D_0 s0 1<br />
<br />
ps_3_0<br />
def c1, 0, 2, -0.333299994, 9.99999997e-007<br />
...<br />
dcl_texcoord2_pp v0.xyz<br />
...<br />
dcl_2d s0<br />
...<br />
texld r0, v4, s0<br />
add r1, r0.w, c1.z<br />
...<br />
</nowiki><br />
<br />
Would become:<br />
<br />
<nowiki><br />
...<br />
// Texture2D_0 s0 1<br />
<br />
ps_3_0<br />
def c1, 0, 2, -0.333299994, 9.99999997e-007<br />
def c200, 0, 0, 0.0625, 0<br />
...<br />
dcl_texcoord2_pp v0.xyz<br />
...<br />
dcl_2d s0<br />
...<br />
// Check if we are in 3D, and only disable effect if separation==0<br />
texldl r30, c200.z, s0<br />
if_ne r30.x, c200.x<br />
mov oC0.rgba, c200.wwww<br />
ret<br />
endif<br />
<br />
texld r0, v4, s0<br />
add r1, r0.w, c1.z<br />
...<br />
</nowiki><br />
<br />
<br />
''notes: Not positive this is actually optimal just yet. Need to revisit.''<br />
<br />
''We can switch to Shader Model 4.0, because DX10 video cards have been out for forever (starting with 8800 GTX), and we don't expect anyone to actually only be able to run SM3.0. Switching to SM4.0 allows us to use the ''discard'' instruction for simplicity. Consider switching to SM4, at the expense of not matching some other Helix info.''<br />
<br />
<br><br />
<br><br />
'''Similar variant for HLSL using 3Dmigoto:'''<br />
<br />
<nowiki><br />
...<br />
void main(<br />
float4 v0 : TEXCOORD0,<br />
float4 v1 : TEXCOORD1,<br />
out float4 o0 : SV_Target0)<br />
{<br />
...<br />
o0.xyz = HDR_EncodeScale.zzz * r0.xyz;<br />
o0.w = 1.000000000e+000;<br />
return;<br />
}</nowiki><br />
<br />
Becomes:<br />
<br />
<nowiki><br />
...<br />
void main(<br />
float4 v0 : TEXCOORD0,<br />
float4 v1 : TEXCOORD1,<br />
out float4 o0 : SV_Target0)<br />
{<br />
...<br />
o0.xyz = HDR_EncodeScale.zzz * r0.xyz;<br />
o0.w = 1.000000000e+000;<br />
<br />
// Disable the effect<br />
o0 = 0;<br />
return;<br />
}</nowiki><br />
<br />
== Trying to understand the 'code'. ==<br />
<br />
Hello!<br />
<br />
Just got round to looking at the lesson. I love learning!<br />
<br />
You tube: 18:46 to 19.28.<br />
<br />
I think I get the second part of the move thing (c1.wwww) but not the first bit, oC0.xyzw. The register? Where did this come from? Have I even asked the question correctly?<br />
<br />
The reason I am asking is can I just plonk that line in another game's shader etc?<br />
<br />
Thanks!<br />
<br />
AndysonofBob<br />
<br />
=== Late answer here ===<br />
The output register in ASM is the oC0 register, and it will always be oC0 for pixel shaders, as that is how it's defined for the hardware. <br />
<br />
There can sometimes be more than one, but there will always be at oC0.<br />
<br />
''[http://msdn.microsoft.com/en-us/library/windows/desktop/bb219871%28v=vs.85%29.aspx definition of oC0]''</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Game_Fixing_StrategyGame Fixing Strategy2014-10-07T15:42:16Z<p>Bo3b admin: Protected "Game Fixing Strategy" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</p>
<hr />
<div>The idea is to save as much of your time as possible.<br />
<br />
Fixing can be very time consuming, and often frustrating, so even once you are expert, it will still be worth tackling a game in a strategic fashion.<br />
<br />
These are sorted in order of quickest to hardest.<br />
<br />
<br />
# Change in-game settings.<br />
# Change configuration file options.<br />
# Try different profiles. ''[http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html Guide for changing profiles.]''<br />
# Disable key effects. ''[[Lesson 2 - disable effect]]''<br />
# Disable all broken effects. ''[[Lesson 4 - game fix]]''<br />
# Fix easy or known effects.<br />
# Fix hard effects.<br />
<br />
<br />
At any time when the game is playable, share it! We've lost any number of game fixes because people weren't quite satisfied, then never got back to it. Remember, you can always update it, or hand it over to someone else.<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Canonical_Stereo_CodeCanonical Stereo Code2014-10-07T15:42:02Z<p>Bo3b admin: Protected "Canonical Stereo Code" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</p>
<hr />
<div>This is the ''prime directive'' code in ASM for DX9 and HelixMod. And the HLSL version for 3Dmigoto. In all cases, we are implementing the NVidia specified formula of: <br><br><br />
<code>clipPos.x += EyeSign * Separation * ( clipPos.w – Convergence )</code><br />
<br />
<br />
This is the wordy version with extra comments to make it more clear what is happening.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// The required constant for txldl in c200.z<br />
def c200, 1.0, 600, 0.0625, 0<br />
// Sampler used to fetch stereo params, <br />
// s0 sampler is default for VS<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
// Fetch the Separation (r30.x) and Convergence (r30.y) <br />
// using the Helix NVapi trick<br />
texldl r30, c200.z, s0<br />
<br />
// (W - Convergence)<br />
add r30.w, r0.w, -r30.y<br />
<br />
// multiply that times Separation for:<br />
// Separation * (W - Convergence)<br />
mul r30.z, r30.x, r30.w<br />
<br />
// Add that to Xold for the complete:<br />
// Xold + Separation * (W - Convergence)<br />
add r0.x, r0.x, r30.z<br />
<br />
</syntaxhighlight><br />
<br />
<br />
Another variant that is more concise, but less clear. As you get more accustomed to seeing this sequence of code, or are sharing with an expert crowd, it's less necessary to fully document this part, as it is always the same sequence and easy to recognize because of the texldl of 0.0625.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
<br />
// To create stereo effects, we need to calculate:<br />
// Xnew = Xold + Separation * (W - Convergence)<br />
<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mad r0.x, r30.x, r30.w, r0.x<br />
</syntaxhighlight><br />
<br />
<br />
Another very common variant you'll see in HelixMod fixes is the four line version, with no comments. This is less optimal than the two above, but is worth seeing to be able to recognize it.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// Stereo correction constants<br />
def c200, 1.0, 600, 0.0625, 0<br />
dcl_2d s0<br />
...<br />
<br />
// At this point r0 is the output position, correctly<br />
// placed, but without stereo.<br />
texldl r30, c200.z, s0<br />
add r30.w, r0.w, -r30.y<br />
mul r30.z, r30.x, r30.w<br />
add r0.x, r0.x, r30.z<br />
</syntaxhighlight><br />
<br />
<br />
The HLSL version is very similar, but since it's a compile language there is no need to be terse when writing the code. We can make it "self-documenting" by using good variable names.<br />
<br />
<syntaxhighlight lang="c"><br />
...<br />
// .Load should only be done once, but can be done anywhere in the code.<br />
<br />
float4 stereo = StereoParams.Load(0);<br />
float separation = stereo.x; float convergence = stereo.y;<br />
<br />
// At this point, "location" is the output position, but missing stereo.<br />
<br />
location.x += separation * (location.w - convergence);<br />
</syntaxhighlight></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Default_DX9Settings.iniDefault DX9Settings.ini2014-10-07T15:41:46Z<p>Bo3b admin: Protected "Default DX9Settings.ini" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</p>
<hr />
<div> <nowiki><br />
[General]<br />
<br />
// UseRenderedShaders=true is nearly always useful, because it trims the <br />
// list of shaders seen while hunting down to just those active in the <br />
// current scene. Disable this only if you get crashes during hunting.<br />
UseRenderedShaders=true<br />
<br />
// DumpAll will generate ASM text files for every shader seen by the game.<br />
// This is usually worth doing once, but not useful for every run.<br />
DumpAll=false<br />
<br />
// Constant registers that will arrive in Vertex and Pixel Shaders, as<br />
// c220. The constants below will be assigned, based on the key preset.<br />
DefVSConst1 = 220 <br />
DefPSConst1 = 220<br />
<br />
// The PresetKeysList specifies which KEYs will be used.<br />
// Multiple keys lists are supported.<br />
PresetsKeysList = 1;<br />
<br />
// For this single key example, we only need one keylist, KEY1. This specifies<br />
// that the Numpad 0 keyboard key (Key=96) should act as a toggle. And toggle<br />
// between the two Presets of PRES1, PRES2. Which will change the Const1 being <br />
// passed to the shader code from 1.0 to 0.0 as floating point numbers.<br />
// Type=1 is toggle, Type=2 is momentary.<br />
[KEY1]<br />
Key = 96<br />
Presets = 1;2;<br />
Type = 1<br />
<br />
// Constants that will be sent to every shader through constant register c220.<br />
// The Const1 tells us that we'll need to use c220.x to compare against these<br />
// values. Const2 would be seen as c220.y.<br />
// 0x3f800000 is 1.0 in floating point hex, 0x00000000 is 0.0 in hex<br />
// UseByDef specifies which constant is the default starting value.<br />
[PRES1]<br />
Const1 = 0x3f800000<br />
[PRES2]<br />
UseByDef=True<br />
Const1 = 0x00000000<br />
</nowiki><br />
<br />
<br />
To use these constants in the shader add code like:<br />
<br />
<nowiki><br />
//def c220, Const1, Const2, Const3, Const4<br />
def c200, 0, 1, 0.0625, 0 // x=0 for comparison to Const1<br />
<br />
// if Const1 = 0 disable effect, else leave it on<br />
mov r30.x, c220.x<br />
if_eq r30.x, c200.x<br />
mov oC0.xyzw, c200.wwww<br />
endif<br />
<br />
// enable/disable in one if block<br />
mov r30.x, c220.x<br />
if_eq r30.x, c200.x<br />
mov r30, c200.wwww // disable<br />
else<br />
mov r30, v0 // enable<br />
endif<br />
</nowiki><br />
<br />
----<br />
'''References''':<br />
<br />
Microsoft virtual keycodes for ''Key='' use. Especially helpful for those odd keys like Insert, or Pause or F-Keys or Numpad. Must be converted from Hexadecimal to Decimal. [http://msdn.microsoft.com/en-us/library/ms927178.aspx keycodes]<br />
<br />
ASCII table for normal keyboard keys. Use the Dec column. [http://www.asciitable.com/ ASCII]<br />
<br />
Floating point to Hex converter, to make floating point hex constants. At shader runtime, constants are always float. [http://gregstoll.dyndns.org/~gregstoll/floattohex/ FloatToHex]</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=List_of_glitchesList of glitches2014-10-07T15:41:10Z<p>Bo3b admin: Protected "List of glitches" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</p>
<hr />
<div>This is intended to be a comprehensive list of visual glitches seen in games, as a way of categorizing them and having an example of each.<br />
<br />
* HUD at screen depth<br />
* Nameplates at screen depth<br />
* Crosshair at screen depth<br />
* Skybox too close<br />
<br />
* Lights at screen depth<br />
* Bloom at wrong depth<br />
<br />
* Character halos<br />
* Shadows at screen depth<br />
* Shadows doubled</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Levels_of_FixingLevels of Fixing2014-10-07T15:40:49Z<p>Bo3b admin: Protected "Levels of Fixing" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</p>
<hr />
<div>==== Beginner 0 - ''change profiles'' ====<br />
As a very first step in fixing games, it is often worth trying different profiles, because sometimes you can fix a game by simply putting it on a better profile. A good example is Defense Grid, where simply switching profiles makes it flawless.<br />
<br />
==== Beginner 1 - ''remove effects'' ====<br />
The very first fixes are simply to remove broken shader effects. <br />
<br />
Maybe we can't describe these as actual 'fixes', but if we can take a game from being unplayable to playable, that would seem to qualify as a 'Fix'.<br />
<br />
Anyone can learn how to disable shader effects. If you can edit a .ini file, you can remove effects.<br />
<br />
You will need to get familiar with the basic assembly shader structure, but that is all. ''Structure'' are the pieces that define variables, including the key input and output variables.<br />
<br />
==== Beginner 2 - ''move to depth'' ====<br />
The next level of fix is to move an effect to the right depth. <br />
<br />
A skybox might appear annoyingly close in 3D, and we can move it to infinity where it belongs.<br />
<br />
<br />
[[File:Psychonauts03_85_-_Copy.jpg|700px|center|broken]]<br />
[[File:Psychonauts04_85_-_Copy.jpg|700px|center|fixed]]<br />
<br />
<br />
==== Intermediate 1 - ''separate textures'' ====<br />
Separating textures is necessary when a specific shaders is being used for multiple parts of the image. <br />
<br />
For example, the HUD and the Crosshair might both be drawn by the same shader. To move the Crosshair to depth, without impacting the HUD is where we would separate textures.<br />
<br />
You will need to understand what textures are, and how textures are applied to the wire-frame models. Also how to use HelixMod to find textures and specify their use on specific shaders. <br />
<br />
==== Intermediate 2 - ''stereo-correction'' ====<br />
At this level, we want to actually correct a position in 3D space.<br />
<br />
An example would be moving player nameplates from screen depth to a better object depth. Or fixing halos around characters.<br />
<br />
You will need to understand how vertex shaders and pixel shaders make up the graphics pipeline, and why vertex shaders usually are the spot for deciding depth. You will also need to understand the stereo prime directive, which is the simple math behind what changes perceived depth.<br />
<br />
==== Advanced - ''deferred-rendering'' ====<br />
This level generally fixes effects in PixelShaders, where the developer is using the deferred-rendering technique. <br />
<br />
Examples are some lighting effects, and often shadows.<br />
<br />
You will need to understand how objects are stereoized in the first place, and how the graphics pipeline works for deferred-rendering. You will need to be able to roughly understand shader language to determine if deferred-rendering is being used. And then apply several common techniques to fix the depth.<br />
<br />
----<br />
<br />
<nowiki><br />
Beginner fixes do not require shader knowledge, or DX9 knowledge. You just need to learn "what to do". <br />
Studying other peoples fixes will help you absorb it pretty quickly, and bo3bs references above have loads of stuff. These beginner fixes are NOT using "full stereo correction", but more are 'moving things to fixed locations/depths' etc.<br />
1. Read the stuff on what the helixmod dll is, the difference between the debug and the releae<br />
2. Learn how to disable problematic shaders. This will crystalize your understanding of the basics of using the helixmod wrapper, stepping through shaders, editing them etc.<br />
3. Find a game (even if it's already been fixed!) that has a skybox at the wrong depth. Fix it using the instructions in the original Helix guides.<br />
4. Similarly, find a game with a 2D hud. Practice moving the hud elements to different depths.<br />
** When you can do the above 3 things, you will actually be in a great position to start creating fixes that make games playable. This is not insignificant!<br />
<br />
5. Next step would be spending a bit more time looking at how you "separate textures" - this is really useful for HUD fixes, so you can move some parts of the hud and not others. It's also essential for some games where fixing one part of the game (e.g. moving a HUD element to depth) also affects some entirely unrelated part of the game (objects in the world).<br />
** With the above, you can now do some fancy stuff :-)<br />
<br />
== Intermediate 2 ==<br />
Intermediate fixes start to require some knowledge of what is going on in the vertex shaders, and they start to use "full stereo correction" i.e. the actual formula that Nvidia uses to inject stereo in the drivers. Only Vertex shaders are involved.<br />
6. Haloing: A lot of the really nasty looking issues in games are caused when things "halo" or "double/triple image". There is an absolute (almost universal) reason for, pattern to fixing, all of these issues. I will state it here for when you are ready to tray this out. In a VS the "output position" variable is calculated from a View Projection transformation (you need to read about what that is), and this is what defines the coordinates of objects in the scene - the nvidia drivers specifically stereoizes these output variables. However, what often happens in games is that a temporary variable is used for the result of the VPM transform, and then used to set the output position variable. The problem comes when this same temporary position variable is additionally output to other "texcoords" that get used in later Pixel Shaders. These texcoords do not get stereoized by the Nvidia driver, and so in the pixel shaders they are the wrong coordinates. The fix is to manually stereoize the temp position variable before outputting to the texcoord. There are loads of example fixes for this<br />
7. Water: Many (but not all) water effects are vertex shader issues, and this is where you would start looking for a solution. Main issues are haloing and reflections. Both of these are often fixed the same way as above in point 6.<br />
<br />
== Advanced ==<br />
These fixes require Pixel Shader correction. They require you to understand much better the graphics rendering stages, the coordinate systems, and the transformations between them, including what the stereo correction is doing - this background is actually the most important part. You still do *not* need to know much about shader programming, though it will start to help a teeny bit to understand how to apply matrix transforms. I am not going to go into detail right now, but there are a few levels at which PS correction is relevant:<br />
- Accepting a newly defined replacement variable from a parent VS and using that (e.g. a stereoized version of some texcoord that is needed in only one part of the PS, but not everwhere)<br />
- What is called "texture coordinate" corrections to offset where sample maps are sampled (often a texture coordinate needs to be "built' form something call vPos)<br />
- Direct correction of projection space coordinates (easiest) <br />
- Indirect correction of world space coordinates for deferred rendered shaders (hardest)</nowiki><br />
<br />
<br />
<span style="font-size:95%">Big thanks to Mike_ar69 for providing the initial text layout.</span><br />
<br />
<br><br />
----<br />
<br />
Consult the [//meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.<br />
<br />
Wiki Getting started <br />
* [//www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]<br />
* [//www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]<br />
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]<br />
* [//www.mediawiki.org/wiki/Localisation#Translation_resources Localise MediaWiki for your language]</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_7_-_set_depthLesson 7 - set depth2014-10-05T08:19:20Z<p>Bo3b admin: </p>
<hr />
<div>==== Summary ====<br />
Learning how to move on-screen items to a different visual depth. <br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 25 minutes<br />
<br><br />
<br><br />
[http://youtu.be/yznX9IBip9o <u>Video Walkthrough on YouTube</u>]<br><br />
[http://sg.bo3b.net/Lesson%202%20-%20disable%20effect.mp4 <u>Video Walkthrough direct download link</u>]<br />
<br><br />
<br><br />
<br />
<br />
==== Objective ====<br />
Revisit how the illusion of depth is created. <br><br />
Move the HUD to a different depth, from screen depth. <br><br />
<br />
==== Quiz====<br />
...<br />
<br><br />
<br><br />
<br />
----<br />
We are going to switch gears now, because we have covered all the basics, and now understand how all the pieces work together. From here the Lessons will revolve around specific techniques or problems seen in games.<br />
<br />
This will be the first, and easiest, of those specific fixes. We are going to look at how to move items on screen to a specific depth of our choosing. This is useful for moving the HUD to a better depth, either further into the screen or even to pop-out if desired. This can also be good for moving nameplates deeper than screen depth, moving the skybox out to infinity where it belongs, or pushing the crosshair deeper than screen depth.<br />
<br />
This technique won't fix the depth specifically, but it can still help to have things closer to where they belong, even if it's not at exactly the right spot.<br />
<br />
<br />
----<br />
Talk about depth, and parallax, and why it's +- x.<br />
<br />
<br />
* Shader hunting a specific effect<br />
*# Run The Ball, in 3D with HelixMod installed.<br />
<br />
<br><br />
<br />
----<br />
Move the HUD out of the screen.<br />
<br />
<br />
* Finding the shader, then moving it into ''ShaderOverride''<br />
*# Navigate to The Ball's game directory with our shortcut.<br />
<br />
Busted. Show can't find hud in ball.<br />
<br />
Switch to Cryis. <br />
Show busted look, then fix by config.<br />
<br><br />
<br />
----</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_0.5_-_quick_fixLesson 0.5 - quick fix2014-10-04T03:33:31Z<p>Bo3b admin: </p>
<hr />
<div>==== Summary ====<br />
Look for easy ways to fix effects, only do the hard stuff if you need to.<br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 20 minutes<br />
<br><br />
<br><br />
This lesson does not have a video walkthrough, as the techniques are simple and well understood.<br />
<br />
<br />
==== Objective ====<br />
Learn three alternate techniques for fixing stereo glitches, that don't require HelixMod.<br />
<br><br />
Adopt a fixing strategy to optimize your game-fixing time.<br />
<br />
==== Quiz====<br />
Find and enable the Unreal engine flag to fix 3D in The Ball.<br />
<br><br />
<br><br />
<br />
----<br />
Although it's incredibly rewarding, keep in mind that fixing games with HelixMod can also sometimes be tedious and time-consuming. Thus it's worth trying easy techniques first, as they can save significant time that can be spent on harder or more interesting problems.<br />
<br />
<br />
There are three techniques that are nearly always worth trying first.<br />
<br />
<br />
* Change ''in-game'' settings to disable or improve the 3D.<br />
:: Like we found early on, the dynamic shadows around the ball are broken in 3D, and the quickest technique by far is to simply bring up Setttings and disable shadows. For The Ball, this is a perfectly acceptable fix, because losing the shadows barely impacts the visuals, and actually fixing shadows is one of the very hardest, and hence time-consuming techniques.<br />
:: Always play with the in-game settings first to get a feel for what might be easy fixes. Remember, you can always come back to improve it later.<br />
<br />
* Change ''configuration file'' settings to disable or improve the 3D. <br />
:: For Unreal Engine 3 games, it is likely that setting the ''AllowNvidiaStereo3d=True'' can dramatically improve the game in 3D. As seen in shaders in The Ball, there is code specifically activated when the flag is enabled.<br />
:: Depending upon the engine, there may be a wealth of parameters you can set to disable broken effects. Do Google searches for other similar games, or look for tweakguides like [http://www.tweakguides.com/UT3_1.html Unreal 3] or [http://www.tweakguides.com/HL2_1.html Valve Source Engine].<br />
<br />
* Switch NVidia profiles for fixes.<br />
:: Sometimes it is possible to dramatically improve a game by switching to other profiles. NVidia seems to have trouble keeping the profiles correct. If a different profile can fix even some of the effects, those will be fewer shaders to disable or fix. Take a look at the [http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html guide to changing profiles.]<br />
<br />
<br />
----<br />
With those quick-fix techniques in mind, let's take a look at a possible fixing strategy that can optimize your time.<br />
<br />
There are no hard and fast rules for fixing games, since there are so many varieties of problems and that inescapable conflict between disabling effects for quick results, and fixing effects for the best quality. This strategy is optimized to save you time, not necessarily give you the best results. <br />
<br />
However, with a game that is fully playable, you can always come back later and improve the fix.<br />
<br />
<br />
* Consider a possible [[Game Fixing Strategy]]<br />
<br />
<br />
----<br />
* Quiz: Find and enable the flag for Unreal engine games that automatically fixes 3D problems.<br />
*# Find the UDKEngine.ini file for the game.<br />
*# Change the setting to '''AllowNvidiaStereo3d=True'''<br />
*# Run the game, and look for the fog and lava effects to be fixed.<br />
*# Note that the heinous bloom effect is not fixed, but can also be disabled with '''Bloom=False'''<br />
*# Save a screen shot, using only these techniques.<br />
<br />
<br />
In the case of The Ball, you will find that these techniques go a very long ways, but can't resolve the problem with water in the final round. The Unreal flag is very useful, but can't always fix everything.<br />
<br />
You will probably also note that while enabling the flag fixes a lot of effects, it also hammers the performance to an unacceptable level. This is rarely the case with Unreal games, but for The Ball, it's not really a viable fix.<br />
<br />
<br />
As a real world example of using these techniques, look at the Crysis fix on the Helix blog: [http://helixmod.blogspot.com/2014/10/crysis-dx9.html Crysis fix]<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_6_-_prime_directiveLesson 6 - prime directive2014-10-03T08:18:01Z<p>Bo3b admin: Protected "Lesson 6 - prime directive" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</p>
<hr />
<div>==== Summary ====<br />
Now it's time to talk about how stereo 3D is created, and the math behind it.<br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 30 minutes<br />
<br><br />
<br><br />
[http://youtu.be/FwaakXn13pI <u>Video Walkthrough on YouTube</u>] ... <br />
[http://sg.bo3b.net/Lesson%206%20-%20prime%20directive.mp4 <u>Video Walkthrough direct download link</u>]<br />
<br><br />
<br><br />
<br />
==== Objective ====<br />
Review and understand the principles behind stereoscopy. <br />
<br><br />
Learn about the prime directive formula, and how to apply it.<br />
<br />
==== Quiz====<br />
Fix the oil shader in mid-game lava room.<br />
<br />
<br />
----<br />
For effects that are important for game play, the best solution is of course to fix them, not disable them. We can fix a surprisingly large number of broken effects with different techniques that we will learn in future Lessons.<br />
<br />
Let's start by fixing an easy one in The Ball, where there is already stereo fix code to guide us. This is the Lava effect. This will be our first actual fix, as opposed to disabling them.<br />
<br />
As a general idea, we probably would not fix this effect, because the version with one layer disabled is perfectly acceptable. It's always worth keeping an eye on how much time a given effect is worth, because there are always more games.<br />
<br />
<br />
----<br />
We'll step back into The Ball for a minute to get a first glimpse of the 3D formula I'm calling the ''prime directive''&sup1;.<br />
<br />
Let's not worry about the details yet, just see how it's applied.<br />
<br />
<br />
* Fix Lava effect, not just disable it.<br />
*# Lava in The Ball is perfectly usable now, but we noticed the Unreal fix earlier.<br />
*# Unreal fix did not function, but we can make it work, using HelixMod inputs.<br />
*# Edit shader file to use HelixMod stereo texture, instead of game based one.<br />
*# Fixed in 3D, not just disabling a piece of it.<br />
<br />
<br />
----<br />
The best background for how 3D works is a presentation from NVidia for GTC2010.<br />
<br />
[http://www.nvidia.com/content/GTC-2010/pdfs/2010_GTC2010.pdf http://www.nvidia.com/content/GTC-2010/pdfs/2010_GTC2010.pdf]<br />
<br />
<br />
* Take a look at how 3D Vision works, so that we all use NVidia's terminology.<br />
*# Starts with the basics of two offset images.<br />
*# How to think about shader rendering, including coordinate space.<br />
*# What is stereo projection, separation, convergence.<br />
*# Max separation.<br />
<br />
<br />
It's worth reading the rest of this paper for other good tidbits, like why convergence is locked under 'advanced.'<br />
<br />
<br />
* Looking at the prime directive.<br />
*# Slide 49.<br />
*# Eyesign is automatically applied by driver.<br />
<br />
<br />
[[File:Prime_directive.JPG|200px|center]]<br />
<br />
The ''prime directive'' from that slide: <br><br />
<code><br />
<br />
clipPos.x += EyeSign * Separation * ( clipPos.w – Convergence )<br />
<br />
</code><br />
<br />
<br />
* How does this translate to code: [[Canonical_Stereo_Code]]<br />
<br />
<br />
----<br />
With that background, let's go back to the Lava, but fix it from the VertexShader this time. <br />
<br />
In general, we can fix effects from either the VertexShader or the PixelShader, because the output of one is the input of the other. Given a choice, we'd rather fix location problems like skybox or HUD in the VertexShader. If we are going to disable an effect, it's better to use the PixelShader. And some complicated effects like shadows can generally only be fixed in PixelShaders.<br />
<br />
<br />
* Fix Lava effect using the prime directive.<br />
*# Run TheBall, and load up a Lava level.<br />
*# Shader hunt for the VertexShader this time. Note the non-obvious shader makes it all dark.<br />
*# Exit out and move the found shader to ShaderOverride.<br />
*# Edit the shader, and comment out the o3 to find the problem texture.<br />
*# Edit the shader, and add our stereo correction to o3.<br />
<br />
<br />
----<br />
<br />
Quiz: In the middle of the demo, fix the broken oil effect using the prime directive.<br />
<br />
* Fix the oil effect in the lava and bomb room.<br />
*# Play through to the lava room, it's shortly after first lava.<br />
*# See the oil has annoying double-imaging like the lava and fog did.<br />
*# Find a way to apply a stereo correction, it's similar to lava.<br />
*# Save a screenshot to your personal page.<br />
<br />
<br />
<br><br />
<br />
&sup1;''prime directive'' is not used by NVidia, I just made that up because it's more fun than ''stereo correction''.</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_0.5_-_quick_fixLesson 0.5 - quick fix2014-10-03T08:17:41Z<p>Bo3b admin: Protected "Lesson 0.5 - quick fix" ([Edit=Allow only administrators] (indefinite) [Move=Allow only administrators] (indefinite))</p>
<hr />
<div>==== Summary ====<br />
Look for easy ways to fix effects, only do the hard stuff if you need to.<br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 20 minutes<br />
<br><br />
<br><br />
This lesson does not have a video walkthrough, as the techniques are simple and well understood.<br />
<br />
<br />
==== Objective ====<br />
Learn three alternate techniques for fixing stereo glitches, that don't require HelixMod.<br />
<br><br />
Adopt a fixing strategy to optimize your game-fixing time.<br />
<br />
==== Quiz====<br />
Find and enable the Unreal engine flag to fix 3D in The Ball.<br />
<br><br />
<br><br />
<br />
----<br />
Although it's incredibly rewarding, keep in mind that fixing games with HelixMod can also sometimes be tedious and time-consuming. Thus it's worth trying easy techniques first, as they can save significant time that can be spent on harder or more interesting problems.<br />
<br />
<br />
There are three techniques that are nearly always worth trying first.<br />
<br />
<br />
* Change ''in-game'' settings to disable or improve the 3D.<br />
:: Like we found early on, the dynamic shadows around the ball are broken in 3D, and the quickest technique by far is to simply bring up Setttings and disable shadows. For The Ball, this is a perfectly acceptable fix, because losing the shadows barely impacts the visuals, and actually fixing shadows is one of the very hardest, and hence time-consuming techniques.<br />
:: Always play with the in-game settings first to get a feel for what might be easy fixes. Remember, you can always come back to improve it later.<br />
<br />
* Change ''configuration file'' settings to disable or improve the 3D. <br />
:: For Unreal Engine 3 games, it is likely that setting the ''AllowNvidiaStereo3d=True'' can dramatically improve the game in 3D. As seen in shaders in The Ball, there is code specifically activated when the flag is enabled.<br />
:: Depending upon the engine, there may be a wealth of parameters you can set to disable broken effects. Do Google searches for other similar games, or look for tweakguides like [http://www.tweakguides.com/UT3_1.html Unreal 3] or [http://www.tweakguides.com/HL2_1.html Valve Source Engine].<br />
<br />
* Switch NVidia profiles for fixes.<br />
:: Sometimes it is possible to dramatically improve a game by switching to other profiles. NVidia seems to have trouble keeping the profiles correct. If a different profile can fix even some of the effects, those will be fewer shaders to disable or fix. Take a look at the [http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html guide to changing profiles.]<br />
<br />
<br />
----<br />
With those quick-fix techniques in mind, let's take a look at a possible fixing strategy that can optimize your time.<br />
<br />
There are no hard and fast rules for fixing games, since there are so many varieties of problems and that inescapable conflict between disabling effects for quick results, and fixing effects for the best quality. This strategy is optimized to save you time, not necessarily give you the best results. <br />
<br />
However, with a game that is fully playable, you can always come back later and improve the fix.<br />
<br />
<br />
* Consider a possible [[Game Fixing Strategy]]<br />
<br />
<br />
----<br />
* Quiz: Find and enable the flag for Unreal engine games that automatically fixes 3D problems.<br />
*# Find the UDKEngine.ini file for the game.<br />
*# Change the setting to '''AllowNvidiaStereo3d=True'''<br />
*# Run the game, and look for the fog and lava effects to be fixed.<br />
*# Note that the heinous bloom effect is not fixed, but can also be disabled with '''Bloom=False'''<br />
*# Save a screen shot, using only these techniques.<br />
<br />
<br />
In the case of The Ball, you will find that these techniques go a very long ways, but can't resolve the problem with water in the final round. The Unreal flag is very useful, but can't always fix everything.<br />
<br />
You will probably also note that while enabling the flag fixes a lot of effects, it also hammers the performance to an unacceptable level. This is rarely the case with Unreal games, but for The Ball, it's not really a viable fix.<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_0.5_-_quick_fixLesson 0.5 - quick fix2014-10-02T10:04:10Z<p>Bo3b admin: </p>
<hr />
<div>==== Summary ====<br />
Look for easy ways to fix effects, only do the hard stuff if you need to.<br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 20 minutes<br />
<br><br />
<br><br />
This lesson does not have a video walkthrough, as the techniques are simple and well understood.<br />
<br />
<br />
==== Objective ====<br />
Learn three alternate techniques for fixing stereo glitches, that don't require HelixMod.<br />
<br><br />
Adopt a fixing strategy to optimize your game-fixing time.<br />
<br />
==== Quiz====<br />
Find and enable the Unreal engine flag to fix 3D in The Ball.<br />
<br><br />
<br><br />
<br />
----<br />
Although it's incredibly rewarding, keep in mind that fixing games with HelixMod can also sometimes be tedious and time-consuming. Thus it's worth trying easy techniques first, as they can save significant time that can be spent on harder or more interesting problems.<br />
<br />
<br />
There are three techniques that are nearly always worth trying first.<br />
<br />
<br />
* Change ''in-game'' settings to disable or improve the 3D.<br />
:: Like we found early on, the dynamic shadows around the ball are broken in 3D, and the quickest technique by far is to simply bring up Setttings and disable shadows. For The Ball, this is a perfectly acceptable fix, because losing the shadows barely impacts the visuals, and actually fixing shadows is one of the very hardest, and hence time-consuming techniques.<br />
:: Always play with the in-game settings first to get a feel for what might be easy fixes. Remember, you can always come back to improve it later.<br />
<br />
* Change ''configuration file'' settings to disable or improve the 3D. <br />
:: For Unreal Engine 3 games, it is likely that setting the ''AllowNvidiaStereo3d=True'' can dramatically improve the game in 3D. As seen in shaders in The Ball, there is code specifically activated when the flag is enabled.<br />
:: Depending upon the engine, there may be a wealth of parameters you can set to disable broken effects. Do Google searches for other similar games, or look for tweakguides like [http://www.tweakguides.com/UT3_1.html Unreal 3] or [http://www.tweakguides.com/HL2_1.html Valve Source Engine].<br />
<br />
* Switch NVidia profiles for fixes.<br />
:: Sometimes it is possible to dramatically improve a game by switching to other profiles. NVidia seems to have trouble keeping the profiles correct. If a different profile can fix even some of the effects, those will be fewer shaders to disable or fix. Take a look at the [http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html guide to changing profiles.]<br />
<br />
<br />
----<br />
With those quick-fix techniques in mind, let's take a look at a possible fixing strategy that can optimize your time.<br />
<br />
There are no hard and fast rules for fixing games, since there are so many varieties of problems and that inescapable conflict between disabling effects for quick results, and fixing effects for the best quality. This strategy is optimized to save you time, not necessarily give you the best results. <br />
<br />
However, with a game that is fully playable, you can always come back later and improve the fix.<br />
<br />
<br />
* Consider a possible [[Game Fixing Strategy]]<br />
<br />
<br />
----<br />
* Quiz: Find and enable the flag for Unreal engine games that automatically fixes 3D problems.<br />
*# Find the UDKEngine.ini file for the game.<br />
*# Change the setting to '''AllowNvidiaStereo3d=True'''<br />
*# Run the game, and look for the fog and lava effects to be fixed.<br />
*# Note that the heinous bloom effect is not fixed, but can also be disabled with '''Bloom=False'''<br />
*# Save a screen shot, using only these techniques.<br />
<br />
<br />
In the case of The Ball, you will find that these techniques go a very long ways, but can't resolve the problem with water in the final round. The Unreal flag is very useful, but can't always fix everything.<br />
<br />
You will probably also note that while enabling the flag fixes a lot of effects, it also hammers the performance to an unacceptable level. This is rarely the case with Unreal games, but for The Ball, it's not really a viable fix.<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Bo3b%27s_School_for_ShaderhackersBo3b's School for Shaderhackers2014-10-02T10:02:00Z<p>Bo3b admin: </p>
<hr />
<div>__NOTOC__<br />
<br />
==== [[Lesson 0|Lesson 0 - ''prerequisites'']] ====<br />
:* Ensure user account is Admin<br />
:* Game setup and installation<br />
:* Text editor setup and installation<br />
:* HelixMod tool installation<br />
:* Create page on [http://wiki.bo3b.net wiki.bo3b.net]<br />
<br />
: Quiz: Save and share 3D image with red debug text<br />
<br />
<br />
==== [[Lesson_0.5_-_quick_fix|Lesson 0.5 - ''quick fix'']] ====<br />
:* Change in-game settings to disable or improve the 3D<br />
:* Change configuration file settings to disable or improve the 3D<br />
:* Switch NVidia profiles for fixes<br />
:* Consider a possible Game Fixing Strategy<br />
<br />
: Quiz: Find and enable the Unreal engine flag to fix 3D in The Ball<br />
<br />
<br />
==== [[Lesson 1|Lesson 1 - ''using HelixMod'']] ====<br />
:* Shader hunting keys<br />
:* Editing DX9Settings.ini<br />
:* Improved shader hunting<br />
:* Shader saving<br />
:* Save shader text file<br />
<br />
: Quiz: Save and share an ASM shader file from the game<br />
<br />
<br />
==== [[Lesson_2_-_disable_effect|Lesson 2 - ''disable effect'']] ====<br />
:* Shader hunting a specific effect<br />
:* Saving the shader, then moving it into ShaderOverride<br />
:* Editing shader to disable effect<br />
:* Load shader to see changes<br />
<br />
: Quiz: Save and upload before and after 3D snapshots<br />
<br />
<br />
==== [[Lesson_3_-_Const|Lesson 3 - ''Const'']] ====<br />
:* Create an on/off mechanism using HelixMod constants<br />
<br />
: Quiz: Modify the toggle code, then upload your changes.<br />
<br />
<br />
==== [[Lesson_4_-_game_fix|Lesson 4 - ''game fix'']] ====<br />
:* Creating a complete list of shaders<br />
:* Editing shaders to disable effects<br />
<br />
: Quiz: Make a second key preset to toggle bloom independently from other effects.<br />
<br />
<br />
==== [[Lesson_5_-_experimentation|Lesson 5 - ''experimentation'']] ====<br />
:* Pt 1: Play with the Principles of Shading demo.<br />
:* Pt 2: Experiment on lava shaders.<br />
<br />
: Quiz: Go to the end of the demo, and figure out a way to fix the broken water.<br />
<br />
<br />
==== [[Lesson_6_-_prime_directive|Lesson 6 - ''prime directive'']] ====<br />
:* Fix Lava effect, not just disable it.<br />
:* Take a look at how 3D Vision works, so that we all use NVidia's terminology.<br />
:* Looking at the prime directive.<br />
:* How does this translate to code: Canonical_Stereo_Code<br />
:* Fix Lava effect using the prime directive.<br />
<br />
: Quiz: In the middle of the demo, fix the broken oil effect using the prime directive.<br />
<br />
<br />
''More lessons to be added...''</div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_0.5_-_quick_fixLesson 0.5 - quick fix2014-10-02T10:01:50Z<p>Bo3b admin: </p>
<hr />
<div>==== Summary ====<br />
Look for easy ways to fix effects, only do the hard stuff if you need to.<br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 20 minutes<br />
<br><br />
<br><br />
This lesson does not have a video walkthrough, as the techniques are simple and well understood.<br />
<br />
<br />
==== Objective ====<br />
Learn three alternate techniques for fixing stereo glitches, that don't require HelixMod.<br />
<br><br />
Adopt a fixing strategy to optimize your game-fixing time.<br />
<br />
==== Quiz====<br />
Find and enable the Unreal engine flag to fix 3D in The Ball.<br />
<br><br />
<br><br />
<br />
----<br />
Although it's incredibly rewarding, keep in mind that fixing games with HelixMod can also sometimes be tedious and time-consuming. Thus it's worth trying easy techniques first, as they can save significant time that can be spent on harder or more interesting problems.<br />
<br />
<br />
There are three techniques that are nearly always worth trying first.<br />
<br />
<br />
* Change ''in-game'' settings to disable or improve the 3D.<br />
:: Like we found early on, the dynamic shadows around the ball are broken in 3D, and the quickest technique by far is to simply bring up Setttings and disable shadows. For The Ball, this is a perfectly acceptable fix, because losing the shadows barely impacts the visuals, and actually fixing shadows is one of the very hardest, and hence time-consuming techniques.<br />
:: Always play with the in-game settings first to get a feel for what might be easy fixes. Remember, you can always come back to improve it later.<br />
<br />
* Change ''configuration file'' settings to disable or improve the 3D. <br />
:: For Unreal Engine 3 games, it is likely that setting the ''AllowNvidiaStereo3d=True'' can dramatically improve the game in 3D. As seen in shaders in The Ball, there is code specifically activated when the flag is enabled.<br />
:: Depending upon the engine, there may be a wealth of parameters you can set to disable broken effects. Do Google searches for other similar games, or look for tweakguides like [http://www.tweakguides.com/UT3_1.html Unreal 3] or [http://www.tweakguides.com/HL2_1.html Valve Source Engine].<br />
<br />
* Switch NVidia profiles for fixes.<br />
:: Sometimes it is possible to dramatically improve a game by switching to other profiles. NVidia seems to have trouble keeping the profiles correct. If a different profile can fix even some of the effects, those will be fewer shaders to disable or fix. Take a look at the [http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html guide to changing profiles.]<br />
<br />
<br />
----<br />
With those quick-fix techniques in mind, let's take a look at a possible fixing strategy that can optimize your time.<br />
<br />
There are no hard and fast rules for fixing games, since there are so many varieties of problems and that inescapable conflict between disabling effects and fixing effects. This strategy is optimized to save you time, not necessarily give you the best results. <br />
<br />
However, with a game that is fully playable, you can always come back later and improve the fix.<br />
<br />
<br />
* Consider a possible [[Game Fixing Strategy]]<br />
<br />
<br />
----<br />
* Quiz: Find and enable the flag for Unreal engine games that automatically fixes 3D problems.<br />
*# Find the UDKEngine.ini file for the game.<br />
*# Change the setting to '''AllowNvidiaStereo3d=True'''<br />
*# Run the game, and look for the fog and lava effects to be fixed.<br />
*# Note that the heinous bloom effect is not fixed, but can also be disabled with '''Bloom=False'''<br />
*# Save a screen shot, using only these techniques.<br />
<br />
<br />
In the case of The Ball, you will find that these techniques go a very long ways, but can't resolve the problem with water in the final round. The Unreal flag is very useful, but can't always fix everything.<br />
<br />
You will probably also note that while enabling the flag fixes a lot of effects, it also hammers the performance to an unacceptable level. This is rarely the case with Unreal games, but for The Ball, it's not really a viable fix.<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_0.5_-_quick_fixLesson 0.5 - quick fix2014-10-02T09:55:27Z<p>Bo3b admin: Bo3b admin moved page Lesson 1.5 - quick fix to Lesson 0.5 - quick fix without leaving a redirect</p>
<hr />
<div>==== Summary ====<br />
Look for easy ways to fix effects, only do the hard stuff if you need to.<br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 20 minutes<br />
<br><br />
<br><br />
This lesson does not have a video walkthrough, as the techniques are simple and well understood.<br />
<br />
<br />
==== Objective ====<br />
Learn three alternate techniques for fixing stereo glitches, that don't require HelixMod.<br />
<br><br />
Adopt a fixing strategy to optimize your game-fixing time.<br />
<br />
==== Quiz====<br />
Find and enable the Unreal engine flag to fix 3D in The Ball.<br />
<br><br />
<br><br />
<br />
----<br />
Although it's incredibly rewarding, keep in mind that fixing games with HelixMod can also sometimes be tedious and time-consuming. Thus it's worth trying easy techniques first, as they can save significant time that can be spent on harder or more interesting problems.<br />
<br />
<br />
There are three techniques that are nearly always worth trying first.<br />
<br />
<br />
* Change ''in-game'' settings to disable or improve the 3D.<br />
:: Like we found early on, the dynamic shadows around the ball are broken in 3D, and the quickest technique by far is to simply bring up Setttings and disable shadows. For The Ball, this is a perfectly acceptable fix, because losing the shadows barely impacts the visuals, and actually fixing shadows is one of the very hardest, and hence time-consuming techniques.<br />
:: Always play with the in-game settings first to get a feel for what might be easy fixes. Remember, you can always come back to improve it later.<br />
<br />
* Change ''configuration file'' settings to disable or improve the 3D. <br />
:: For Unreal Engine 3 games, it is likely that setting the ''AllowNvidiaStereo3d=True'' can dramatically improve the game in 3D. As seen in shaders in The Ball, there is code specifically activated when the flag is enabled.<br />
:: Depending upon the engine, there may be a wealth of parameters you can set to disable broken effects. Do Google searches for other similar games, or look for tweakguides like [http://www.tweakguides.com/UT3_1.html Unreal 3] or [http://www.tweakguides.com/HL2_1.html Valve Source Engine].<br />
<br />
* Switch profiles for fixes.<br />
:: Sometimes it is possible to dramatically improve a game by switching to other profiles. NVidia seems to have trouble keeping the profiles correct. If a different profile can fix even some of the effects, those will be fewer shaders to disable or fix. Take a look at the [http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html guide to changing profiles.]<br />
<br />
<br />
----<br />
With those quick-fix techniques in mind, let's take a look at a possible fixing strategy that can optimize your time.<br />
<br />
There are no hard and fast rules for fixing games, since there are so many varieties of problems and that inescapable conflict between disabling effects and fixing effects. This strategy is optimized to save you time, not necessarily give you the best results. <br />
<br />
However, with a game that is fully playable, you can always come back later and improve the fix.<br />
<br />
<br />
Take a look at a possible [[Game Fixing Strategy]]<br />
<br />
<br />
----<br />
* Quiz: Find and enable the flag for Unreal engine games that automatically fixes 3D problems.<br />
*# Find the UDKEngine.ini file for the game.<br />
*# Change the setting to '''AllowNvidiaStereo3d=True'''<br />
*# Run the game, and look for the fog and lava effects to be fixed.<br />
*# Note that the heinous bloom effect is not fixed, but can also be disabled with '''Bloom=False'''<br />
*# Save a screen shot, using only these techniques.<br />
<br />
<br />
In the case of The Ball, you will find that these techniques go a very long ways, but can't resolve the problem with water in the final round. The Unreal flag is very useful, but can't always fix everything.<br />
<br />
You will probably also note that while enabling the flag fixes a lot of effects, it also hammers the performance to an unacceptable level. This is rarely the case with Unreal games, but for The Ball, it's not really a viable fix.<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_0.5_-_quick_fixLesson 0.5 - quick fix2014-10-02T09:54:12Z<p>Bo3b admin: </p>
<hr />
<div>==== Summary ====<br />
Look for easy ways to fix effects, only do the hard stuff if you need to.<br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 20 minutes<br />
<br><br />
<br><br />
This lesson does not have a video walkthrough, as the techniques are simple and well understood.<br />
<br />
<br />
==== Objective ====<br />
Learn three alternate techniques for fixing stereo glitches, that don't require HelixMod.<br />
<br><br />
Adopt a fixing strategy to optimize your game-fixing time.<br />
<br />
==== Quiz====<br />
Find and enable the Unreal engine flag to fix 3D in The Ball.<br />
<br><br />
<br><br />
<br />
----<br />
Although it's incredibly rewarding, keep in mind that fixing games with HelixMod can also sometimes be tedious and time-consuming. Thus it's worth trying easy techniques first, as they can save significant time that can be spent on harder or more interesting problems.<br />
<br />
<br />
There are three techniques that are nearly always worth trying first.<br />
<br />
<br />
* Change ''in-game'' settings to disable or improve the 3D.<br />
:: Like we found early on, the dynamic shadows around the ball are broken in 3D, and the quickest technique by far is to simply bring up Setttings and disable shadows. For The Ball, this is a perfectly acceptable fix, because losing the shadows barely impacts the visuals, and actually fixing shadows is one of the very hardest, and hence time-consuming techniques.<br />
:: Always play with the in-game settings first to get a feel for what might be easy fixes. Remember, you can always come back to improve it later.<br />
<br />
* Change ''configuration file'' settings to disable or improve the 3D. <br />
:: For Unreal Engine 3 games, it is likely that setting the ''AllowNvidiaStereo3d=True'' can dramatically improve the game in 3D. As seen in shaders in The Ball, there is code specifically activated when the flag is enabled.<br />
:: Depending upon the engine, there may be a wealth of parameters you can set to disable broken effects. Do Google searches for other similar games, or look for tweakguides like [http://www.tweakguides.com/UT3_1.html Unreal 3] or [http://www.tweakguides.com/HL2_1.html Valve Source Engine].<br />
<br />
* Switch profiles for fixes.<br />
:: Sometimes it is possible to dramatically improve a game by switching to other profiles. NVidia seems to have trouble keeping the profiles correct. If a different profile can fix even some of the effects, those will be fewer shaders to disable or fix. Take a look at the [http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html guide to changing profiles.]<br />
<br />
<br />
----<br />
With those quick-fix techniques in mind, let's take a look at a possible fixing strategy that can optimize your time.<br />
<br />
There are no hard and fast rules for fixing games, since there are so many varieties of problems and that inescapable conflict between disabling effects and fixing effects. This strategy is optimized to save you time, not necessarily give you the best results. <br />
<br />
However, with a game that is fully playable, you can always come back later and improve the fix.<br />
<br />
<br />
Take a look at a possible [[Game Fixing Strategy]]<br />
<br />
<br />
----<br />
* Quiz: Find and enable the flag for Unreal engine games that automatically fixes 3D problems.<br />
*# Find the UDKEngine.ini file for the game.<br />
*# Change the setting to '''AllowNvidiaStereo3d=True'''<br />
*# Run the game, and look for the fog and lava effects to be fixed.<br />
*# Note that the heinous bloom effect is not fixed, but can also be disabled with '''Bloom=False'''<br />
*# Save a screen shot, using only these techniques.<br />
<br />
<br />
In the case of The Ball, you will find that these techniques go a very long ways, but can't resolve the problem with water in the final round. The Unreal flag is very useful, but can't always fix everything.<br />
<br />
You will probably also note that while enabling the flag fixes a lot of effects, it also hammers the performance to an unacceptable level. This is rarely the case with Unreal games, but for The Ball, it's not really a viable fix.<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Lesson_0.5_-_quick_fixLesson 0.5 - quick fix2014-10-02T08:29:22Z<p>Bo3b admin: </p>
<hr />
<div>==== Summary ====<br />
Look for easy ways to fix effects, only do the hard stuff if you need to.<br />
<br />
<br />
Level of difficulty: Easy<br><br />
Time required: 20 minutes<br />
<br><br />
<br><br />
This lesson does not have a video walkthrough, as the techniques are simple and well understood.<br />
<br />
<br />
==== Objective ====<br />
Learn two alternate techniques for fixing stereo glitches, that don't require HelixMod.<br />
<br><br />
Adopt a fixing strategy to optimize your game-fixing time.<br />
<br />
==== Quiz====<br />
...<br />
<br><br />
<br><br />
<br />
----<br />
Although it's incredibly rewarding, keep in mind that fixing games with HelixMod can be tedious and time-consuming. Thus, it's worth spending some time trying easy techniques first, as they can save significant time that can be spent on harder or more interesting problems.<br />
<br />
<br />
There are three techniques that are nearly always worth trying first.<br />
<br />
<br />
* Change in-game settings to disable or improve the 3D.<br />
<br />
* Change configuration file settings to disable or improve the 3D. <br />
*# nvidia cfg param for stereo in Unreal games.<br />
<br />
* Switch profiles for fixes.<br />
[http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html Guide to changing profiles]<br />
<br />
<br />
----<br />
With those quick-fix techniques in mind, let's take a look at a possible fixing strategy that can optimize your time.<br />
<br />
<br />
[[Game_Fixing_Strategy]]<br />
<br />
<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Game_Fixing_StrategyGame Fixing Strategy2014-10-02T08:28:05Z<p>Bo3b admin: </p>
<hr />
<div>The idea is to save as much of your time as possible.<br />
<br />
Fixing can be very time consuming, and often frustrating, so even once you are expert, it will still be worth tackling a game in a strategic fashion.<br />
<br />
These are sorted in order of quickest to hardest.<br />
<br />
<br />
# Change in-game settings.<br />
# Change configuration file options.<br />
# Try different profiles. ''[http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html Guide for changing profiles.]''<br />
# Disable key effects. ''[[Lesson 2 - disable effect]]''<br />
# Disable all broken effects. ''[[Lesson 4 - game fix]]''<br />
# Fix easy or known effects.<br />
# Fix hard effects.<br />
<br />
<br />
At any time when the game is playable, share it! We've lost any number of game fixes because people weren't quite satisfied, then never got back to it. Remember, you can always update it, or hand it over to someone else.<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Game_Fixing_StrategyGame Fixing Strategy2014-10-02T08:24:12Z<p>Bo3b admin: </p>
<hr />
<div>The idea is to save as much of your time as possible.<br />
<br />
Fixing can be very time consuming, and often frustrating, so even once you are expert, it will still be worth tackling a game in a strategic fashion.<br />
<br />
These are sorted in order of quickest to hardest.<br />
<br />
<br />
# Change in-game settings.<br />
# Change configuration file options.<br />
# Try different profiles. [http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html Guide for changing profiles.]<br />
# Disable key effects. [[Lesson 2 - disable effect]]<br />
# Disable all broken effects. [[Lesson 4 - game fix]]<br />
# Fix easy or known effects.<br />
# Fix hard effects.<br />
<br />
<br />
At any time when the game is playable, share it! We've lost any number of game fixes because people weren't quite satisfied, then never got back to it. Remember, you can always update it, or hand it over to someone else.<br />
<br><br />
<br></div>Bo3b adminhttps://wiki.bo3b.net/index.php?title=Game_Fixing_StrategyGame Fixing Strategy2014-10-02T08:21:05Z<p>Bo3b admin: </p>
<hr />
<div>The idea is to save as much of your time as possible.<br />
<br />
Fixing can be very time consuming, and often frustrating, so even once you are expert, it will still be worth tackling a game in a strategic fashion.<br />
<br />
These are sorted in order of quickest to hardest.<br />
<br />
<br />
# Change in-game settings.<br />
# Change configuration file options.<br />
# Try different profiles. [http://helixmod.blogspot.com/2013/03/how-to-change-3d-vision-profile-and.html Guide for changing profiles.]<br />
# Disable key effects.<br />
# Disable all broken effects.<br />
# Fix easy or known effects.<br />
# Fix hard effects.<br />
<br />
<br />
At any time when the game is playable, share it! We've lost any number of game fixes because people weren't quite satisfied, then never got back to it. Remember, you can always update it, or hand it over to someone else.<br />
<br><br />
<br></div>Bo3b admin