Dope88 Posted October 10, 2021 Share Posted October 10, 2021 Hello I want to put multiple textures to one texture Name with "engineApplyShaderToWorldTexture", but when I apply one shader the other one disappears. What could I do now? Thanks for the help! Link to comment
The_GTA Posted October 11, 2021 Share Posted October 11, 2021 19 hours ago, Dope88 said: Hello I want to put multiple textures to one texture Name with "engineApplyShaderToWorldTexture", but when I apply one shader the other one disappears. Please take a look at the engineApplyShaderToWorldTexture wiki documentation. Are you properly setting the appendLayers parameter to true or leaving it out? It might help to support you if we had insight into your shaders themselves. They could be designed in a way that does not allow layering. Could you share them with us? 1 Link to comment
Dope88 Posted October 11, 2021 Author Share Posted October 11, 2021 3 hours ago, The_GTA said: Please take a look at the engineApplyShaderToWorldTexture wiki documentation. Are you properly setting the appendLayers parameter to true or leaving it out? It might help to support you if we had insight into your shaders themselves. They could be designed in a way that does not allow layering. Could you share them with us? Thanks for the Answer! I just set appendLayers to true but now nothing seems to happen. Client Side: local shaderData = [[ texture tex; technique replace { pass P0 { Texture[0] = tex; } } ]] face = {} bart = {} function addFace(thePlayer, ID, color) if (face[thePlayer]) then -- to remove any existing hair before applying new one. for i, v in ipairs(clothes_ID[7]["face"]) do engineRemoveShaderFromWorldTexture ( face[thePlayer], v, thePlayer) end local shader = dxCreateShader(shaderData, {}, 0, 0, false, "ped") local texture = dxCreateTexture("clothes/7/face/1/"..color..".png") dxSetShaderValue(shader, "tex", texture) engineApplyShaderToWorldTexture(shader,clothes_ID[7]["face"][tonumber(ID)],thePlayer, true) hat[thePlayer] = shader else local shader = dxCreateShader(shaderData, {}, 0, 0, false, "ped") local texture = dxCreateTexture("clothes/7/face/"..ID.."/"..color..".png") dxSetShaderValue(shader, "tex", texture) engineApplyShaderToWorldTexture(shader,clothes_ID[7]["face"][1],thePlayer, true) hat[thePlayer] = shader end end addEvent("client:sync:face", true) addEventHandler("client:sync:face", root, addFace) function addBart(thePlayer, ID, color) if (face[thePlayer]) then for i, v in ipairs(clothes_ID[7]["face"]) do engineRemoveShaderFromWorldTexture ( face[thePlayer], v, thePlayer) end local shader = dxCreateShader(shaderData, {}, 0, 0, false, "ped") local texture = dxCreateTexture("clothes/7/bart/1/"..color..".png") dxSetShaderValue(shader, "tex", texture) engineApplyShaderToWorldTexture(shader,clothes_ID[7]["face"][tonumber(ID)],thePlayer, true) hat[thePlayer] = shader else local shader = dxCreateShader(shaderData, {}, 0, 0, false, "ped") local texture = dxCreateTexture("clothes/7/bart/"..ID.."/"..color..".png") dxSetShaderValue(shader, "tex", texture) engineApplyShaderToWorldTexture(shader,clothes_ID[7]["face"][1],thePlayer, true) hat[thePlayer] = shader end end addEvent("client:sync:Bart", true) addEventHandler("client:sync:Bart", root, addBart) Server Side: function testface(thePlayer, _, ID, color) triggerClientEvent(root, "client:sync:face", thePlayer, thePlayer, ID, color) end addCommandHandler("testface", testface, false, false) function testbart(thePlayer, _, ID, color) triggerClientEvent(root, "client:sync:bart", thePlayer, thePlayer, ID, color) end addCommandHandler("testbart", testbart, false, false) Shared: clothes_ID = { [7] = { ["face"] = {"head_diff_000_a_whi"}, ["bart"] = {"head_diff_000_a_whi"}, }, } Link to comment
Dope88 Posted October 11, 2021 Author Share Posted October 11, 2021 I made a Mistake with "bart" and "Bart" had the B big and b small but now I changed it and the face texture disappears when I activate the beard and the beard disappears when I activate the face texture.. Link to comment
The_GTA Posted October 11, 2021 Share Posted October 11, 2021 Do your textures have alpha enabled? This looks like a hack-job to me and I am not convinced that you truly know how HLSL shaders work. If the beard is an alpha texture then you might have to set relevant alpha-enabling render-states. What you have to set depends on the asset structure themselves and unless you share the textures I cannot give you a recommendation. Link to comment
Dope88 Posted October 11, 2021 Author Share Posted October 11, 2021 I bought the Script from the Internet I‘ll look what I can do and could I message you in private please? Link to comment
The_GTA Posted October 11, 2021 Share Posted October 11, 2021 13 minutes ago, Dope88 said: I bought the Script from the Internet I‘ll look what I can do and could I message you in private please? Yes. I do not like to start support requests through private messaging but continuing there is fine. 1 Link to comment
The_GTA Posted October 18, 2021 Share Posted October 18, 2021 (edited) I have received your resource files for full evaluation and have detected an alpha-based image configuration combined with append-layer based shader attachment. Based on the provided files, here is my defect report: By creating and attaching multiple shaders onto the same "head_diff_000_a_whi" texture of the player model you are inducing depth-fighting between the bart and the face textures. It looks like a coding error in your script due to COPY & PASTE. In order to focus your eyes for critical reading, take a look at line 348 of example.lua: engineApplyShaderToWorldTexture(shader,clothes_ID[7]["face"][1],thePlayer, true) In this line you are using the "face" texture. Are you meaning to use the "beard" texture instead? If you are, then you can fix easily fix this issue by chaging the string and making sure that each shader points to only one texture. In case you are not, there is a fundamental flaw in your design that is caused by misunderstanding how the GPU works and how MTA is utilizing it. By using append-layers and enabling depth-testing, the GPU is attempting to redraw the beard onto the original model BUT this is not stable because of mathematical inprecision. Your textures will start to flicker or one will hide another. So how to fix this defect? Instead of creating two shaders that draw onto one texture, I recommend you to off-screen combine the textures and then apply them to a shader. You can use the dxCreateRenderTarget, dxSetRenderTarget, dxCreateTexture and dxDrawImage functions to create a drawing surface (render target), layer the face + beard onto each other and then use the resulting render-target as texture in your shader. Do not forget to enable alpha for the render-target! Here is how a combine-stage of two textures might look like: local function renderCombinedTexture(tex1, tex2) local tex1w, tex1h = dxGetMaterialSize(tex1) local tex2w, tex2h = dxGetMaterialSize(tex2) local cw, ch = math.max(tex1w, tex2w), math.max(tex1h, tex2h) local rt = dxCreateRenderTarget(cw, ch, true) dxSetRenderTarget(rt) dxDrawImage(0, 0, tex1w, tex1h, tex1) dxDrawImage(0, 0, tex2w, tex2h, tex2) dxSetRenderTarget() return rt end You should use renderCombinedTexture in the onClientRender event handler to adhere to MTA's recommendations. If you have combined the textures and the combined texture does replace a predefined texture fully of the GTA SA DFF file, then I recommend you to set appendLayers to false instead. I was unsure how your system worked in my previous reply so I spearheaded a guess. But now with my actual analysis I recommend you to NOT use the appendLayers functionality. IMO it is a feature of MTA with very limited applicability. You seem to use weird global variables across your script. Take a look at the following line which repeats itself but seems to imply a contradiction: hat[thePlayer] = shader The global table is called "hat" but the function it is used in is called addFace or addBart. Could this be a variable misuse? I am looking forward to hearing back from you! Edited October 18, 2021 by The_GTA 2 Link to comment
Dope88 Posted October 18, 2021 Author Share Posted October 18, 2021 13 minutes ago, The_GTA said: I have received your resource files for full evaluation and have detected an alpha-based image configuration combined with append-layer based shader attachment. Based on the provided files, here is my defect report: By creating and attaching multiple shaders onto the same "head_diff_000_a_whi" texture of the player model you are inducing depth-fighting between the bart and the face textures. It looks like a coding error in your script due to COPY & PASTE. In order to focus your eyes for critical reading, take a look at line 348 of example.lua: engineApplyShaderToWorldTexture(shader,clothes_ID[7]["face"][1],thePlayer, true) In this line you are using the "face" texture. Are you meaning to use the "beard" texture instead? If you are, then you can fix easily fix this issue by chaging the string and making sure that each shader points to only one texture. In case you are not, there is a fundamental flaw in your design that is caused by misunderstanding how the GPU works and how MTA is utilizing it. By using append-layers and enabling depth-testing, the GPU is attempting to redraw the beard onto the original model BUT this is not stable because of mathematical inprecision. Your textures will start to flicker or one will hide another. So how to fix this defect? Instead of creating two shaders that draw onto one texture, I recommend you to off-screen combine the textures and then apply them to a shader. You can use the dxCreateRenderTarget, dxSetRenderTarget, dxCreateTexture and dxDrawImage functions to create a drawing surface (render target), layer the face + beard onto each other and then use the resulting render-target as texture in your shader. Do not forget to enable alpha for the render-target! Here is how a combine-stage of two textures might look like: local function renderCombinedTexture(tex1, tex2) local tex1w, tex1h = dxGetMaterialSize(tex1) local tex2w, tex2h = dxGetMaterialSize(tex2) local cw, ch = math.max(tex1w, tex2w), math.max(tex1h, tex2h) local rt = dxCreateRenderTarget(cw, ch, true) dxSetRenderTarget(rt) dxDrawImage(0, 0, tex1w, tex1h, tex1) dxDrawImage(0, 0, tex2w, tex2h, tex2) dxSetRenderTarget() return rt end You should use renderCombinedTexture in the onClientRender event handler to adhere to MTA's recommendations. You seem to use weird global variables across your script. Take a look at the following line which repeats itself but seems to imply a contradiction: hat[thePlayer] = shader The global table is called "hat" but the function it is used in is called addFace or addBart. Could this be a variable misuse? I am looking forward to hearing back from you! Wow! Thank you very much for taking the Time to help me with my Problem. I will take a look at it and try toedit it the next days. I will tell you when im done! Thank you! Link to comment
The_GTA Posted October 18, 2021 Share Posted October 18, 2021 (edited) 10 minutes ago, Dope88 said: Wow! Thank you very much for taking the Time to help me with my Problem. I will take a look at it and try toedit it the next days. I will tell you when im done! Thank you! You're welcome! Working with the GPU is very complicated because it is a piece of hardware that has been incrementally created. A lot of things that seem intuitive will lead you to annoying & strong drawbacks, most likely due to aging & limited API design (Direct3D9). That is why it is important to get support on our forums whenever your drawing code does not work how you imagine it. Edited October 18, 2021 by The_GTA 1 Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now