Dark Souls internal rendering resolution fix (DSfix)

Thank you for the links, I hope I can fix it, the video shows locations i cant access yet though, so it might a bit hard to notice.

I have undead burg, parish, depths, blighttown and the Firelink

Even walking (yours and the enemies) sounds much better, you will notice it in an instant.
 
Not best GIF but it shows the differences.

53xZXY.gif
 
So what gives better IQ... downsampling + SMAA through dsfix, or native res + MSAA/Combined SSAA or whatever in inspector?

Downsampling + SMAA Ultra. The textures really come out to shine. I have myself 3840*2160 with SMAA Ultra. Want it higher but it isnt perfect 30fps then.
 
If you're going to make AO comparison pics, you really need to make sure you keep the same camera direction.

Find the place you want to take your screenshot, and exit the game. Load it up, but don't touch the camera. Take your screenshot. Exit the game, change AO settings, load up the game, and take up your screenshot. Repeat.

Also, if you really want to show off AO, you need to find a room with lots of interconnecting geometry, since the occlusion is applied mostly where surfaces intersect.
 
If you're going to make AO comparison pics, you really need to make sure you keep the same camera direction.

Find the place you want to take your screenshot, and exit the game. Load it up, but don't touch the camera. Take your screenshot. Exit the game, change AO settings, load up the game, and take up your screenshot. Repeat.

Also, if you really want to show off AO, you need to find a room with lots of interconnecting geometry, since the occlusion is applied mostly where surfaces intersect.

I know first time I did it and was in a hurry. Next time I will do a better jobb.


Durante: Your early version is already good, and its working already better at some levels than nvidias AO. :)
 
If you're going to make AO comparison pics, you really need to make sure you keep the same camera direction.

Find the place you want to take your screenshot, and exit the game. Load it up, but don't touch the camera. Take your screenshot. Exit the game, change AO settings, load up the game, and take up your screenshot. Repeat.

Also, if you really want to show off AO, you need to find a room with lots of interconnecting geometry, since the occlusion is applied mostly where surfaces intersect.

Agreed. That is how you do an AO comparison.

Admitadely though, it is also a good idea to go to a place with alpha textures. AO can have problems with them and the best AO solution could be one that works best with the alpha.
 
So I'm just now wondering which resolution is a good place to downsample from with a HD5870/1gB VRAM. The standard setting looks quite a bit blurrier than higher resos, but its much smoother. While also looking way better than the vanilla game. But it shouldn't really be blurry at all because straight up 1080p is higher than my monitor can handle.
 
So I'm just now wondering which resolution is a good place to downsample from with a HD5870/1gB VRAM. The standard setting looks quite a bit blurrier than higher resos, but its much smoother. While also looking way better than the vanilla game. But it shouldn't really be blurry at all because straight up 1080p is higher than my monitor can handle.

Try this, make sure that the render resolution you're using is a whole number multiple of your monitors resolution. Say if your monitor is a 1680x1050 monitor, then you could use 3360x2100 as your setting in the ini-file.
 
The difference is striking, wow.

Ya I'm kind of pissed I played through 90% of the game without that fix. I only have the dlc content and final boss left.

But when I first turned it on I was blown away by what I was missing. I was in the painted world and there were bugs, snowfall, birds, and a wolf howling in the background...and it was dead silent before.

Oh well. I'm about to start a int/dex build and do another playthrough right after I finish this one.
 
Try this, make sure that the render resolution you're using is a whole number multiple of your monitors resolution. Say if your monitor is a 1680x1050 monitor, then you could use 3360x2100 as your setting in the ini-file.

So I should be going by multiples of 720 then, considering that is the highest widescreen resolution my monitor is capable of. Or should I aim for multiples of 1280x1024?
 
So I should be going by multiples of 720 then, considering that is the highest widescreen resolution my monitor is capable of. Or should I aim for multiples of 1280x1024?

If you got a 4:3 monitor then go for the right resolution, try 2560x2028
 
FilteringOverride set to 2 was definitely the cause of any performance issues I had in the past. Got that set to 1 now, downsampling from 1440p, SMAA cranked and the 1.0 SSAO and even in Blighttown I haven't dropped a frame. Before with just the downsampling and filter override on 2 it would jump down to 15fps every few minutes.
 
FilteringOverride set to 2 was definitely the cause of any performance issues I had in the past. Got that set to 1 now, downsampling from 1440p, SMAA cranked and the 1.0 SSAO and even in Blighttown I haven't dropped a frame. Before with just the downsampling and filter override on 2 it would jump down to 15fps every few minutes.

pretty sure Durante recommends filtering at 0 because it's bugged... don't know why the option is in there though if you're not supposed to use it. just use the filtering override in you GPU driver settings.
 
Durante you are the best dude ever.

I was the one who first said that SSAO via fix would be best thing ever and now it is and i am amazed.

Beautiful work dude.

Also durante you should connect your fix of yours with adfly. 5 sec ad for people downloading and cash for you with each download. So people will help you just with downloading your fix. It is not much but hey it's better than nothing :)
 
pretty sure Durante recommends filtering at 0 because it's bugged... don't know why the option is in there though if you're not supposed to use it. just use the filtering override in you GPU driver settings.

I was under the impression that if you were downscaling (which I am) you needed this setting at 1.

# texture filtering override
# 0 = no change
# 1 = enable supersampling by downscaling (use only if you need it!)
# 2 = full AF override (may degrade performance, currently implemented badly, do not enable)
# if in doubt, leave this at 0
 
I was under the impression that if you were downscaling (which I am) you needed this setting at 1.
That's only true if you don't override filtering in the driver. If you do, you can skip it.

pretty sure Durante recommends filtering at 0 because it's bugged... don't know why the option is in there though if you're not supposed to use it. just use the filtering override in you GPU driver settings.
Because removing it and then re-adding it when it's fixed takes some effort ;)
 
I tweaked the SSAO shader a lot. The major artifacting in the distance is completely gone, and the line artifacts close up have been substantially diminished (but not eliminated). The remaining artifacts are hard to fix, they are because I get a very low-precision depth buffer from the game.

At some point I may implement an option for more expensive AO filtering that will deal with the remaining artifacts (or at least diminish them further).

Since people like screenshot comparisons, here's an "official" one (load the images in tabs for a direct comparison)

(The good news is that I seem to have no framerate issues even running SSAO at 3kx2k)
 
I tweaked the SSAO shader a lot. The major artifacting in the distance is completely gone, and the line artifacts close up have been substantially diminished (but not eliminated). The remaining artifacts are hard to fix, they are because I get a very low-precision depth buffer from the game.

At some point I may implement an option for more expensive AO filtering that will deal with the remaining artifacts (or at least diminish them further).

Since people like screenshot comparisons, here's an "official" one (load the images in tabs for a direct comparison)


(The good news is that I seem to have no framerate issues even running SSAO at 3kx2k)

Wow great work! You my man should be added in the credits of the game, in a special update.

Your AO is alot better than the Nvidias AO which can dissapear at some camera angles and yours works with higher resolution.
 
Is there an easy way to verify if SSAO is working? I mean without removing the fix and restarting the game etc. :)

Just press 2 on the numpad and see if there is added shadows to outer layer of objects. Or go to Firelink and press 2. You should see that the grass gets shadows.
 
Note that the version included in 1.0 isn't quite ready for consumption, there are some really ugly artifacts in the distance.
 
Durante, any chance you would take a look at getting rid of black bars for non 16:9 resolution with correct fov?

The fix from flawless widescreen main purpose seems to be getting the game to work on surround/eyefinity setups.
 
Looking at the key bindings ini file, I wanted to see what the game looked like with smaa on/off in realtime. So the key is label VK_NUMPAD1 and I don't see a difference when hitting that key. It should be pretty noticeable with #3 on/off yes? Btw, it's early and I feel kinda stupid right now, I didn't know what the hudless screenshot key was until I googled it heh.
 
Fuck yeah!

I fixed the SSAO issue! (and without impacting performance)

1.0 (actually, it was even worse than this, but this is the closest I cared to reconstruct):
screenshot_2012-09-0899fzu.jpg


Now:
screenshot_2012-09-0899fvv.jpg

(Note that the noise you see doesn't really matter in the final filtered image -- this is the raw AO buffer)


Final image on/off:
screenshot_2012-09-088adsn.jpg

screenshot_2012-09-08k8imt.jpg

Look at that depth and solidity!

I think the AO is now pretty damn good, especially given the relatively low performance impact.

Durante, any chance you would take a look at getting rid of black bars for non 16:9 resolution with correct fov?

The fix from flawless widescreen main purpose seems to be getting the game to work on surround/eyefinity setups.
Not too soon probably, sorry.
 
Looking at the key bindings ini file, I wanted to see what the game looked like with smaa on/off in realtime. So the key is label VK_NUMPAD1 and I don't see a difference when hitting that key. It should be pretty noticeable with #3 on/off yes? Btw, it's early and I feel kinda stupid right now, I didn't know what the hudless screenshot key was until I googled it heh.
That should be correct, but you can try binding it to a different key. And it's easier to see if you run a low internal resolution, and harder with downsampling.
 
Fuck yeah!

I fixed the SSAO issue! (and without impacting performance)

Look at that depth and solidity!

I think the AO is now pretty damn good, especially given the relatively low performance impact.

Not too soon probably, sorry.

Ah, that's too bad. Thx for answering anyway. Can't wait to try that new SSAO!
 
Fuck yeah!

I fixed the SSAO issue! (and without impacting performance)

1.0 (actually, it was even worse than this, but this is the closest I cared to reconstruct):
screenshot_2012-09-0899fzu.jpg


Now:
screenshot_2012-09-0899fvv.jpg

(Note that the noise you see doesn't really matter in the final filtered image -- this is the raw AO buffer)


Final image on/off:
screenshot_2012-09-088adsn.jpg

screenshot_2012-09-08k8imt.jpg

Look at that depth and solidity!

I think the AO is now pretty damn good, especially given the relatively low performance impact.

Not too soon probably, sorry.

post that fix :D
 
improved AO in v 1.1 durante?
Yes. I still want to fix the issue some people experience with SMAA, but I still couldn't reproduce it :(

post that fix :D
It will be in the next version, but if you can't wait you should be able to just replace the contents of VSSAO.fx with this:
Code:
// Volumetric SSAO
// Implemented by Tomerk for OBGE
// Adapted and tweaked for Dark Souls by Durante

/***User-controlled variables***/
#define N_SAMPLES 9 //number of samples, currently do not change.

extern float scale = 1; //downsampling scale, 1 is highest quality but slowest
extern float aoRadiusMultiplier = 1.2; //Linearly multiplies the radius of the AO Sampling
extern float aoStrengthMultiplier = 2.0; //Linearly multiplies the strength of the AO
extern float aoClamp = 0.0; //The maximum strength of the AO, 0 is max strength, 1 is weakest
extern float ThicknessModel = 30000.0; //units in space the AO assumes objects' thicknesses are
extern float FOV = 68; //Field of View in Degrees
extern float luminosity_threshold = 0.3;

#define LUMINANCE_CONSIDERATION //comment this line to not take pixel brightness into account
//#define RAW_SSAO //uncomment this line to show the raw ssao

/***End Of User-controlled Variables***/
static float2 rcpres = PIXEL_SIZE;
static float aspect = rcpres.y/rcpres.x;
static const float nearZ = 10.0;
static const float farZ = 5000.0;
static const float2 g_InvFocalLen = { tan(0.5f*radians(FOV)) / rcpres.y * rcpres.x, tan(0.5f*radians(FOV)) };
static const float depthRange = nearZ-farZ;

texture2D depthTex2D;
texture2D frameTex2D;
texture2D prevPassTex2D;

sampler depthSampler = sampler_state
{
	texture = <depthTex2D>;
	AddressU = CLAMP;
	AddressV = CLAMP;
	MINFILTER = LINEAR;
	MAGFILTER = LINEAR;
};

sampler frameSampler = sampler_state
{
	texture = <frameTex2D>;
	AddressU = CLAMP;
	AddressV = CLAMP;
	MINFILTER = LINEAR;
	MAGFILTER = LINEAR;
};

sampler passSampler = sampler_state
{
	texture = <prevPassTex2D>;
	AddressU = CLAMP;
	AddressV = CLAMP;
	MINFILTER = LINEAR;
	MAGFILTER = LINEAR;
};

struct VSOUT
{
	float4 vertPos : POSITION;
	float2 UVCoord : TEXCOORD0;
};

struct VSIN
{
	float4 vertPos : POSITION0;
	float2 UVCoord : TEXCOORD0;
};

VSOUT FrameVS(VSIN IN)
{
	VSOUT OUT = (VSOUT)0.0f;	// initialize to zero, avoid complaints.
	OUT.vertPos = IN.vertPos;
	OUT.UVCoord = IN.UVCoord;
	return OUT;
}

static float2 sample_offset[N_SAMPLES] =
{
//#if N_SAMPLES >= 9
	float2(-0.1376476f, 0.2842022f),
	float2(-0.626618f, 0.4594115f),
	float2(-0.8903138f, -0.05865424f),
	float2(0.2871419f, 0.8511679f),
	float2(-0.1525251f, -0.3870117f),
	float2(0.6978705f, -0.2176773f),
	float2(0.7343006f, 0.3774331f),
	float2(0.1408805f, -0.88915f),
	float2(-0.6642616f, -0.543601f)
//#endif
};

static float sample_radius[N_SAMPLES] =
{
//#if N_SAMPLES >= 9
	0.948832,
	0.629516,
	0.451554,
	0.439389,
	0.909372,
	0.682344,
	0.5642,
	0.4353,
	0.5130
//#endif
};


float2 rand(in float2 uv) {
	float noiseX = (frac(sin(dot(uv, float2(12.9898,78.233)*2.0)) * 43758.5453));
	//float noiseY = sqrt(1-noiseX*noiseX);
	float noiseY = (frac(sin(dot(uv, float2(12.9898,78.233))) * 43758.5453));
	return float2(noiseX, noiseY);
}

float readDepth(in float2 coord : TEXCOORD0) {
	float4 col = tex2D(depthSampler, coord);
	float posZ = clamp(((1.0-col.z)/256.0 + (1.0-col.y) + 256.0*(1.0-col.x))/(5.0), 0.0, 1.0);
	//float posZ = ((1.0-col.y) + 256.0*(1.0-col.x))/(5.0);
	return ((2.0f * nearZ) / (nearZ + farZ - posZ * (farZ - nearZ)))*10.0;
	//return posZ / (depthRange - (depthRange - 1.0)*posZ);
	//float posZ = ((1.0-col.y) + 256.0*(1.0-col.x));
	//return posZ;
}

float3 getPosition(in float2 uv, in float eye_z) {
   uv = (uv * float2(2.0, -2.0) - float2(1.0, -1.0));
   float3 pos = float3(uv * g_InvFocalLen * eye_z, eye_z );
   return pos;
}


float4 ssao_Main( VSOUT IN ) : COLOR0 {
	clip(1/scale-IN.UVCoord.x);
	clip(1/scale-IN.UVCoord.y);	
	IN.UVCoord.xy *= scale;

	float depth = readDepth(IN.UVCoord);
	float3 pos = getPosition(IN.UVCoord, depth);
	float3 dx = ddx(pos);
	float3 dy = ddy(pos);
	float3 norm = normalize(cross(dx,dy));
	norm.y *= -1;

	float sample_depth;

	float ao=0;
	float s=0.0;

	float2 rand_vec = rand(IN.UVCoord);
	float2 sample_vec_divisor = g_InvFocalLen*depth*depthRange/(aoRadiusMultiplier*4000*rcpres);
	float2 sample_center = IN.UVCoord + norm.xy/sample_vec_divisor*float2(1,aspect);
	float sample_center_depth = depth*depthRange + norm.z*aoRadiusMultiplier*10;
	
	for(int i = 0; i < N_SAMPLES; i++) {
		float2 sample_vec = reflect(sample_offset[i], rand_vec);
		sample_vec /= sample_vec_divisor;
		float2 sample_coords = sample_center + sample_vec*float2(1,aspect);
		
		float curr_sample_radius = sample_radius[i]*aoRadiusMultiplier*10;
		float curr_sample_depth = depthRange*readDepth(sample_coords);
		
		ao += clamp(0,curr_sample_radius+sample_center_depth-curr_sample_depth,2*curr_sample_radius);
		ao -= clamp(0,curr_sample_radius+sample_center_depth-curr_sample_depth-ThicknessModel*depth*depth*depth,2*curr_sample_radius);
		s += 2*curr_sample_radius;
	}

	ao /= s;
	
	// adjust for close and far away
	if(depth<0.08) ao = lerp(ao, 0.0, (0.08-depth)*25);
	//if(depth>0.5) ao = lerp(ao, 0.0, (depth-0.5)*10);

	ao = 1.0-ao*aoStrengthMultiplier;
	
	//return float4(depth,depth,depth,1);
	return float4(ao,ao,ao,1);
}


float4 Blur( VSOUT IN ) : COLOR0 {
	float color = tex2D(passSampler, IN.UVCoord).r*4;

	color += tex2D(passSampler, IN.UVCoord + float2(rcpres.x,0)).r*2;
	color += tex2D(passSampler, IN.UVCoord + float2(-rcpres.x,0)).r*2;
	color += tex2D(passSampler, IN.UVCoord + float2(0,rcpres.y)).r*2;
	color += tex2D(passSampler, IN.UVCoord + float2(0,-rcpres.y)).r*2;

	color += tex2D(passSampler, IN.UVCoord + rcpres).r;
	color += tex2D(passSampler, IN.UVCoord - rcpres).r;
	color += tex2D(passSampler, IN.UVCoord + rcpres * float2(1,-1)).r;
	color += tex2D(passSampler, IN.UVCoord - rcpres * float2(1,-1)).r;

	color /= 16;

	return float4(color,1,1,1);
	//return tex2D(passSampler, IN.UVCoord).r;
}


float4 Combine( VSOUT IN ) : COLOR0 {
	float3 color = tex2D(frameSampler, IN.UVCoord).rgb;
	float ao = clamp(tex2D(passSampler, IN.UVCoord/scale).r, aoClamp, 1.0);

	#ifdef LUMINANCE_CONSIDERATION
	float luminance = color.r*0.3+color.g*0.59+color.b*0.11;
	float white = 1.0;
	float black = 0;

	luminance = clamp(max(black,luminance-luminosity_threshold)+max(black,luminance-luminosity_threshold)+max(black,luminance-luminosity_threshold),0.0,1.0);
	ao = lerp(ao,white,luminance);
	#endif

	color *= ao;

   
	//return float4(ao, ao, ao,1);
	return float4(color,1);
}

technique t0 
{
	pass p0
	{
		VertexShader = compile vs_3_0 FrameVS();
		PixelShader = compile ps_3_0 ssao_Main();
	}
	pass p1
	{
		VertexShader = compile vs_3_0 FrameVS();
		PixelShader = compile ps_3_0 Blur();
	}
	pass p2
	{
		VertexShader = compile vs_1_1 FrameVS();
		PixelShader = compile ps_2_0 Combine();
	}
}

No support for this!
 
Top Bottom