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:
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.

 » Tue Oct 12, 2010 5:36 am
  » Tue Oct 12, 2010 5:36 am 


















 
												



 ).
).												

