🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Projected texture, HLSL VS vs PS issue

Started by
1 comment, last by cozzie 2 years, 6 months ago

Hi all,

I've found out that I'm doing some projected lighting/texture calculations in the PS, which I should/can also do in the VS, so I've tried to redo it. But somehow the outcome is incorrect (visually). Any idea what I'm overlooking?

Old approach:

//VS
	[unroll]
	for(uint v=0;v<gPerScene.NrProjSpotLights;v++) vout.ViewPos[v] = GetViewPos(v, float4(vout.PosW, 1.0f));

// PS
	for(uint ps=0;ps<gPerObject.NrProjSpotLightsAff;++ps)
	{
		uint lightId = gPerObject.ProjSpotLightsAff[ps/4][ps%4];
		uint texIndex = gPerScene.LightSources[lightId].LengthOrProjTexIndex;
		projColor = gLightMap.Sample(gTexSampler, float3(GetProjectedUV(pin.ViewPos[gPerScene.LightSources[lightId].ProjMVPIndex], true), texIndex)).rgb;

		CalcSpotLightProj(gPerScene.LightSources[lightId], pin.PosW, toEye, lightSetup, projColor.rgb);
	}

New approach:

// VS
	[unroll]
	for(uint ps=0;ps<gPerObject.NrProjSpotLightsAff;++ps)
	{
		uint lightId = gPerObject.ProjSpotLightsAff[ps/4][ps%4];
		float4 tViewPos = GetViewPos(ps, float4(vout.PosW, 1.0f));
		vout.ProjPos[ps] = GetProjectedUV(tViewPos, true);
	}
	
// PS
	for(uint ps=0;ps<gPerObject.NrProjSpotLightsAff;++ps)
	{
		uint lightId = gPerObject.ProjSpotLightsAff[ps/4][ps%4];
		uint texIndex = gPerScene.LightSources[lightId].LengthOrProjTexIndex;
		
		float3 projColor = gLightMap.Sample(gTexSampler, float3(pin.ProjPos[ps], texIndex)).rgb;

		CalcSpotLightProj(gPerScene.LightSources[lightId], pin.PosW, toEye, lightSetup, projColor.rgb);
	}


Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

Update; found the issue, I was indexing the wrong MVP (model/view/projection) matrix per projected spot light. But besides this, I also understood that the perspective division and converting to normalized space need to be done in the PS, because of interpolation.

Tbh, this is too bad, because it means still most of the code has to be executed on the PS, which doesn't add up to what I read here:

Fixed code below. Any thoughts on why that book differs, let me know.

// VS

	[unroll]
	for(uint pt=0;pt<gPerObject.NrProjSpotLightsAff;++pt)
	{
		uint lightId = gPerObject.ProjSpotLightsAff[pt/4][pt%4];
		vout.ProjPos[pt] = mul(float4(vout.PosW, 1.0f), gPerScene.ProjSpotLightMVP[gPerScene.LightSources[lightId].ProjMVPIndex]).xyw;
	}

// PS

	for(uint ps=0;ps<gPerObject.NrProjSpotLightsAff;++ps)
	{
		uint lightId = gPerObject.ProjSpotLightsAff[ps/4][ps%4];
		uint texIndex = gPerScene.LightSources[lightId].LengthOrProjTexIndex;
		
		float2 projUV = pin.ProjPos[ps].xy / pin.ProjPos[ps].z;
		float2 projUVnorm = (projUV.xy + 1.0.xx) * float2(0.5, -0.5); // Convert to normalized space
				
		float3 projColor = gLightMap.Sample(gTexSampler, float3(projUVnorm, texIndex)).rgb;
		CalcSpotLight(gPerScene.LightSources[lightId], pin.PosW, toEye, lightSetup, projColor.rgb);
	}

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement