Jump to content

[Help] Distorted Rendertargets? How to fix?


Ceeser

Recommended Posts

Hey, I'm currently working on a minimap / radar that shows objects.

And now I noticed that somehow my renderTargets are distorted/warped if drawn at objects rotation, example:
spacer.png

The objects that are at 0° rotation look straight, but the objects at 24° rotation are wierdly distorted.
Ingame View of that: (to make the actual straight line - that should be visible on the radar - more clear I changed the color of the shades) spacer.png

I hope you get my point.
It shouldn't even be possible, that a renderTarget (the shade-image get created and colored by the script) gets bend like that..
There is no parameter like for distortion in dxDrawImage, wtf
.spacer.png

These yellow lines is how it should get displayed - in a straight line, or am I dumb?
Is there any reason why that happens and/or any way I could fix it?

To the code:
tl;dr: There is litterally nothing that could cause the effect visible on the radar
 

Spoiler

function getFilteredObjects()
	for _, object in pairs(getElementsByType("object")) do
		local iModel = getElementModel(object);

		if (tblSupportedModelIDs[iModel]) then -- Only create renderTargets for supported models
			if (not tblModelValues[iModel]) then -- Prevent dublications
				tblModelValues[iModel] = getModelValues(object);
			end
		end
	end
end

function getModelValues(uObject)
	local iMinX, iMinY, iMinZ, iMaxX, iMaxY, iMaxZ = getElementBoundingBox(uObject);

	local iSizeX, iSizeY = iMaxX - iMinX, iMaxY - iMinY;
	local uRenderTarget = dxCreateRenderTarget(iSizeX, iSizeY);

	dxSetBlendMode("modulate_add");
	dxSetRenderTarget(uRenderTarget);
	dxDrawRectangle(0, 0, iSizeX, iSizeY);
	dxSetRenderTarget();
	dxSetBlendMode("blend");

	return {img = uRenderTarget, sizeX = iSizeX, sizeY = iSizeY};
end

function renderFilteredObjects(uObject)
	dxSetBlendMode("modulate_add");
	dxSetRenderTarget(Radar.renderTarget);

	for model, modelObjects in pairs(tblFilteredObjects) do
		for _, object in pairs(modelObjects) do
			local posX, posY = convertCoordinatesToPixels(object.posX, object.posY);
			local sizeX = tblModelValues[model].sizeX;
			local sizeY = tblModelValues[model].sizeY;

			dxDrawImage(posX - sizeX / 2, posY + sizeY / 2, sizeX, sizeY, tblModelValues[model].img, object.rotZ, 0, 0, tocolor(0, 0, 0, 64)); -- Shadow
			dxDrawImage(posX - sizeX / 2 + 1, posY + sizeY / 2 + 1, sizeX - 2, sizeY - 2, tblModelValues[model].img, object.rotZ, 0, 0, tblSupportedModelIDs[model]); -- Object
		end
	end

	dxSetRenderTarget();
	dxSetBlendMode("blend");
end

function renderRadar()
	local posX, posY = getElementPosition(localPlayer);
	local uCamTarget = getCameraTarget();

	posX = 0.5 - (Map.maxX + iRenderTargetExtraSpace - posX) / Map.sizeX;
	posY = 0.5 - (Map.maxY + iRenderTargetExtraSpace - posY - 2.5) / Map.sizeY;

	if (not uCamTarget) then
		uCamTarget = localPlayer;
	end

	if (uCamTarget) then	
		local _, _, iCameraRotation = getElementRotation(getCamera());
		local _, _, iVehicleRotation = getElementRotation(uCamTarget);

		dxSetShaderValue(uMaskShader, "gUVPosition", posX, posY);
		dxSetShaderValue(uMaskShader, "gUVScale", 1 / iRadarZoom, 1 / iRadarZoom);
		dxSetShaderValue(uMaskShader, "gUVRotAngle", math.rad(iCameraRotation + 180));

		dxDrawImage(Radar.posX + Radar.size, Radar.posY, -Radar.size, Radar.size, uMaskShader);
		dxDrawImage(Radar.posX + Radar.size / 2 - iPlayerSize / 2, Radar.posY + Radar.size / 2 - iPlayerSize / 2, iPlayerSize, iPlayerSize, "images/player.png", iCameraRotation - iVehicleRotation);
	end
end
addEventHandler("onClientRender", root, renderRadar);

 

 

Edited by Ceeser
Link to comment
  • Moderators
23 minutes ago, Ceeser said:

Is there any reason why that happens and/or any way I could fix it?

Are the images drawn from path? (not recommended: line 68)

If not, what are the arguments you use for the textures?

Link to comment

Yes, the player.png gets drawn from that path (line 68) - Should I create a texture for it too to speed up drawing?
But that's anyways the only radar blip, for the player (and this is fine)^^

Everything else gets created by the script (and shaped by the mask shader which gets drawn - line 67)
But the problem is even before that, the renderTargets of the objects that get rendered are somehow "bend" if the objects rotation isn't "straight" like 0°, 90°, etc. (line 39 and 40, "object.rotZ").

The base rotation of the renderTargets are also fine, but the corners are not 90° which doesnt make much sense since renderTargets can only have 90° corners..
If the Object has a rotation of (like in the screen) 24° or sth the renderTarget basically gets rendered like this:
spacer.png
..and that doesn't make any sense to me.

Link to comment
  • Moderators
2 hours ago, Ceeser said:

But the problem is even before that, the renderTargets of the objects that get rendered are somehow "bend" if the objects rotation isn't "straight" like 0°, 90°, etc. (line 39 and 40, "object.rotZ").

Did you try to capture the pixels, transfer them to a new texture (and maybe enable mipmaps if needed)? (do not do this every frame)

That way you wouldn't lose your rendertargets either after minimizing etc.

Edited by IIYAMA
Link to comment

I've kept experimenting around, also tried out the texture, but the problem still exists :c

Here another example screenshot of the (scaled) map + ingame view:
8YWVyf5.png

If you want I could send you the whole resource so you could take a look yourself :D
I'm really out of ideas.

@IIYAMA

Link to comment
  • Moderators
43 minutes ago, Ceeser said:

I'm really out of ideas.

You are not the only person that tried to create this.

For my projectile I used the basic function: https://wiki.multitheftauto.com/wiki/DxDrawLine

Which did indeed work. Created nice quality lines.

 

While doing this project there was 1 wall I hit with project that ended up making it a failure. The map-draw resource required heavily on realtime updates for all 3 dimensions: x, y and z.

Depending on the height of the camera, the order and opacity for each element was adjusted. This was required because the maps did also have multiple (building) floor.

Which ended up in too many draws on a single rendertarget. While my computer could easily handle it, that was not for everybody the case.

 

This was more or less the :~ty math I used:

Spoiler

	local x0, y0, z0, x1, y1, z1 = getElementBoundingBox ( object )
	if x0 and x1 then
		local originalBoundingBoxSize = getDistanceBetweenPoints2D(x0, y0, x1, y1)
		if originalBoundingBoxSize > 1.5 then
			local matrix = getElementMatrix ( object )  -- Get the matrix

			
			local startX, startY, minZ = getPositionFromMatrixOffset(matrix, x0, 0, z0)
			local endX, endY, maxZ = getPositionFromMatrixOffset(matrix, x1, 0, z1)
			local objectX, objectY, objectZ = getElementPosition(object)
			
			local startX2, startY2, _ = getPositionFromMatrixOffset(matrix, 0, y0, z0)
			local endX2, endY2, _ = getPositionFromMatrixOffset(matrix, 0, y1, z1)
			
			local newObjectData = {
				element = object,
				position = {objectX, objectY, objectZ},
				renderPosition = {startX, startY, minZ, endX, endY, maxZ},
				originalBoundingBoxSize = originalBoundingBoxSize,
				boundingBoxSize = math.max(getDistanceBetweenPoints2D(startX2, startY2, endX2, endY2), 2) -- boundingBoxSize
			}
    -- etc.

 

 

 

  • Thanks 1
Link to comment

I found, what's causing the problem I have.
But idk how to write shaders, so not why it’s doing that..

Im using the HUD Mask Shader of the MTA Wiki and somehow that shader causes the distortion.

The Yellow lines represent my viewing angle and the yellow circle is the section visible on the radar.
I drew the renderTarget (as source) on fullscreen and on the left side is the radar.

spacer.png

As you can see on the RenderTarget - Yellow Circle all lines are straight as wanted.
On the radar the shades are shifted like a dxDrawRectangle rectangle cant even look.
The radar gets drawn through the shader, so the shader has to do that to the renderTarget.


Is there any other Mask Shader I could try?

Edited by Ceeser
inserted image
Link to comment
  • Moderators
1 hour ago, Ceeser said:

Is there any other Mask Shader I could try?

Hmm, not sure. I haven't seen another one.

 


 

Instead of this, you can also rotate this:

		dxDrawImage(Radar.posX + Radar.size, Radar.posY, -Radar.size, Radar.size, uMaskShader);

Instead of:

dxSetShaderValue(uMaskShader, "gUVRotAngle", math.rad(iCameraRotation + 180));

 


 

You could also try dxSetBlendMode ("overwrite"). I am not sure if it will overwrite the color or applying negative result and therefore doing the same as an inverted mask. > Never tried that before.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...