Advertisement

Projected texture, HLSL VS vs PS issue

Started by December 11, 2021 06:45 PM
1 comment, last by cozzie 3 years, 1 month 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

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