Jump to content

Green screen shader


Recommended Posts

Hello!

So, I would like to make something like a green screen shader, so I can take screenshots of players and vehicles, but I have never created or done shaders, my HLSL knowledge is 0, I don't know how shaders work. The effect I would like to reach looks like this (image taken from google):

FDexu3a.png

So how I would like my script to work: when I start the resource, there would be a colored texture applied to everything, except the local player, or if he/she is sitting in a vehicle then remove the shader from the vehicle as well. Like a green pane would appear behind the characters/vehicles, but I keep failing with my script. I don't know what would be the most efficient way to do this, I was thinking about this, but there might be other, easier methods as well, but I can't think about anything else.

As I said before, I'm not experienced with shaders at all, could somebody help me out with this script? I would need this so I can make artworks and such, I would be really grateful!

Here's my script:

local sx, sy = guiGetScreenSize()

local screenColor = {0,255,0,255}

addEventHandler( "onClientResourceStart", getResourceRootElement(getThisResource()),
function()
	greenScreenShader = dxCreateShader ( "greenscreen.fx",0,0,false,"all" )
	
	local texture = dxCreateTexture ( sx, sy )
	dxSetShaderValue ( greenScreenShader, "greenScreenTexture", texture )
	dxSetShaderValue ( greenScreenShader, "screenColor", screenColor[1]/255, screenColor[2]/255, screenColor[3]/255, screenColor[4]/255 )

	engineApplyShaderToWorldTexture ( greenScreenShader, "*" )
	engineRemoveShaderFromWorldTexture ( greenScreenShader, "*", localPlayer )
end)

local screenOutput = dxCreateScreenSource( scx, scy)

addEventHandler ( "onClientHUDRender", root,
function()
	if greenScreenShader then
		local vehicle = getPedOccupiedVehicle(localPlayer)
		if vehicle then
			engineRemoveShaderFromWorldTexture ( greenScreenShader, "*", vehicle )
		end
		dxDrawImage( 0, 0, scx, scy, screenOutput, 0,0,0)
	end
end)

And my shader file (probably wrong, I don't even know what does things mean here, I copied these from other shader files):

texture greenScreenTexture;
float4 screenColor = float4(0.0 / 255.0, 255.0 / 255.0, 0.0 / 255.0, 255.0 / 255.0 );

technique simple
{
    pass P0
    {
        Texture[0] = greenScreenTexture;
    }
}

And this is the result I get:

P2izw1O.png

Could somebody help me out with this?

Thank you for your answers in advance!

Link to comment
greenScreenShader = dxCreateShader ( "greenscreen.fx",0,0,false,"all" )
	
local texture = dxCreateTexture( "Green.png" )
dxSetShaderValue ( greenScreenShader, "greenScreenTexture", texture )

function Refresh()
	if greenScreenShader then
		engineApplyShaderToWorldTexture ( greenScreenShader, "*" )
		local vehicle = getPedOccupiedVehicle(localPlayer)
		if vehicle then
			engineRemoveShaderFromWorldTexture ( greenScreenShader, "*", vehicle )
		end
		engineRemoveShaderFromWorldTexture ( greenScreenShader, "*", getLocalPlayer() )
	end
end

Refresh()

setTimer(Refresh,1000,0) -- Redo texture maps.
texture greenScreenTexture;

technique simple
{
    pass P0
    {
        Texture[0] = greenScreenTexture;
    }
}

For the texture, ensure to supply a green texture.

Edited by CodyJ(L)
Link to comment

That's not good for me, what about the ground? I would prefer if I could make everything green except the players and occupied vehicles, just to be sure that I can get the best results.

I also think that I don't necessarily need shaders, but as I said, I can't think of another solution.

Link to comment

I might try that, just to see how it would look like, but I still prefer the shader/other similar method, because if I want to make an artwork of the rancher for example, and I would like to make it look like it's driving through an obstacle, I must go on to a rock or something to make the wheels look correct, hope you know what I mean. However, if somebody could help me out with the shader method or has any other idea, please reply.

Link to comment

I've written an example in pure Lua to remove the green screen from an image

local img = dxCreateTexture "img.png"
local w, h = dxGetMaterialSize(img)
local pixels = dxGetTexturePixels(img)
local bg_color = {0, 255, 0, 255}
for i=1, w do
    for j=1, h do
        local r, g, b, a = dxGetPixelColor(pixels, i-1, j-1)
        if table.concat({r, g, b, a}, "") == table.concat(bg_color, "") then
            dxSetPixelColor(pixels, i-1, j-1, 0, 0, 0, 0)
        end
    end
  dxSetTexturePixels(img, pixels)
end

-- then you can draw it
addEventHandler("onClientRender", root, function()
	dxDrawImage(0, 0, w, h, img)
end)

 

Edited by </Mr.Tn6eL>
Link to comment

Alright, so I checked out what @pa3ck sent here, the topic, and I got the stuff from there, changed it up a little bit, and yes, everything changed to green, but I still have some problems:

First of all, this is still not the result I would like to get, how I could remove the shadows and textures, since this is just changes the texture color, as I can see.

iesoGRr.jpg

My second problem is that as you can see on the picture, there are still some textures that not even get colored, how I could fix that?

The third problem is that whenever I get into a vehicle, for some reason it remains green, but I can't see any errors in the script, not even debugscript outputs any, here's my current code:

local myShader = dxCreateShader('greenscreen.fx', 0, 0, false, 'all') 
dxSetShaderValue(myShader, 'red', 0.0) 
dxSetShaderValue(myShader, 'green', 1.0) 
dxSetShaderValue(myShader, 'blue', 0.0) 
dxSetShaderValue(myShader, 'alpha', 1.0) 
engineApplyShaderToWorldTexture(myShader, '*')

addEventHandler("onClientRender", root,
function()
	local players = getElementsByType('player') 
	for _, player in ipairs(players) do
		local vehicle = getPedOccupiedVehicle(player)
		if vehicle then
			engineRemoveShaderFromWorldTexture(myShader, '*', vehicle)
		end
		engineRemoveShaderFromWorldTexture(myShader, '*', player)
	end
end)

And the shader:

float red; 
float green; 
float blue; 
float alpha; 

technique simple
{
    pass P0 
    { 
        MaterialAmbient = float4(red, green, blue, alpha); 
    } 
}

By the way, is there any way to draw a dxRectangle or something and then draw the players and vehicles on top of it? I guess that would be one more way to do it, but I don't know if it is possible, because it seems like that this won't work, with this shader.

On 2017. 06. 30. at 16:17, </Mr.Tn6eL> said:

I've written an example in pure Lua to remove the green screen from an image


local img = dxCreateTexture "img.png"
local w, h = dxGetMaterialSize(img)
local pixels = dxGetTexturePixels(img)
local bg_color = {0, 255, 0, 255}
for i=1, w do
    for j=1, h do
        local r, g, b, a = dxGetPixelColor(pixels, i-1, j-1)
        if table.concat({r, g, b, a}, "") == table.concat(bg_color, "") then
            dxSetPixelColor(pixels, i-1, j-1, 0, 0, 0, 0)
        end
    end
  dxSetTexturePixels(img, pixels)
end

-- then you can draw it
addEventHandler("onClientRender", root, function()
	dxDrawImage(0, 0, w, h, img)
end)

 

I appreciate your answer, but this is not what I would like to do, I would like to make the screen/everything green, except players and vehicles that are occupied, so if I take a screenshot and put it to photoshop I can make nicer artworks without choppy and ugly edges.

Link to comment

Can you not just use fun turf? or maybe even find someone that made a custom texture that's pure green.....  Or use paint.net or paint and place an object with one color behind you then edit the object with the paint bucket thing?

Link to comment
46 minutes ago, kieran said:

Can you not just use fun turf? or maybe even find someone that made a custom texture that's pure green.....  Or use paint.net or paint and place an object with one color behind you then edit the object with the paint bucket thing?

That's not what I want to do.

Edited by Dzsozi (h03)
Link to comment

There's an object called "funturf" it looks like grass, there is also many ways to replace an object image with another, so you could just make a script that replaces the image of an object, call the script on a game mode, do a full test and then you'd have a nice green object. :D 

Link to comment
On 6/29/2017 at 02:28, Dzsozi (h03) said:

It doesn't work also:

R780YeO.png

Not the result I was expecting :/

That's just as close as it gets, basically it's the same as the picture you posted.. If that is not the result you expected, I don't think we are on the same page. What is the purpose of the script you're making? Do you want to create a function that will take a picture (as you posted) of the player / vehicle no matter where they are on the map?

Link to comment

Kinda what @pa3ck said. I just want to render everything green, like there is a dxDrawRectangle on the screen, but you can still see the players and vehicles, so I can just move around while everything is green and just take a screenshot, then put that image in photoshop or some image editor software and cut around the character or vehicle easily. That way I could avoid pixelated edges. And the reason I would like to make it as a shader or something similar, not with objects or 3D drawing things, is that I could make for example a rancher look like its driving over a rock on the hills, so the wheels look like there is something under it, but only the rancher would be visible, so I could make artworks and in-game commercial pictures, etc., I hope you could understand me this time. I just want to render EVERYTHING green, EXCEPT the players and the vehicles that are occupied, while I can just move around.

Link to comment
1 hour ago, </Mr.Tn6eL> said:

Try that i think that you want

dxCreateShader("greenscreen.fx",0,0,false,"world,object" )

I think it doesn't matter if I give  "all" instead of "world" and "object" and then use engineRemoveShaderFromWorldTexture function on players and vehicles. Also, that is not the problem, the problem is written above, I just need solid green textures, without model shadows and such.

Link to comment

Seems like a lot of work.

In one of my DM maps I replaced the textures of 1 tree, JUST 1 TREE.
And almost every tree in the entire world started to get replaced.
I then remembered my experience with 3DS Max, and what you name textures in the modeling program has a lot to do with this.
Then discovered that I could use the SAME .TXD, to replace EVERY tree, to my knowledge at least, because I didn't try every tree, but I know I replaced tooooons of trees with the same .TXD file that's only 177 KB.

I opened the GTA3.img.
>
Extracted the tree .TXD of my choice.
>
Opened TXD Workshop.
>
Extracted the .TXD as a .PNG.
>
Opened the .PNG in PhotoShop.
>
Changed the green foliage to blue.
>
Saved the .PNG
>
Went to TXD Workshop, imported the .PNG I had just made edited, so it replaced the default .TXD we extracted before from GTA3.img.
>
Saved the .TXD file
>
Imported to the game with a normal script.

function resource_starts ()
txd3 = engineLoadTXD ( "3.txd" )
engineImportTXD ( txd3, 714 ) --Use the same .TXD to replace multiple objects in the world, and sometimes replacing 1 tree texture, will do 20 somehow. 
engineImportTXD ( txd3, 672 ) --Like I said it probably has something to do with the texture name they use in the modeling program.
engineImportTXD ( txd3, 675 ) --But try using this example and see how far it gets you.
end
addEventHandler ( "onClientResourceStart", getRootElement(), resource_starts )

To cut file size you can also delete other images out of the .TXD files, if they're not being replaced with an edited version they'll stay default.
Goodluck.
 

Edited by Justin|X5|
I'm OCD with grammer.
Link to comment
21 hours ago, Justin|X5| said:

Seems like a lot of work.

In one of my DM maps I replaced the textures of 1 tree, JUST 1 TREE.
And almost every tree in the entire world started to get replaced.
I then remembered my experience with 3DS Max, and what you name textures in the modeling program has a lot to do with this.
Then discovered that I could use the SAME .TXD, to replace EVERY tree, to my knowledge at least, because I didn't try every tree, but I know I replaced tooooons of trees with the same .TXD file that's only 177 KB.

I opened the GTA3.img.
>
Extracted the tree .TXD of my choice.
>
Opened TXD Workshop.
>
Extracted the .TXD as a .PNG.
>
Opened the .PNG in PhotoShop.
>
Changed the green foliage to blue.
>
Saved the .PNG
>
Went to TXD Workshop, imported the .PNG I had just made edited, so it replaced the default .TXD we extracted before from GTA3.img.
>
Saved the .TXD file
>
Imported to the game with a normal script.


function resource_starts ()
txd3 = engineLoadTXD ( "3.txd" )
engineImportTXD ( txd3, 714 ) --Use the same .TXD to replace multiple objects in the world, and sometimes replacing 1 tree texture, will do 20 somehow. 
engineImportTXD ( txd3, 672 ) --Like I said it probably has something to do with the texture name they use in the modeling program.
engineImportTXD ( txd3, 675 ) --But try using this example and see how far it gets you.
end
addEventHandler ( "onClientResourceStart", getRootElement(), resource_starts )

To cut file size you can also delete other images out of the .TXD files, if they're not being replaced with an edited version they'll stay default.
Goodluck.
 

I don't think that it would work out as well, also this is lot of work for just a script that is I think is possible with dxDraw functions. I don't know if any of you have ever played on the Need For Speed SA server, like in the default NFS game, you can make magazine runs and magazine covers, and on this server, when you are making a magazine cover, you can select various backgrounds, but the making of the magazine simply happens in the free run mode, enabling just a kind of an editor for you. So there, you can change between various backgrounds, but when you changed a background it looks like there is just an image drawn on the screen behind your vehicle, it is the same effect that I would like to reach, but with a green background. Here's an example image:

Without the background:

s1fzTmf.png

With backgrounds:

Qm2Q97U.pnghauEJu6.png

And I would like to reach this effect, but with a fully green background.

Link to comment
  • 10 months later...
On 2017. 07. 05. at 00:58, Ren_712 said:

It is possible, but it requires rendering vehicle and background in a separate rendering pass. The object preview shaders (without the custom position) might be good enough.

Sorry for bringing up this topic.

Can you help me out with that? I can't do it by myself, I am not a shader expert.

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