Oblivion Graphics Extender, Thread 15

Post » Tue Oct 12, 2010 5:36 am

Well, translating compiled shader assembly back into HLSL is a real pain. Dividing through multiplication of reciprocals, length being the inverse of the inverse square root of a dot product of X (that is no typo, TWO inverses), taking matrix multiplication from 4 dot products to a single HLSL multiply call...

But, after 6 hours of figuring many of the techniques a compiler uses to make the most efficient code it can, I finally translated the vertex shader for PAR2000, one-half of the thirty-five shaders responsible for parallax displacement mapping in Oblivion. Now I know the inputs for both the vertex and pixel shader, and what they look like coming out of the vertex shader. After vtastek mentioned cone-relief mapping, I just had to go and read about it... After a couple of days figuring out how to create the custom assets for cone-relief mapping (and doing it in such a way that Oblivion will still mostly work), I set off to replace a single shader with cone relief mapping, and the textures for great forest rocks to see how it looks.

Well, I haven't gotten that far yet, but here is the HLSL for PAR2000.vso:
Spoiler
row_major float4x4 ModelViewProj : register(c0);float3 LightDirection : register(c13);float4 FogParam : register(c23);float3 FogColor : register(c24);float4 EyePosition : register(c25);struct vertexInput{	float4 pos       : POSITION;	float3 tangent   : TANGENT;	float3 binormal  : BINORMAL;	float3 normal    : NORMAL;	float2 texCoord  : TEXCOORD0;	float4 color     : COLOR0;};struct pixelInput{	float4 pos       : POSITION;	float4 color     : COLOR0;	float4 fogcolor  : COLOR1;	float2 texCoord  : TEXCOORD0;	float3 lightDir  : TEXCOORD1;	float3 cameraDir : TEXCOORD6;};pixelInput simple_vs(vertexInput IN){		float temp1;	float3 temp3;		//Transform light direction to tangent space.	float3x3 tangentMatrix = {IN.binormal,IN.tangent,IN.normal};	temp3 = mul(tangentMatrix, LightDirection);		//Normalize the light direction and output.	OUT.lightDir = normalize(temp3);	//Find camera direction and normalize it.	temp3 = normalize(EyePosition.xyz - IN.pos.xyz);		//Transform the camera vector to tangent space.	temp3 = mul(tangentMatrix, temp3);	OUT.cameraDir = normalize(temp3);		//Transform position of the vertex into clip coordinates	float4 posCS = mul(ModelViewProj, IN.pos);	//...and output.	OUT.pos = posCS;		//Next, calculate the fog attenuation.	temp1 = (FogParam.x - length(posCS.xyz)) / FogParam.y;	temp1 = saturate(temp1);	//Encode the attenuation amount into the fog color's alpha channel.	OUT.fogcolor.rgb = FogColor;	OUT.fogcolor.a = 1.0 - temp1;	//And output the rest of our outputs.	OUT.texCoord = IN.texCoord;	OUT.color = IN.color;	return OUT;}

vtastek is right. It is pretty standard, but now I at least know its all in tangent space, and how fog attenuation was programmed. It was a more difficult task to reverse engineer this than I thought, but hopefully it'll be worth it. I haven't attempted to compile it yet, but it looks right and makes sense. Let me know if there is anything off about it.


Brilliant work. :thumbsup:

Does anyone know why the shader packages seem to contain many identical shaders, eg. the nighteye shader, which has a copy in each package? I haven't done anything with the shaders myself yet, but I did notice this when I had a quick look.
User avatar
Sabrina Steige
 
Posts: 3396
Joined: Mon Aug 20, 2007 9:51 pm

Post » Mon Oct 11, 2010 11:58 pm

I guess because every Shader package is made to handle a different Graphic Card and the technique use in that card. So basically every Shader package contains the exact same Shaders for all in game effects but only a few are adapted for a specific Graphic Card and the technique use in those cards. Like different shader packaged for HD lightning and NON HD lightning, support for Shader model 3 and 2 and Geforce / ATI and so on.
User avatar
Bambi
 
Posts: 3380
Joined: Tue Jan 30, 2007 1:20 pm

Post » Mon Oct 11, 2010 9:08 pm

Does anyone know why the shader packages seem to contain many identical shaders, eg. the nighteye shader, which has a copy in each package?

I believe its because many of the packages are dependent on hardware or LOD/Quality. If the game says, "This computer is on the minimum graphics hardware, I should use this shader package to make the game easier for this computer." But, I imagine making the image brighter and blue isn't that hard no matter the hardware configuration, so the night eye shader is similar across all the packages. Other shaders like those responsible for normal mapping, specular, parallax mapping, HDR/Bloom, and the like are probably very, very different between the packages.
User avatar
Sarah MacLeod
 
Posts: 3422
Joined: Tue Nov 07, 2006 1:39 am

Post » Tue Oct 12, 2010 12:44 am

Ah, I hadn't thought of that. I would have had a core package of shaders that could run on any card matching or exceeding the minimum requirements, which I would have thought would be a fair few, and then had hardware specific ones loaded as well as that, but that's just me. :shrug: Makes sense though, and you can see which package your game loads in the RendererInfo.txt in your My Games folder, which simplifies quick testing at least.
User avatar
Veronica Martinez
 
Posts: 3498
Joined: Tue Jun 20, 2006 9:43 am

Post » Tue Oct 12, 2010 6:11 am

All I can think of is to try setting the legacy compiler on. Other than that, it looks like a hardware/driver thing to me, though I don't really know. :shrug:
What's your OBGEv2 log look like?


I tried the legacy compiler and it did absolutely nothing except take longer to load - it also had compatibility issues with a few of the shaders.
I seem to get better results when I disable the raw z fix, but it still isn't displaying correctly.
Here are some screenshots with the raw z fix disabled. The shaders seem to actually behave as they should but with some rendering errors... as opposed to just putting some graphical junk on top of the game screen.

I've tried all sorts of drivers to no avail. Im running a 7800gtx on Windows XP with DX9.0c

Once again, any input is appreciated.

http://img.photobucket.com/albums/v203/solarwins/Oblivion2010-05-3102-18-11-15.jpg
http://img.photobucket.com/albums/v203/solarwins/Oblivion2010-05-3102-18-26-79.jpg

Here is the OBGE log with the raw z fix enabled:
Spoiler
Ingnoring message.Pre HookRESZ not supported.Failed to create buffer texture (INTZ).Failed to create buffer texture (DF24).Failed to create buffer texture (DF16).Depth buffer texture (RAWZ) (1024,768) created OK.Depth buffer attached OK. 3Setting IsRAWZflag.Starting a new game.Creating vertex buffers.Creating shader textures.Width = 1024, Height = 768Setting shader surfaces.Setting depth texture.RAWZ depth texture - applying fix.ShaderList has been disabled by the INI file.Added to list OK.Alt Render target - width = 256, height = 256Received save game message.Ingnoring message.Saving a game.Calling TextureManager::SaveGameShaderManager::SaveGameShader index = 0Shader (ssao_perf.fx) - Script refID = 3000800  Loading shader (data\shaders\ssao_perf.fx)Setting effects screen texture.Shader (ssao_test.fx) - Script refID = 3000800  Loading shader (data\shaders\ssao_test.fx)Found filename : ssao\RandomNoiseB.ddsLoading texture (data\textures\ssao\RandomNoiseB.dds)Setting effects screen texture.Shader (DepthOfField.fx) - Script refID = 3000800  Loading shader (data\shaders\DepthOfField.fx)Setting effects screen texture.Shader (Godrays.fx) - Script refID = 3000800  Loading shader (data\shaders\Godrays.fx)Setting effects screen texture.Shader (CelShader+EdgeAA.fx) - Script refID = 3000800  Loading shader (data\shaders\CelShader+EdgeAA.fx)Setting effects screen texture.Shader (ColorEffects.fx) - Script refID = 3000800  Loading shader (data\shaders\ColorEffects.fx)Setting effects screen texture.Shader (ColorMood.fx) - Script refID = 3000800  Loading shader (data\shaders\ColorMood.fx)Setting effects screen texture.Shader (obsharpen.fx) - Script refID = 3000800  Loading shader (data\shaders\obsharpen.fx)Setting effects screen texture.Alt Render target - width = 1024, height = 768Alt Render target - width = 1024, height = 768Received ExitGame message.Calling Release DeviceReleasing thisframe surface.Releasing thisframe texture.Releasing lastpass surface.Releasing lastpass texture.Releasing lastframe surface.Releasing lastframe texture.Releasing shader vertex buffer.


Here is the OBGE log with the raw z fix disabled:
Spoiler
Ingnoring message.Pre HookRESZ not supported.Failed to create buffer texture (INTZ).Failed to create buffer texture (DF24).Failed to create buffer texture (DF16).Depth buffer texture (RAWZ) (1024,768) created OK.Depth buffer attached OK. 3Ingnoring message.Received load game message.Loading a game.Creating vertex buffers.Creating shader textures.Width = 1024, Height = 768Setting shader surfaces.Setting depth texture.ShaderList has been disabled by the INI file.Added to list OK.ShaderList has been disabled by the INI file.No texture data found in save file.No shader data in save file.Alt Render target - width = 1024, height = 768Shader (ssao_perf.fx) - Script refID = 3000800  Loading shader (data\shaders\ssao_perf.fx)Setting effects screen texture.Shader (ssao_test.fx) - Script refID = 3000800  Loading shader (data\shaders\ssao_test.fx)Found filename : ssao\RandomNoiseB.ddsLoading texture (data\textures\ssao\RandomNoiseB.dds)Setting effects screen texture.Shader (DepthOfField.fx) - Script refID = 3000800  Loading shader (data\shaders\DepthOfField.fx)Setting effects screen texture.Shader (Godrays.fx) - Script refID = 3000800  Loading shader (data\shaders\Godrays.fx)Setting effects screen texture.Shader (CelShader+EdgeAA.fx) - Script refID = 3000800  Loading shader (data\shaders\CelShader+EdgeAA.fx)Setting effects screen texture.Shader (ColorEffects.fx) - Script refID = 3000800  Loading shader (data\shaders\ColorEffects.fx)Setting effects screen texture.Shader (ColorMood.fx) - Script refID = 3000800  Loading shader (data\shaders\ColorMood.fx)Setting effects screen texture.Shader (obsharpen.fx) - Script refID = 3000800  Loading shader (data\shaders\obsharpen.fx)Setting effects screen texture.Alt Render target - width = 1024, height = 768Alt Render target - width = 1024, height = 768Alt Render target - width = 1024, height = 768Received ExitGame message.Calling Release DeviceReleasing thisframe surface.

User avatar
Fanny Rouyé
 
Posts: 3316
Joined: Sun Mar 25, 2007 9:47 am

Post » Tue Oct 12, 2010 12:25 am

Anyone familiar with shadowing techniques? The code below is an intermediary between shader assembly and human readable HLSL that I'm working on from PAR2002.vso, and it definitely has to do with shadow casting. Unfortunately, I don't know much about shadowing, and if I don't know anything about shadowing, then it is nearly impossible for me to interpret this assembly...

Spoiler
//Constants used in this block.row_major float4x4 ShadowProj : register(c28);float4 ShadowProjData : register(c32);float4 ShadowProjTransform : register(c33);	//Variables meant to mimic shader registers.	float4 r0,r1,r2;	r1.w = dot(ShadowProj[3], IN.pos);	r1.y = r1.w * ShadowProjTransform.w;	r0.w = 1 / r1.y;	r1.x = dot(ShadowProj[0], IN.pos);	r1.y = dot(ShadowProj[1], IN.pos);	r2.xy = (r1.w * ShadowProjTransform.xy) + r1.xy;	OUT.texCShad.xy = r0.w * r2.xy;	r1.w = 1 / ShadowProjData.w;	r1.xy = r1.xy - ShadowProjData.xy;	OUT.texCShad.z = r1.x * r1.w;	OUT.texCShad.w = (r1.y * -r1.w) + 1.0;


It appears that texCShad contains 2 pairs of texture coordinates, with texCShad.xy for the Shadow Map, and texCShad.zw for the Shadow Map Mask.

So, can anyone help me get this portion of code into something a human can interpret? Does it look like any kind of well known shadowing algorithm?
User avatar
sarah taylor
 
Posts: 3490
Joined: Thu Nov 16, 2006 3:36 pm

Post » Mon Oct 11, 2010 7:24 pm

Update: Nailed it down! It's the VSync enabled causing the issue. Disabling it fix it. :facepalm:
(I kept it enabled in Oblivion because of some tearing.)

I can confirm this. Maybe it's a good idea to update the first post with this info when you have time, wrinklyninja?
User avatar
Jessie Rae Brouillette
 
Posts: 3469
Joined: Mon Dec 11, 2006 9:50 am

Post » Mon Oct 11, 2010 6:46 pm

I tried the legacy compiler and it did absolutely nothing except take longer to load - it also had compatibility issues with a few of the shaders.
I seem to get better results when I disable the raw z fix, but it still isn't displaying correctly.
Here are some screenshots with the raw z fix disabled. The shaders seem to actually behave as they should but with some rendering errors... as opposed to just putting some graphical junk on top of the game screen.

I've tried all sorts of drivers to no avail. Im running a 7800gtx on Windows XP with DX9.0c

Once again, any input is appreciated.

http://img.photobucket.com/albums/v203/solarwins/Oblivion2010-05-3102-18-11-15.jpg
http://img.photobucket.com/albums/v203/solarwins/Oblivion2010-05-3102-18-26-79.jpg

Here is the OBGE log with the raw z fix enabled:
Spoiler
Ingnoring message.Pre HookRESZ not supported.Failed to create buffer texture (INTZ).Failed to create buffer texture (DF24).Failed to create buffer texture (DF16).Depth buffer texture (RAWZ) (1024,768) created OK.Depth buffer attached OK. 3Setting IsRAWZflag.Starting a new game.Creating vertex buffers.Creating shader textures.Width = 1024, Height = 768Setting shader surfaces.Setting depth texture.RAWZ depth texture - applying fix.ShaderList has been disabled by the INI file.Added to list OK.Alt Render target - width = 256, height = 256Received save game message.Ingnoring message.Saving a game.Calling TextureManager::SaveGameShaderManager::SaveGameShader index = 0Shader (ssao_perf.fx) - Script refID = 3000800  Loading shader (data\shaders\ssao_perf.fx)Setting effects screen texture.Shader (ssao_test.fx) - Script refID = 3000800  Loading shader (data\shaders\ssao_test.fx)Found filename : ssao\RandomNoiseB.ddsLoading texture (data\textures\ssao\RandomNoiseB.dds)Setting effects screen texture.Shader (DepthOfField.fx) - Script refID = 3000800  Loading shader (data\shaders\DepthOfField.fx)Setting effects screen texture.Shader (Godrays.fx) - Script refID = 3000800  Loading shader (data\shaders\Godrays.fx)Setting effects screen texture.Shader (CelShader+EdgeAA.fx) - Script refID = 3000800  Loading shader (data\shaders\CelShader+EdgeAA.fx)Setting effects screen texture.Shader (ColorEffects.fx) - Script refID = 3000800  Loading shader (data\shaders\ColorEffects.fx)Setting effects screen texture.Shader (ColorMood.fx) - Script refID = 3000800  Loading shader (data\shaders\ColorMood.fx)Setting effects screen texture.Shader (obsharpen.fx) - Script refID = 3000800  Loading shader (data\shaders\obsharpen.fx)Setting effects screen texture.Alt Render target - width = 1024, height = 768Alt Render target - width = 1024, height = 768Received ExitGame message.Calling Release DeviceReleasing thisframe surface.Releasing thisframe texture.Releasing lastpass surface.Releasing lastpass texture.Releasing lastframe surface.Releasing lastframe texture.Releasing shader vertex buffer.


Here is the OBGE log with the raw z fix disabled:
Spoiler
Ingnoring message.Pre HookRESZ not supported.Failed to create buffer texture (INTZ).Failed to create buffer texture (DF24).Failed to create buffer texture (DF16).Depth buffer texture (RAWZ) (1024,768) created OK.Depth buffer attached OK. 3Ingnoring message.Received load game message.Loading a game.Creating vertex buffers.Creating shader textures.Width = 1024, Height = 768Setting shader surfaces.Setting depth texture.ShaderList has been disabled by the INI file.Added to list OK.ShaderList has been disabled by the INI file.No texture data found in save file.No shader data in save file.Alt Render target - width = 1024, height = 768Shader (ssao_perf.fx) - Script refID = 3000800  Loading shader (data\shaders\ssao_perf.fx)Setting effects screen texture.Shader (ssao_test.fx) - Script refID = 3000800  Loading shader (data\shaders\ssao_test.fx)Found filename : ssao\RandomNoiseB.ddsLoading texture (data\textures\ssao\RandomNoiseB.dds)Setting effects screen texture.Shader (DepthOfField.fx) - Script refID = 3000800  Loading shader (data\shaders\DepthOfField.fx)Setting effects screen texture.Shader (Godrays.fx) - Script refID = 3000800  Loading shader (data\shaders\Godrays.fx)Setting effects screen texture.Shader (CelShader+EdgeAA.fx) - Script refID = 3000800  Loading shader (data\shaders\CelShader+EdgeAA.fx)Setting effects screen texture.Shader (ColorEffects.fx) - Script refID = 3000800  Loading shader (data\shaders\ColorEffects.fx)Setting effects screen texture.Shader (ColorMood.fx) - Script refID = 3000800  Loading shader (data\shaders\ColorMood.fx)Setting effects screen texture.Shader (obsharpen.fx) - Script refID = 3000800  Loading shader (data\shaders\obsharpen.fx)Setting effects screen texture.Alt Render target - width = 1024, height = 768Alt Render target - width = 1024, height = 768Alt Render target - width = 1024, height = 768Received ExitGame message.Calling Release DeviceReleasing thisframe surface.



It looks like your card uses the RAWZ depth buffer method, so you should use the fix or things won't work right. (not that they're working ATM)

The screen corruption reminds me of the sort of thing I'd get if I had drivers that weren't too good with what I was trying to play, or something like that. I know I recently got a similar thing with my Mobility HD 4650 when I upgraded to Ubuntu 10.04, which managed to break everything graphics related for me. :banghead: But anyway, it looks like your drivers don't approve of the way OBGEv2 is doing what it does.

Are you using the latest drivers?


Anyone familiar with shadowing techniques? The code below is an intermediary between shader assembly and human readable HLSL that I'm working on from PAR2002.vso, and it definitely has to do with shadow casting. Unfortunately, I don't know much about shadowing, and if I don't know anything about shadowing, then it is nearly impossible for me to interpret this assembly...

Spoiler
//Constants used in this block.row_major float4x4 ShadowProj : register(c28);float4 ShadowProjData : register(c32);float4 ShadowProjTransform : register(c33);	//Variables meant to mimic shader registers.	float4 r0,r1,r2;	r1.w = dot(ShadowProj[3], IN.pos);	r1.y = r1.w * ShadowProjTransform.w;	r0.w = 1 / r1.y;	r1.x = dot(ShadowProj[0], IN.pos);	r1.y = dot(ShadowProj[1], IN.pos);	r2.xy = (r1.w * ShadowProjTransform.xy) + r1.xy;	OUT.texCShad.xy = r0.w * r2.xy;	r1.w = 1 / ShadowProjData.w;	r1.xy = r1.xy - ShadowProjData.xy;	OUT.texCShad.z = r1.x * r1.w;	OUT.texCShad.w = (r1.y * -r1.w) + 1.0;


It appears that texCShad contains 2 pairs of texture coordinates, with texCShad.xy for the Shadow Map, and texCShad.zw for the Shadow Map Mask.

So, can anyone help me get this portion of code into something a human can interpret? Does it look like any kind of well known shadowing algorithm?


Sorry, this one knows nothing of shadows. Presumably you've already tried searching for similar code or shadowing algorithms?
User avatar
jadie kell
 
Posts: 3497
Joined: Sat Jul 29, 2006 3:54 pm

Post » Mon Oct 11, 2010 5:50 pm

@HawkleyFox:
Are you familiar with RPG-BlackDragons work?
He has taken a shot in modifying the Shades that do shadows swell.
Download his resource on shadowing, it contains some insight on the Shaders.

RPG-BlackDragons Oblivion with Shadows
http://oblivionmodgods.de/rpg-blackdragons-oblivion-with-shadows-t440.html

NOTE:
For those that did not know about RPG-BlackDragons Oblivion with Shadows, and now think Wow I want that, the modification does not work that well. You will experience lots of wrong looking shadows and Saving / Loading ERRORS.

EXTRA LINK:
For those that want more.

Blip-Blop-Shadow Mod
http://oblivionmodgods.de/blip-blops-shadow-mod-t450.html#p2237
User avatar
Anna S
 
Posts: 3408
Joined: Thu Apr 19, 2007 2:13 am

Post » Mon Oct 11, 2010 8:17 pm

Do we know which shader packages are used with which hardware levels (shader model support levels, I presume)? That would be quite useful IMHO, and if we don't know, perhaps it would be a good idea to do a survey of people's RendererInfo.txt files to find out?

That way if we can actually replace shaders in the packages, we can pinpoint which packages will need replacing, as the new stuff will not necessarily be compatible for all hardware, and so we'd need to avoid putting something with a higher SM requirement into a lower SM package.
User avatar
Invasion's
 
Posts: 3546
Joined: Fri Aug 18, 2006 6:09 pm

Post » Mon Oct 11, 2010 9:21 pm

@wrinklyninja:
This is what I think the only thing we know so far.
http://cs.elderscrolls.com/constwiki/index.php/SDP_Files

NOTE:
Here some info from my system / setup.

* NVIDIA GeForce 6200 uses package 4
* NVIDIA GeForce 8800 uses package 13

But I think they can all use package 19 without issues / let say I never had any issues.
Package 19 is what I believe the only one that fully supports 3.0 Shaders.

Allow use of 3.0 Shader:
Set bAllow30Shaders= from 0 to 1.

Force use of 3.0 Shader:
Change RenderInfo.txt file= from shader package 13 to shader package 19

or

Change shaderpackage019.sdp in to shaderpackage013.sdp by renaming.
User avatar
Jerry Jr. Ortiz
 
Posts: 3457
Joined: Fri Nov 23, 2007 12:39 pm

Post » Tue Oct 12, 2010 12:46 am

Sjors, does that actually work (or rephrase: do anything to the game)? Because I've never really noticed a difference visually when I changed shader packs.
User avatar
Symone Velez
 
Posts: 3434
Joined: Thu Sep 07, 2006 12:39 am

Post » Tue Oct 12, 2010 1:47 am

Sjors, does that actually work (or rephrase: do anything to the game)? Because I've never really noticed a difference visually when I changed shader packs.


Me too - I think I'll take a look at the shaders there and try to see what's different.
User avatar
Kelly Tomlinson
 
Posts: 3503
Joined: Sat Jul 08, 2006 11:57 pm

Post » Tue Oct 12, 2010 4:06 am

Do we know which shader packages are used with which hardware levels (shader model support levels, I presume)? That would be quite useful IMHO, and if we don't know, perhaps it would be a good idea to do a survey of people's RendererInfo.txt files to find out?

That way if we can actually replace shaders in the packages, we can pinpoint which packages will need replacing, as the new stuff will not necessarily be compatible for all hardware, and so we'd need to avoid putting something with a higher SM requirement into a lower SM package.
I'm fairly certain that I encountered the package picking code in one of the renderer's init routines. I'll enumerate them as soon as I get my rig fixed and sue Seagate.
User avatar
jodie
 
Posts: 3494
Joined: Wed Jun 14, 2006 8:42 pm

Post » Tue Oct 12, 2010 3:00 am

No sorry I never noticed any difference when changing the Shaders package to use. I think it is only the way the GPU does his thing in 2.0 or 3.0 Shader management. On the other side that could mean that package 19 is the only one that needs to be adapted when making changes to the Shaders.
User avatar
Franko AlVarado
 
Posts: 3473
Joined: Sun Nov 18, 2007 7:49 pm

Post » Tue Oct 12, 2010 2:05 am

It looks like your card uses the RAWZ depth buffer method, so you should use the fix or things won't work right. (not that they're working ATM)

The screen corruption reminds me of the sort of thing I'd get if I had drivers that weren't too good with what I was trying to play, or something like that. I know I recently got a similar thing with my Mobility HD 4650 when I upgraded to Ubuntu 10.04, which managed to break everything graphics related for me. :banghead: But anyway, it looks like your drivers don't approve of the way OBGEv2 is doing what it does.

Are you using the latest drivers?


I am using the latest drivers currently, but now that I think about it I had to roll back my drivers in the past to play Warsow (a game that uses cel shading) and the graphical glitches were very similar. I'm just going to assume its crappy nvidia drivers (not surprising) causing the issue. I'll see if I can't find some compatible ones.

Thanks for the help.
User avatar
Rachel Eloise Getoutofmyface
 
Posts: 3445
Joined: Mon Oct 09, 2006 5:20 pm

Post » Mon Oct 11, 2010 8:45 pm

Hmm... Cone Step Mapping is not liking Oblivion... Or vice versa.

Produces strange "glassy" stretching artifacts on the silhouette of the geometry, and the surface kind of morphs and ripples as you move around it. It could be due to any of the following: I'm not handling the input positions and tangent space rotation matrix right, the vectors need to be converted to world space then tangent space (but I lack access to the appropriate matrix), the algorithm wasn't designed with convex surfaces in mind, or the rock mesh in Oblivion has terrible UV mapping that these types of raytrace displacement mapping algorithms can't deal with.

I tried to use FX Composer to debug the shader, but it has some weird problem where the relief reverses on one side of the mesh, and I could not find the reason for it...

Anyways, here is the shader for PAR2002. It shades the rocks around the Imperial City Island when shadowing is enabled, but when dynamic lighting is not being applied. I, uh, haven't cleaned it up much...

Spoiler
//Vertex Shader Constantsrow_major float4x4 ModelViewProj : register(c0);float3 LightDirection[3] : register(c13);//How FogParam works://FarExtent = FogParam.x//NearExtent = FogParam.x - FogParam.yfloat4 FogParam : register(c23);float3 FogColor : register(c24);float4 EyePosition : register(c25);row_major float4x4 ShadowProj : register(c28);float4 ShadowProjData : register(c32);float4 ShadowProjTransform : register(c33);//Pixel Shader Constantsfloat4 AmbientColor : register(c1);float4 PSLightColor[4] : register(c2);float4 Toggles : register(c7);sampler2D BaseMap : register(s0);sampler2D NormalMap : register(s1);sampler2D ShadowMap : register(s6);sampler2D ShadowMaskMap : register(s7);struct vertexInput{    float4 pos       : POSITION;	float3 tangent   : TANGENT;	float3 binormal  : BINORMAL;    float3 normal    : NORMAL;    float2 texCoord  : TEXCOORD0;    float4 color     : COLOR0;};struct pixelInput{	float4 pos       : POSITION;	float4 color     : COLOR0;	float4 fogcolor  : COLOR1;	float2 texCoord  : TEXCOORD0;	float3 lightDir  : TEXCOORD1_centroid;	float3 cameraDir : TEXCOORD6_centroid;	float4 texCShad  : TEXCOORD7;};pixelInput PAR2002_vs(vertexInput IN){		pixelInput OUT;	float temp1;	float3 temp3;		//Transform light direction to tangent space.	float3x3 tangentMatrix = {IN.tangent,IN.binormal,IN.normal};	temp3 = mul(tangentMatrix, LightDirection[0]);		//Normalize the light direction and output.	OUT.lightDir = normalize(temp3);	//Find camera direction and normalize it.	temp3 = EyePosition.xyz - IN.pos.xyz;	temp3 = normalize(temp3);		//Transform the camera vector to tangent space.	temp3 = mul(tangentMatrix, temp3);	OUT.cameraDir = normalize(temp3);		float4 r0,r1,r2;	r1.w = dot(ShadowProj[3], IN.pos);	r1.y = r1.w * ShadowProjTransform.w;	r0.w = 1 / r1.y;	r1.x = dot(ShadowProj[0], IN.pos);	r1.y = dot(ShadowProj[1], IN.pos);	r2.xy = (r1.w * ShadowProjTransform.xy) + r1.xy;	OUT.texCShad.xy = r0.w * r2.xy;	r1.w = 1 / ShadowProjData.w;	r1.xy = r1.xy - ShadowProjData.xy;	OUT.texCShad.z = r1.x * r1.w;	OUT.texCShad.w = (r1.y * -r1.w) + 1.0;		//Transform position of the vertex into clip coordinates	float4 posCS = mul(ModelViewProj, IN.pos);	//...and output.	OUT.pos = posCS;		//Next, calculate the fog attenuation.	temp1 = (FogParam.x - length(posCS.xyz)) / FogParam.y;	temp1 = saturate(temp1);	//Encode the attenuation amount into the fog color's alpha channel.	OUT.fogcolor.rgb = FogColor;	OUT.fogcolor.a = 1.0 - temp1;	//And output the rest of our outputs.	OUT.texCoord = IN.texCoord;	OUT.color = IN.color;	return OUT;}// setup ray pos and dir based on view vector// and apply depth bias and depth factorvoid setup_ray(pixelInput IN, out float3 p, out float3 v){	float depth = 0.05;	const bool depth_bias = true;		p = float3(IN.texCoord,0);	v = normalize(IN.cameraDir);		v.z = abs(v.z);	if (depth_bias)	{		float db = 1.0-v.z;		db*=db;		//db*=db;		db=1.0-db*db;		//v.xy *= db;		depth *= db;	}		v.xy *= depth;}// ray intersect depth map using cone space leaping// depth value stored in alpha channel (black is at object surface)// and cone ratio stored in blue channelvoid ray_intersect_cone(inout float3 p, inout float3 v, float2 dx, float2 dy){	const int num_steps = 15;		float dist = length(v.xy);		[unroll] for( int i=0; i < num_steps; i++ )	{		float height = tex2Dgrad(BaseMap, p.xy, dx, dy).a;		height = saturate(height - p.z);				float cone_ratio = tex2Dgrad(NormalMap, p.xy, dx, dy).z;				p += v * (cone_ratio * height / (dist + cone_ratio));	}}float4 PAR2002_ps(pixelInput IN) : COLOR{	float temp1;	/*/Sample the displacement map, stored in the alpha channel of the diffuse texture.    temp1 = tex2D(BaseMap, IN.texCoord).a;	temp1 = (temp1 * 0.04) - 0.02;		//Calculate the parallax offset texture coordinates.	float2 parCoords = normalize(IN.cameraDir).xy;	parCoords = (parCoords * temp1) + IN.texCoord;	//*/		//return float4(IN.cameraDir.rgb, AmbientColor.a);		float3 p,v;	float2 dx,dy;	dx = ddx( IN.texCoord );	dy = ddy( IN.texCoord );	setup_ray(IN,p,v);	ray_intersect_cone(p,v,dx,dy);			//Sample the textures at the new coordinates.	float3 diffuse = tex2D(BaseMap, p.xy).rgb;	float3 temp3 = tex2D(NormalMap, p.xy).xyz;	temp3.z = sqrt( 1.0 - temp3.x*temp3.x - temp3.y*temp3.y );	//And sample the shadow maps as well.	float3 shadow = tex2D(ShadowMap, IN.texCShad.xy).xyz;	float3 mask = tex2D(ShadowMaskMap, IN.texCShad.zw).xyz;		//Calculate the lighting factor.	temp1 = saturate(dot(temp3, IN.lightDir));	//...and now the colors attributed from light.	temp3 = ((PSLightColor[0].rgb * temp1) * (((shadow - 1.0) * mask.x) + 1.0)) + AmbientColor.rgb;	//We'll assume anti-photons are not involved.	temp3 = max(temp3, 0.0);		//Should we mix the vertex color in, or use the raw diffuse color only?	diffuse = !Toggles.x ? diffuse : (diffuse * IN.color.rgb);	//Apply light to diffuse color.	diffuse = temp3 * diffuse;	//Calculate the color with fog taken into account.	temp3 = -diffuse + IN.fogcolor.rgb;		//Mix the fog color with the diffuse color based on the fog attenuation factor.	temp3 = (IN.fogcolor.a * temp3) + diffuse;	//Should we use the fogged color, or the lit diffuse only?	diffuse = !Toggles.y ? diffuse : temp3;	//Output the final pixel color.	return float4(diffuse.rgb, AmbientColor.a);}technique PAR2002{    pass Pass0    {		VertexShader = compile vs_2_0 PAR2002_vs();		PixelShader  = compile ps_3_0 PAR2002_ps();    }}


If you want to mess with it yourself, instructions are in the spoiler. It goes without saying, you can mess up your game bad if you aren't careful. :P
Spoiler
You can compile the effect file with the following command from your DirectX SDK command prompt (assuming a filename of "_PAR2002.fx"):
fxc /E:PAR2002 /T:fx_2_0 /Fc:_PAR2002.o _PAR2002.fx

Take the ASM code from "_PAR2002.o" and paste it into the SDP Editor, vertex shader in *.vso, pixel in *.pso, and then the CSM shader will be in the game.

You'll also need to produce the texture assets, which you can do with the program on http://forum.unity3d.com/viewtopic.php?p=307475. The cone map is produced from heightmap data from a .TGA texture with the height data in the alpha channel, and outputs the cone map into the blue channel. A program called CrazyBump produced far more detailed height maps from the normal maps in Oblivion than are provided by the game itself. Finally, when you make the changes to the final texture to use in the game, height map goes in the diffuse texture's alpha channel, and the cone map goes in the normal map's blue channel.

Anyways, looking at this shader, does anything immediately pop up as "odd"? I'm about sick of cone mapping, and frankly, it isn't very good for Oblivion due to the way it stores some of it's maps. Maybe I'll try a simpler Parallax Occlusion map. After all that volume cloud stuff, I should be an expert at that displacement technique.
User avatar
Emma Copeland
 
Posts: 3383
Joined: Sat Jul 01, 2006 12:37 am

Post » Tue Oct 12, 2010 7:16 am

Maybe I'll try a simpler Parallax Occlusion map. After all that volume cloud stuff, I should be an expert at that displacement technique.


He,he.. sounds promising, good luck HawkleyFox :wink_smile:
User avatar
C.L.U.T.C.H
 
Posts: 3385
Joined: Tue Aug 14, 2007 6:23 pm

Post » Mon Oct 11, 2010 7:35 pm

Update: Nailed it down! It's the VSync enabled causing the issue. Disabling it fix it. :facepalm:
(I kept it enabled in Oblivion because of some tearing.)

Update2:
Ok, bug reappeared later, while I had just installed some textures and a few esp's, and VSync was still off. Removed all of these, didn't fix, removed UOP, Bash and Obmm didn't fix it either.
Since I was waiting for SI by mail I dropped it.
Once I got SI I uninstalled everything then deleted every folder related to Oblivion or its utilities.

Installed Oblivion, SI, patched it to v1.2.0416. Installed OBSE, OBGEv2.
VSync was deactivated but the bug triggered.
This time, activating VSync fixed the issue. Then I tried to deactivate VSync, just to see, but the bug didn't come back.

So I dunno what causes the issue, but it seems playing with VSync, either on or off, fixes it when it arises.
I guess wrong flag/data is stored in the obse memory/save somehow and playing with VSync just cleanse it. What? Yes I'm completely uneducated on the subject, sorry to blatter. :P

If I ever come again across the issue and just playing with VSync fix it again, I'll update one last time. But since it worked for RebelMax too I have faith people with this issue will still be able to stick with OBGE. :)
User avatar
Guinevere Wood
 
Posts: 3368
Joined: Mon Dec 04, 2006 3:06 pm

Post » Mon Oct 11, 2010 10:43 pm

I wish you luck HawkleyFox.
User avatar
Emzy Baby!
 
Posts: 3416
Joined: Wed Oct 18, 2006 5:02 pm

Post » Mon Oct 11, 2010 7:17 pm

I wish you luck HawkleyFox.

I don't think luck is going to help. Two days of trying to solve this distortion problem, but nothing useful came out of it, and I still don't know what the problem is. Everything is in object space, and so long as everything is on the same coordinate system, this should work. I'm wondering if the interpolation of the eye direction vector across the surface between the vertex and pixel shader is causing the problem... Like the vector is getting horribly chewed up at vertex intersections, especially where the angles between polygons changes drastically.

Any suggestions?
User avatar
sarah simon-rogaume
 
Posts: 3383
Joined: Thu Mar 15, 2007 4:41 am

Post » Tue Oct 12, 2010 5:36 am

Has any yet tackle the horrible look of water when it meets the edge of the ground? The body of water looks great with all the mods out there to enhanced the beauty but, when it gets to the edge where water meets ground or what not looks like graphics from 1998. I'm not asking something like Crysis which would be asking too much but like Morrowind Graphic Extender(MGE) The water shader for Morrowind by Phal, I believe, has a soft water "edge" that looks great.
User avatar
le GraiN
 
Posts: 3436
Joined: Thu Mar 22, 2007 6:48 pm

Post » Tue Oct 12, 2010 8:21 am

I don't think luck is going to help. Two days of trying to solve this distortion problem, but nothing useful came out of it, and I still don't know what the problem is. Everything is in object space, and so long as everything is on the same coordinate system, this should work. I'm wondering if the interpolation of the eye direction vector across the surface between the vertex and pixel shader is causing the problem... Like the vector is getting horribly chewed up at vertex intersections, especially where the angles between polygons changes drastically.

Any suggestions?

Hawkley thanks for giving a shot at documenting Oblivion shaders. I think the problem could be different implementations need different texture modes. You know those R8G8B8A8 type of stuff. I don't know much about them. :) But to make a new algorithm to work I think you have to change the texture mode for normal map or height map defined by Oblivion, this involves hacking it. I think this is something scanti could help.

Regarding shadows, Oblivion has fake tree canopy shadows which won't be a problem. The one real method in Oblivion is "Percentage closer filtering", that is being used on NPCs by the look of it(Yes I can recognize shadows by the look of them, you have no idea how much time I spent on shadowing methods to find something that could work for Morrowind. :o).
User avatar
jess hughes
 
Posts: 3382
Joined: Tue Oct 24, 2006 8:10 pm

Post » Tue Oct 12, 2010 7:09 am

THis only works when I use OBSE loader: I can see the menu, but the effects don't work. When I use regular launcher, it freezes when I click on the key. I'm also missing shaderlist.txt

Any thoughts?
User avatar
Kim Kay
 
Posts: 3427
Joined: Fri Oct 13, 2006 10:45 am

Post » Mon Oct 11, 2010 9:19 pm

This indeed only works with OBSE, it is depended on a specific OBSE version, latest one.(Links in OP)

You can create your shaderlist.txt and put the names of shaders you want.
Godrays.fx


If you do it this way, you can't control effects in game. I recommend shaderlist.txt way for godrays shader since it is not compatible with plugin support. Be careful, don't double-enable a shader like this.
User avatar
nath
 
Posts: 3463
Joined: Mon Jan 22, 2007 5:34 am

PreviousNext

Return to IV - Oblivion