Advertisement

Screen Space Reflections and 1 year long headache

Started by July 07, 2017 11:33 PM
19 comments, last by WFP 7 years, 6 months ago

Hi, I'm developing a mod for Dirt 3, I'm using 3DMigoto as a shader injector. I've modified 100s of shaders, but I'm completely stuck at implementing Screen Space reflections for water shaders. I've got it almost working, but the reflection is floating whenever I change the camera elevation and there is a lot of misaligned elements floating around. It's been my number one headache trigger for the last year. I've tried everything. but no luck so far.

If there is anyone that could spare some time, take a look at the shader code and point me in the right direction I would be really grateful.

Here is a video showing my problem:

 

and the vertex and pixel shaders:


// water deep not moving VS

cbuffer _Globals : register(b0)
{
  float HDRRange : packoffset(c29);
  float4x4 model : packoffset(c30);
  float4x4 modelViewProj : packoffset(c34);
  float2 AmbientLightMapScale : packoffset(c38);
  float4x4 modelView : packoffset(c39);
  float4x4 prevViewProj : packoffset(c43);
  float4x4 prevModel : packoffset(c47);
  float4 normalParams1 : packoffset(c51);
  float4 normalParams2 : packoffset(c52);
  float4 normalParams3 : packoffset(c53);
  float4 normalParams4 : packoffset(c54);
  float timer : packoffset(c55);
  float blendValue : packoffset(c55.y);
  float4 specularParams : packoffset(c56);
  float4 waveParams : packoffset(c57);
  float4 interactiveParams2 : packoffset(c58);
  float4 interactiveParams3 : packoffset(c59);
  float4 interactiveParams4 : packoffset(c60);
}

cbuffer CameraParamsConstantBuffer : register(b3)
{
  float4x4 projection : packoffset(c0);
  float4x4 viewProjection : packoffset(c4);
  row_major float3x4 view : packoffset(c8);
  row_major float3x4 viewI : packoffset(c11);
  float3 eyePositionWS : packoffset(c14);
  float4x4 inverseProj : packoffset(c15);
  bool leftEye : packoffset(c19);
  bool padding3[3] : packoffset(c20);
}

cbuffer PerFrameConstantBuffer : register(b1)
{
  float4 colorBufferEncodingParams : packoffset(c0);
  float4 envMapEncodingParams : packoffset(c1);
  float4 velocityEncodingParams : packoffset(c2);
  float4 snowEffectsParam2 : packoffset(c3);
  float4 sunDirectionAndTime : packoffset(c4);
  float4 sunColour : packoffset(c5);
  float4 skylightColour : packoffset(c6);
  float4 ambientOcclusionScales : packoffset(c7);
  float4 backlightColour : packoffset(c8);
  float4 specularScales : packoffset(c9);
  float3 specularDirection : packoffset(c10);
  float4 specularColourAndMultiplier : packoffset(c11);
  float4 fogColour : packoffset(c12);
  float4 fogParams : packoffset(c13);
  float4 hazeParams : packoffset(c14);
  float4 hazeParams2 : packoffset(c15);
  float4 nightLightmapParam1 : packoffset(c16);
  float4 nightLightmapParam2 : packoffset(c17);
  float4 wetLightingParam : packoffset(c18);
  float4 snowEffectsParam : packoffset(c19);
  float4 ambientColour : packoffset(c20);
  float4 shadowBlend : packoffset(c21);
  float4 maskParams : packoffset(c22);
  float4 deferredSpecularParams : packoffset(c23);
}



// 3Dmigoto declarations
#define cmp -
Texture1D<float4> IniParams : register(t120);
Texture2D<float4> StereoParams : register(t125);

void main( 
  float4 v0 : POSITION0,
  float3 v1 : NORMAL0,
  float3 v2 : TANGENT0,
  float3 v3 : BINORMAL0,
  float4 v4 : COLOR0,
  out float4 o0 : SV_Position0,
  out float4 o1 : COLOR1,
  out float4 o2 : TEXCOORD0,
  out float4 o3 : TEXCOORD1,
  out float4 o4 : TEXCOORD2,
  out float4 o5 : TEXCOORD3,
  out float4 o6 : TEXCOORD4,
  out float4 o7 : TEXCOORD5,
  out float4 o8 : TEXCOORD6,
  out float4 o9 : TEXCOORD7,
	out float4 o10 : TEXCOORD8, //viewPosition
	out float3 o11 : TEXCOORD9, //viewNormal
	out float3 o12 : TEXCOORD10) //csPos
{
  float4 r0,r1,r2,r3,r4,r5;
  uint4 bitmask, uiDest;
  float4 fDest;

  //-- original game shader code
  r0.xyzw = modelViewProj._m01_m11_m21_m31 * v0.yyyy;
  r0.xyzw = modelViewProj._m00_m10_m20_m30 * v0.xxxx + r0.xyzw;
  r0.xyzw = modelViewProj._m02_m12_m22_m32 * v0.zzzz + r0.xyzw;
  r0.xyzw = modelViewProj._m03_m13_m23_m33 * v0.wwww + r0.xyzw;
  o0.xyzw = r0.xyzw;
  r1.xyz = model._m01_m11_m21 * v0.yyy;
  r1.xyz = model._m00_m10_m20 * v0.xxx + r1.xyz;
  r1.xyz = model._m02_m12_m22 * v0.zzz + r1.xyz;
  r1.xyz = model._m03_m13_m23 * v0.www + r1.xyz;
  r2.xyz = -eyePositionWS.xyz + r1.xyz;
  r1.w = dot(r2.xyz, r2.xyz);
  r1.w = sqrt(r1.w);
  r2.xyz = r2.xyz / r1.www;
  r2.x = saturate(dot(r2.xyz, sunDirectionAndTime.xyz));
  r2.x = log2(r2.x);
  r2.x = hazeParams2.w * r2.x;
  r2.x = exp2(r2.x);
  r2.yzw = hazeParams2.xyz + -hazeParams.xyz;
  r2.xyz = r2.xxx * r2.yzw + hazeParams.xyz;
  r3.x = 1 / fogParams.z;
  r3.x = -r3.x + r1.w;
  r1.w = -30 + r1.w;
  r1.w = saturate(fogParams.z * r1.w);
  r4.w = fogParams.w * r1.w;
  r1.w = max(0, r3.x);
  r1.w = hazeParams.w * r1.w;
  r1.w = 1.44269502 * r1.w;
  r1.w = exp2(r1.w);
  r2.w = 1 + -r1.w;
  r4.xyz = fogColour.xyz;
  r3.xyzw = -r4.xyzw + r2.xyzw;
  r2.xyzw = r2.wwww * r3.xyzw + r4.xyzw;
  o1.xyz = r2.xyz * r2.www;
  o1.w = 1 + -r2.w;
  r2.xyz = model._m01_m11_m21 * v1.yyy;
  r2.xyz = model._m00_m10_m20 * v1.xxx + r2.xyz;
  r2.xyz = model._m02_m12_m22 * v1.zzz + r2.xyz;
  r1.w = dot(r2.xyz, r2.xyz);
  r1.w = rsqrt(r1.w);
  r2.xyz = r2.xyz * r1.www;
  o2.xyz = r2.xyz;
  r3.xy = interactiveParams2.wz * float2(1,-1);
  r3.xy = interactiveParams4.xx * r3.xy;
  r1.w = timer + 0.5;
  r3.xy = r1.ww * r3.xy;
  r3.zw = float2(0.0500000007,0.0500000007) * r1.xz;
  r3.xy = r3.zw * interactiveParams4.xx + r3.xy;
  o2.w = r3.x;
  o3.w = r3.y;
  r4.xyz = model._m01_m11_m21 * v2.yyy;
  r4.xyz = model._m00_m10_m20 * v2.xxx + r4.xyz;
  r4.xyz = model._m02_m12_m22 * v2.zzz + r4.xyz;
  r1.w = dot(r4.xyz, r4.xyz);
  r1.w = rsqrt(r1.w);
  r4.xyz = r4.xyz * r1.www;
  o3.xyz = r4.xyz;
  r5.xyz = r4.yzx * r2.zxy;
  r2.xyz = r2.yzx * r4.zxy + -r5.xyz;
  r1.w = dot(r2.xyz, r2.xyz);
  r1.w = rsqrt(r1.w);
  o4.xyz = r2.xyz * r1.www;
  o4.w = 0;
  r2.xyzw = normalParams4.xyzw + r1.xzxz;
  o7.xyz = r1.xyz;
  o7.w = 0;
  r1.xyzw = normalParams2.xxyy * r2.xyzw;
  r1.xyzw = specularParams.wwww * r1.xyzw;
  o5.xyzw = float4(0.0500000007,0.0500000007,0.0500000007,0.0500000007) * r1.xyzw;
  r1.xy = specularParams.ww * r3.zw;
  r1.zw = waveParams.xy * timer;
  r1.zw = normalParams1.zz * r1.zw;
  o6.xy = r1.xy * normalParams2.zz + r1.zw;
  r1.xy = interactiveParams3.ww * interactiveParams2.zw;
  r1.xy = timer * r1.xy;
  o6.zw = r3.zw * interactiveParams3.ww + r1.xy;
  o8.x = dot(float2(0.5,0.5), r0.xw);
  o8.y = dot(float2(0.5,0.5), r0.yw);
  o8.zw = r0.zw;
  r0.x = modelView._m21 * v0.y;
  r0.x = modelView._m20 * v0.x + r0.x;
  r0.x = modelView._m22 * v0.z + r0.x;
  o9.z = modelView._m23 + r0.x;
  o9.xyw = float3(0,0,1);

  
	//-- output values for SSR
	o10 = mul(modelView, v0.xyzw); //viewPosition
	o11 = mul((float3x3)modelView, v1.xyz); //viewNormal
	float4 position = mul(modelViewProj, float4(v0.xyzw));
	o12 = position.xyz / position.w; //csPosition
	
	
  return;
}

 


// water deep not moving PS

cbuffer _Globals : register(b0)
{
	float HDRRange : packoffset(c29);
	float2 AmbientLightMapScale : packoffset(c29.y);
	float4 normalParams1 : packoffset(c30);
	float4 normalParams2 : packoffset(c31);
	float4 normalParams3 : packoffset(c32);
	float4 normalParams4 : packoffset(c33);
	float timer : packoffset(c34);
	float4 screenProj : packoffset(c35);
	float4 fresnelParams : packoffset(c36);
	float4 horizonColour : packoffset(c37);
	float4 nadirColour : packoffset(c38);
	float4 interactiveParams1 : packoffset(c39);
	float4 interactiveParams5 : packoffset(c40);
	float4 waterShadowBlend : packoffset(c41);
	float4 decodeParam : packoffset(c42);
	float4 sparkleParams : packoffset(c43);
	float4 sparkleParams2 : packoffset(c44);
	float blendValue : packoffset(c45);
	float4 specularParams : packoffset(c46);
	float4 waveParams : packoffset(c47);
	float4 interactiveParams2 : packoffset(c48);
	float4 interactiveParams3 : packoffset(c49);
	float4 interactiveParams4 : packoffset(c50);
}

cbuffer RenderTargetConstantBuffer : register(b2)
{
	float4 viewportDimensions : packoffset(c0);
}

cbuffer CameraParamsConstantBuffer : register(b3)
{
	float4x4 projection : packoffset(c0);
	float4x4 viewProjection : packoffset(c4);
	row_major float3x4 view : packoffset(c8);
	row_major float3x4 viewI : packoffset(c11);
	float3 eyePositionWS : packoffset(c14);
	float4x4 inverseProj : packoffset(c15);
	bool leftEye : packoffset(c19);
	bool padding3[3] : packoffset(c20);
}

cbuffer PerFrameConstantBuffer : register(b1)
{
	float4 colorBufferEncodingParams : packoffset(c0);
	float4 envMapEncodingParams : packoffset(c1);
	float4 velocityEncodingParams : packoffset(c2);
	float4 snowEffectsParam2 : packoffset(c3);
	float4 sunDirectionAndTime : packoffset(c4);
	float4 sunColour : packoffset(c5);
	float4 skylightColour : packoffset(c6);
	float4 ambientOcclusionScales : packoffset(c7);
	float4 backlightColour : packoffset(c8);
	float4 specularScales : packoffset(c9);
	float3 specularDirection : packoffset(c10);
	float4 specularColourAndMultiplier : packoffset(c11);
	float4 fogColour : packoffset(c12);
	float4 fogParams : packoffset(c13);
	float4 hazeParams : packoffset(c14);
	float4 hazeParams2 : packoffset(c15);
	float4 nightLightmapParam1 : packoffset(c16);
	float4 nightLightmapParam2 : packoffset(c17);
	float4 wetLightingParam : packoffset(c18);
	float4 snowEffectsParam : packoffset(c19);
	float4 ambientColour : packoffset(c20);
	float4 shadowBlend : packoffset(c21);
	float4 maskParams : packoffset(c22);
	float4 deferredSpecularParams : packoffset(c23);
}

SamplerState TNormalMap_s : register(s0);
SamplerState DepthMap_s : register(s1);
SamplerState ReflectionMap_s : register(s2);
SamplerState ReflectionMap2_s : register(s3);
SamplerState TMaskMap_s : register(s4);
SamplerState TShadowMask_s : register(s10);
Texture2D<float4> DepthMap : register(t0);
Texture2D<float4> TNormalMap : register(t1);
Texture2D<float4> ReflectionMap : register(t2);
Texture2D<float4> ReflectionMap2 : register(t3);
Texture2D<float4> TShadowMask : register(t4);
Texture2D<float4> TMaskMap : register(t5);



//-- SSR buffers
Texture2D<float> DepthBuffer : register(t100);
SamplerState DepthBuffer_s : register(s11);
Texture2D<float4> HDRTex : register(t101);
SamplerState HDRTex_s : register(s12);



//-- 3Dmigoto declarations
#define cmp -
Texture1D<float4> IniParams : register(t120);
Texture2D<float4> StereoParams : register(t125);



//-- SSR Constants
static float2 cb_depthBufferSize; // dimensions of the z-buffer
static const float cb_zThickness = 1; // thickness to ascribe to each pixel in the depth buffer
//static const float cb_nearPlaneZ = 0.6; // the camera's near z plane

static const float cb_stride = 1; // Step in horizontal or vertical pixels between samples. This is a float
// because integer math is slow on GPUs, but should be set to an integer >= 1.
static float cb_maxSteps; // Maximum number of iterations. Higher gives better images but may be slow.
//static const float cb_maxDistance = 10000; // Maximum camera-space distance to trace before returning a miss.
static const float cb_strideZCutoff = 0; // More distant pixels are smaller in screen space. This value tells at what point to
// start relaxing the stride to give higher quality reflections for objects far from
// the camera.

static const float cb_numMips = 1; // the number of mip levels in the convolved color buffer
static const float cb_fadeStart = 0; // determines where to start screen edge fading of effect
static const float cb_fadeEnd = 0; // determines where to end screen edge fading of effect
static const float cb_sslr_padding0 = 0; // padding for alignment



//--SSR Functions
float linearizeDepth(float depth)
{
	float4 tmp = mul(inverseProj, float4(0, 0, depth, 1));
	return mul(projection, tmp / tmp.w).w;
	//float n = cb_nearPlaneZ; // camera z near
	//float f = cb_maxDistance; // camera z far
	//float z = depth;
	//return (2.0 * n) / (f + n - z * (f - n));
}



float distanceSquared(float2 a, float2 b)
{
	a -= b;
	return dot(a, a);
}
 
 
 
bool intersectsDepthBuffer(float z, float minZ, float maxZ)
{
	/*
	* Based on how far away from the camera the depth is,
	* adding a bit of extra thickness can help improve some
	* artifacts. Driving this value up too high can cause
	* artifacts of its own.
	*/
	float depthScale = min(1.0f, z * cb_strideZCutoff);
	z += cb_zThickness + lerp(0.0f, 2.0f, depthScale);
	return (maxZ >= z) && (minZ - cb_zThickness <= z);
}
 
 
 
void swap(inout float a, inout float b)
{
	float t = a;
	a = b;
	b = t;
}
 
 
 
float linearDepthTexelFetch(int2 hitPixel)
{
	// Load returns 0 for any value accessed out of bounds
	return linearizeDepth(DepthBuffer.Load(int3(hitPixel, 0)).r);
}




bool traceScreenSpaceRay(
	// Camera-space ray origin, which must be within the view volume
	float3 csOrig,
	// Unit length camera-space ray direction
	float3 csDir,
	// Number between 0 and 1 for how far to bump the ray in stride units
	// to conceal banding artifacts. Not needed if stride == 1.
	float jitter,
	// Pixel coordinates of the first intersection with the scene
	out float2 hitPixel,
	// Camera space location of the ray hit
	out float3 hitPoint)
{
	float near = linearizeDepth(0);
	float far = linearizeDepth(1);
	// Clip to the near plane
	float rayLength = ((csOrig.z + csDir.z * far) > -near) ?
	(-near - csOrig.z) / csDir.z : far;
	float3 csEndPoint = csOrig + csDir * rayLength;

	
	// Project into homogeneous clip space
	float4 H0 = mul(projection, float4(csOrig, 1.0f));
	float4 H1 = mul(projection, float4(csEndPoint, 1.0f));

	float k0 = 1.0f / H0.w;
	float k1 = 1.0f / H1.w;
	
	// The interpolated homogeneous version of the camera-space points
	float3 Q0 = csOrig * k0;
	float3 Q1 = csEndPoint * k1;
	
	// Screen-space endpoints
	float2 P0 = H0.xy * k0;
	float2 P1 = H1.xy * k1;

	// Scale to pixels:
	P0 = (P0 * float2(0.5, -0.5) + 0.5) * cb_depthBufferSize;
	P1 = (P1 * float2(0.5, -0.5) + 0.5) * cb_depthBufferSize;

	
	// If the line is degenerate, make it cover at least one pixel
	// to avoid handling zero-pixel extent as a special case later
	P1 += (distanceSquared(P0, P1) < 0.0001f) ? float2(0.01f, 0.01f) : 0.0f;
	float2 delta = P1 - P0;
	
	// Permute so that the primary iteration is in x to collapse
	// all quadrant-specific DDA cases later
	bool permute = false;
	if(abs(delta.x) < abs(delta.y))
	{
		// This is a more-vertical line
		permute = true;
		delta = delta.yx;
		P0 = P0.yx;
		P1 = P1.yx;
	}
	
	float stepDir = sign(delta.x);
	float invdx = stepDir / delta.x;
	
	// Track the derivatives of Q and k
	float3 dQ = (Q1 - Q0) * invdx;
	float dk = (k1 - k0) * invdx;
	float2 dP = float2(stepDir, delta.y * invdx);
	
	// Scale derivatives by the desired pixel stride and then
	// offset the starting values by the jitter fraction
	float strideScale = 1.0f - min(1.0f, csOrig.z * cb_strideZCutoff);
	float stride = 1.0f + strideScale * cb_stride;
	dP *= stride;
	dQ *= stride;
	dk *= stride;
	
	P0 += dP * jitter;
	Q0 += dQ * jitter;
	k0 += dk * jitter;

	// Slide P from P0 to P1, (now-homogeneous) Q from Q0 to Q1, k from k0 to k1
	float4 PQk = float4(P0, Q0.z, k0);
	float4 dPQk = float4(dP, dQ.z, dk);
	float3 Q = Q0; 

	float end = P1.x * stepDir;
	
	float stepCount = 0.0f;
	float prevZMaxEstimate = csOrig.z;
	float rayZMin = prevZMaxEstimate;
	float rayZMax = prevZMaxEstimate;
	float sceneZMax = rayZMax + 100.0f;

	for(;
		((PQk.x * stepDir) <= end) && (stepCount < cb_maxSteps) &&
		!intersectsDepthBuffer(sceneZMax, rayZMin, rayZMax) &&
		(sceneZMax != 0.0f); ++stepCount)
		{
			rayZMin = prevZMaxEstimate;
			rayZMax = (dPQk.z * 0.5f + PQk.z) / (dPQk.w * 0.5f + PQk.w);
			prevZMaxEstimate = rayZMax;
			if(rayZMin > rayZMax)
			{
				swap(rayZMin, rayZMax);
			}
			hitPixel = permute ? PQk.yx : PQk.xy;
			// You may need hitPixel.y = depthBufferSize.y - hitPixel.y; here if your vertical axis
			// is different than ours in screen space
			sceneZMax = linearDepthTexelFetch(int2(hitPixel));
			PQk += dPQk;
		}
		// Advance Q based on the number of steps
		Q.xy += dQ.xy * stepCount;
		hitPoint = Q * (1.0f / PQk.w);
		return intersectsDepthBuffer(sceneZMax, rayZMin, rayZMax);
}



//-- Main stripped from all code, only planar reflection is displayed
void main( 
	float4 v0 : SV_Position0,
	float4 v1 : COLOR1,
	float4 v2 : TEXCOORD0,
	float4 v3 : TEXCOORD1,
	float4 v4 : TEXCOORD2,
	linear centroid float4 v5 : TEXCOORD3,
	linear centroid float4 v6 : TEXCOORD4,
	linear centroid float4 v7 : TEXCOORD5,
	float4 v8 : TEXCOORD6,
	linear centroid float4 v9 : TEXCOORD7,
	out float4 o0 : SV_Target0,
	float4 viewPosition : TEXCOORD8,
	float3 normalVS : TEXCOORD9,
	float3 csPosition : TEXCOORD10)
{
	float4 stereo = StereoParams.Load(0);
	float separation = stereo.x * (leftEye ? -1 : 1);
	float convergence = stereo.y;
	viewPosition.x += separation * convergence * inverseProj._m00;

	DepthBuffer.GetDimensions(cb_depthBufferSize.x, cb_depthBufferSize.y);
	cb_maxSteps = cb_depthBufferSize.y;

	float2 hitPixel = float2(0.0f, 0.0f);
	float3 hitPoint = float3(0.0f, 0.0f, 0.0f);

	int3 loadIndices = int3(v0.xy, 0);
	float depth = DepthBuffer.Load(loadIndices);

	float3 rayOriginVS =	viewPosition * linearizeDepth(depth);
	float3 toPositionVS = normalize(rayOriginVS);
	float3 rayDirectionVS = normalize(reflect(-toPositionVS, normalVS));

	// output rDotV to the alpha channel for use in determining how much to fade the ray
	float rDotV = dot(rayDirectionVS, toPositionVS);

	float jitter = cb_stride > 1.0f ? float(int(v0.x + v0.y) & 1) * 0.5f : 0.0f;
	bool intersection = traceScreenSpaceRay(-rayOriginVS, -rayDirectionVS, jitter, hitPixel, hitPoint);
	if (intersection != false) o0.xyz = HDRTex.Load(float3(hitPixel, 0));
	else o0.xyz = float3(0,0,0);
	o0.w=1;
	return;
}

 

The black edges look like you're hitting out of screenspace without falling back on any other reflection, such as whatever it is the normal game does. 

Advertisement

I'm not concerned about the black edges, as I haven't implemented the blending with the cubemap yet. I need to figure out what I'm doing wrong with the depthbuffer calculations, so the elements are floating and the reflection is not aligned properly.

Just a hunch,

The way I make reflections in our game is by using a skewed front clip plane, that alters the depth values written to the depth buffer. Can you verify that the depth values you are reading are the right ones?

Henning

The depth buffer is complete, but I'm not entirely sure if I linearize it properly. When I subtract the nearplane "linearizeDepth(0)" from the depth value in the 16th line from the bottom like so:


float depth = DepthBuffer.Load(loadIndices) - linearizeDepth(0);

the reflections are almost perfect, but the nearplane is still off.

dirt3_game_2017_07_12_12_38_23_272.png

Advertisement
26 minutes ago, semler said:

Just a hunch,

The way I make reflections in our game is by using a skewed front clip plane, that alters the depth values written to the depth buffer. Can you verify that the depth values you are reading are the right ones?

Henning

Could you elaborate in a few more details about your SSR function? would it work in the situation like mine where you have floating rocks on the lake's surface?

The DB is one frame late as I take it after the lake surface was drawn, so I do not sample the lake's bottom.

At first glance, this seems incorrect to me:


float3 rayOriginVS =	viewPosition * linearizeDepth(depth);

Can you tell me what value you're storing in viewPosition?

In my implementation, that line describes a ray from the camera projected all the way to the far clip plane.

In the vertex shader:


// project the view-space position to the far plane
vertexOut.viewRay = float3(posV.xy / posV.z, 1.0f);

Using that multiplied by linearized depth lets you reconstruct view-space position in the pixel shader, which is what you need for rayOriginVS.

MJP's entire series is a great resource on reconstructing position from depth, but the last post, https://mynameismjp.wordpress.com/2010/09/05/position-from-depth-3/, is closest to what I use for most cases.

I don't own/haven't played the game, so this is strictly a guess, but to me it looks like the rocks (as well as the boat and fisherman in it) are billboarded sprites.  If that's the case, there's a good chance they aren't even being written to the depth buffer, which means there would be nothing for the ray-tracing step to detect.  Are you able to pull a linearized version of the depth buffer that shows what is and isn't actually stored in it?  That could be really helpful for debugging :).

P.S.  I think you might be the same person that was asking about this (Dirt 3 mod + 3DMigoto) on my blog post on glossy reflections.  Sorry I never got back to you - to be completely honest, I got really busy with a few things around then and forgot over time.

Yes, that's me. Thank you for noticing me :) I've been trying to get it working and spammed every possible place to find someone with more experience in that matter.

You may be right about the input values, here are the output values from the vertex shader:


	o10 = mul(modelView, v0.xyzw); //viewPosition
	o11 = mul((float3x3)modelView, v1.xyz); //viewNormal
	float4 position = mul(modelViewProj, float4(v0.xyzw));
	o12 = position.xyz / position.w; //csPosition

I've tried o12 as a ray but it's not working at all.

 

v0 is the   float4 v0 : POSITION0

boat and the rocks are 3d objects, they just do not appear, as everything is shifting gradualy upwards propirtionaly to the distance from the camera.

This topic is closed to new replies.

Advertisement