Jump to content

marcelluss

Members
  • Posts

    30
  • Joined

  • Last visited

About marcelluss

  • Birthday 06/10/2003

Recent Profile Visitors

9,762 profile views

marcelluss's Achievements

Rat

Rat (9/54)

3

Reputation

  1. Hello dear forum members, I am deeply interested in a persistent question regarding my shader for the effect of raindrops flowing down the sides of the car, as well as the effect of raindrops (spots) on the surface of the car (roof, bumper). I’ve been struggling with these issues for a long time and still can’t figure out how to solve my two problems. I hope someone can help me and explain to a beginner in HLSL how to properly implement the shader. The first problem is that I don’t understand how to make the raindrops flow down the different sides of the car. Essentially, I have a single texture applied to the car, and I can't figure out how to split it into multiple segments and adapt it to flow around the sides of the car. (I also need to account for the unique features of each car model so that the flow looks realistic on each vehicle.) The second problem is the effect of tiny raindrops on the roof, hood, and bumper of the car (the generation of small droplets that gradually appear and disappear). The issue is that I’m trying to apply both effects in one shader, but the problem is that either only one of them works under certain settings, or nothing works at all. I can't get both effects to work harmoniously together. I’ll also provide an example of the Lua script and the textures used for the shader. I really hope for your help. I've been spending too much time on this, and I can't seem to find a solution. float4x4 gWorld : WORLD; float4x4 gView : VIEW; float4x4 gProjection : PROJECTION; float gTime : TIME; // Rain parameters float gDropSpeed = 0.03; // Speed of droplet flow float2 noiseScale = float2(0.2, 0.8); // Noise texture scale float3 lightDirection = float3(1.0, 1.0, -1.0); // Light direction float gDropSpread = 0.3; // Droplet spread float gDropDepth = 0.3; // Droplet depth texture gTexture; // Main car texture texture texRain; // Raindrop texture texture texNormalRain; // Raindrop normals texture texNoise; // Noise texture // Variables for controlling the effect float gAlpha = 0.01; // Alpha channel for the car float rainAlpha = 1.8; // Alpha channel for raindrops sampler2D gTextureSampler = sampler_state { Texture = ( gTexture ); MinFilter = Linear; MagFilter = Linear; AddressU = Wrap; AddressV = Wrap; }; sampler2D texRainSampler = sampler_state { Texture = ( texRain ); MinFilter = Linear; MagFilter = Linear; AddressU = Wrap; AddressV = Wrap; }; sampler2D texNormalRainSampler = sampler_state { Texture = ( texNormalRain ); MinFilter = Linear; MagFilter = Linear; AddressU = Wrap; AddressV = Wrap; }; sampler2D texNoiseSampler = sampler_state { Texture = ( texNoise ); MinFilter = Linear; MagFilter = Linear; AddressU = Wrap; AddressV = Wrap; }; struct VertexShaderInput { float4 Position : POSITION; // Using standard POSITION semantics for the vertex shader float2 TextureCoordinate : TEXCOORD0; // Passing texture coordinates }; struct PixelShaderInput { float4 Position : POSITION; // Passing position as float4 for proper operation float3 WorldPos : TEXCOORD1; // Passing world coordinates for calculations float2 TextureCoordinate : TEXCOORD0; // Passing texture coordinates }; PixelShaderInput VertexShaderFunction(VertexShaderInput input) { PixelShaderInput output; // Position in world coordinates float4 worldPos = mul(input.Position, gWorld); // Storing position for further projection output.Position = mul(mul(input.Position, gWorld), gView); output.Position = mul(output.Position, gProjection); // Applying projection // Storing world coordinates (for droplet flow) output.WorldPos = worldPos.xyz; // Passing texture coordinates output.TextureCoordinate = input.TextureCoordinate; return output; } float4 PixelShaderFunction(PixelShaderInput output) : COLOR0 { float2 textureCoordinate = output.TextureCoordinate; // Main car texture float4 baseColor = tex2D(gTextureSampler, textureCoordinate); baseColor.rgb = max(baseColor.rgb, 0.1); // Brightening dark areas // Getting noise for random movement float noise = tex2D(texNoiseSampler, textureCoordinate * noiseScale).r; // World coordinates to determine droplet direction float3 worldPos = output.WorldPos; // Using world coordinates // Determining droplet direction based on normals and world position float3 normal = normalize(output.WorldPos); // Normal to the surface // Checking direction by normals to determine which side of the car we're on if (abs(normal.x) > abs(normal.y) && abs(normal.x) > abs(normal.z)) { // Side surfaces textureCoordinate.y += gDropSpeed * gTime; // Flowing down the sides } else if (normal.y > 0.5) { // Top surface (roof) textureCoordinate.y -= gDropSpeed * gTime; // Droplets flow down } else { // Other sides (front and back) textureCoordinate.x -= gDropSpeed * gTime; // Optionally add droplet flow forward/backward } // Reducing random offset for more precise flow float2 offset = gDropSpread * (noise * 4.0 - 0.5) * float2(1.0, 2.5); // Using float2 for offset textureCoordinate -= offset; // Applying deviation in both axes // Raindrop texture float4 rainColor = tex2D(texRainSampler, textureCoordinate); // Adjusting droplets to the car color rainColor.rgb = baseColor.rgb * 0.8 + float3(0.1, 0.1, 0.1); // Adding body tint to droplets rainColor.a = rainAlpha; // Alpha channel of droplets // Normals for droplets float4 tempRainNormal = tex2D(texNormalRainSampler, textureCoordinate); // Explicitly using float4 float3 rainNormal = normalize(tempRainNormal.rgb * 2.5 - 0.75); // Normalizing normals // Lighting on droplets float diffuse = saturate(dot(normalize(rainNormal), normalize(lightDirection))); // Correct lighting // Combining colors float4 finalColor = lerp(baseColor, rainColor, rainAlpha * diffuse); finalColor.a = lerp(gAlpha, rainAlpha, diffuse * 0.9); // Adding droplet depth finalColor.rgb += gDropDepth * 0.9; // Depth effect of droplets float3 v = float3(0.0, 0.0, 0.0); float Tr2 = gTime * 11000.0; float2 n = tex2D(texNoiseSampler, textureCoordinate * 0.5).rg; for (float r = 4.0; r > 0.0; r--) // Reducing the number of iterations { float2 x = 2100.0 * r * 0.015; float2 p = 6.28 * textureCoordinate * x + (n - 0.5) * 2.0; float4 d = tex2D(texNoiseSampler, round(textureCoordinate * x - 0.25) / x); float t = (sin(p.x) + sin(p.y)) * max(0.0, 1.0 - frac(Tr2 * (d.b + 0.1) + d.g) * 2.0); if (d.r < (2.0 - r) * 0.08 && t > 0.5) { v += normalize(float3(-cos(p.x), lerp(1.2, 2.0, t - 0.5), 0.0)); } } finalColor.rgb += v * rainAlpha; return finalColor; } technique Replace { pass P0 { DepthBias = -0.0001; AlphaBlendEnable = TRUE; SrcBlend = SRCALPHA; DestBlend = INVSRCALPHA; VertexShader = compile vs_1_1 VertexShaderFunction(); PixelShader = compile ps_3_0 PixelShaderFunction(); } } LUA CODE: local shader = dxCreateShader("fx/shader.fx", 2, 300, true, "vehicle"); local zapylyayushiesyaDetali = { "remap_body", }; local rainTexture = dxCreateTexture("assets/RainCar.png") local normalRainTexture = dxCreateTexture("assets/RainNormal.png") local noiseTexture = dxCreateTexture("assets/enbnoise.png") dxSetShaderValue(shader, "texRain", rainTexture) dxSetShaderValue(shader, "texNormalRain", normalRainTexture) dxSetShaderValue(shader, "texNoise", noiseTexture) -- Применение шейдера к машине local vehicle = getPedOccupiedVehicle(localPlayer) if vehicle then --engineApplyShaderToWorldTexture(shader, "vehiclegrunge256", vehicle) for _, name in ipairs(zapylyayushiesyaDetali) do engineRemoveShaderFromWorldTexture(shader, name, localPlayer.vehicle) engineApplyShaderToWorldTexture(shader, name, localPlayer.vehicle) end end renderTarget = dxCreateRenderTarget(512, 512, true) addEventHandler("onClientRender", root, function() iprint(shader) if shader then if renderTarget then dxSetRenderTarget(renderTarget, true) dxDrawImage(0, 0, 512, 512, shader) dxSetRenderTarget() dxDrawImage(50, 50, 256, 256, renderTarget) end end end)
  2. Hello guys, I want to implement an interesting feature in MTA for heating up the brake discs. I'm not sure where to start; how do you actually change the textures of specific car brake discs? Do I need a shader for this? If yes, what kind could serve as a base? Maybe there are already ready-made examples (systems)?
  3. Hello, I would like to know if it is possible to somehow make a normal blur effect (glass) in mta? I know that there are shaders in the likeness of BlurBox, but they do not give enough blur and glass effect, is it possible to somehow achieve such an effect as in the screenshot below? Using a shader? I don't really know how to work with shaders if someone knows how to upgrade my shader, please help me please here is a variant of my shader code texture ScreenSource; float BlurStrength; float2 UVSize; sampler TextureSampler = sampler_state { Texture = <ScreenSource>; MinFilter = Linear; MagFilter = Linear; MipFilter = Linear; AddressU = Wrap; AddressV = Wrap; }; static const float2 poisson[16] = { float2(-0.326212f, -0.40581f), float2(-0.840144f, -0.07358f), float2(-0.695914f, 0.457137f), float2(-0.203345f, 0.620716f), float2(0.96234f, -0.194983f), float2(0.473434f, -0.480026f), float2(0.519456f, 0.767022f), float2(0.185461f, -0.893124f), float2(0.507431f, 0.064425f), float2(0.89642f, 0.412458f), float2(-0.32194f, -0.932615f), float2(-0.65432f, -0.87421f), float2(-0.456899f, -0.633247f), float2(-0.123456f, -0.865433f), float2(-0.664332f, -0.25680f), float2(-0.791559f, -0.59771f) }; float4 PixelShaderFunction(float2 TextureCoordinate : TEXCOORD0) : COLOR0 { float4 color = tex2D(TextureSampler, TextureCoordinate); for(int i = 0; i < 14; i++) { float2 coord= TextureCoordinate.xy + (poisson[i] / UVSize * BlurStrength); color += tex2D(TextureSampler, coord); } return(color/17); } technique BlurShader { pass Pass1 { PixelShader = compile ps_2_0 PixelShaderFunction(); } } and here are two options for the result of my blurring the picture before and after applying the shader picture before picture after
  4. I tried to use this function, but unfortunately I didn't quite understand how to use it :((( local rawSvgData = [[ <svg viewBox="0 0 600 600" xmlns="http://www.w3.org/2000/svg"> <defs> <linearGradient id="gradient"> <stop offset="5%" stop-color="#FF0000" /> <stop offset="95%" stop-color="#00FF00" /> </linearGradient> </defs> <path id="progress" fill="none" stroke="url(#gradient)" d="M300,50 A250,250,0,1,1,299.99,50" stroke-width="20" /> </svg> ]] local svgs = {} local function render(svg) if (not isElement(svg)) or (getElementType(svg) ~= "svg") then removeEventHandler("onClientRender", root, svgs[svg].handler) svgs[svg] = nil end local width, height = svgGetSize(svg) dxDrawImage(500, 500, 430, 430, svg, 0, 0, 0, tocolor(255, 255, 255), false) end local function onUpdate(svg) print("fe") if (not svgs[svg]) then svgs[svg] = { state = true, handler = function() render(svg) end } addEventHandler("onClientRender", root, svgs[svg].handler) end iprint("SVG texture updated", svg, getTickCount()) end addEventHandler("onClientResourceStart", root, function() mySvg = svgCreate(430, 430, rawSvgData, onUpdate) end) bindKey("l", "down", function() local newPath = updateState(100, 100, 300); addSVGRectNode(mySvg, path) end) function addSVGRectNode(svg, path) local svgXML = svgGetDocumentXML(svg) local rect = xmlCreateChild(svgXML, "rect") xmlNodeSetAttribute(rect, "d", path) local status = svgSetDocumentXML(svg, svgXML) print(status) end function updateState(value, total, R) local center local alpha = 360 / total * value local a = (90 - alpha) * math.pi / 180 local x = 300 + R * math.cos(a) local y = 300 - R * math.sin(a) local path if (total == value) then path = "M300,"..(300 - R).." A"..R..","..R..",0,1,1,299.99,"..(300 - R) else if (alpha > 180) then center = 1 else center = 0 end path = "M300,"..(300 - R).." A"..R..","..R..",0,"..center..",1,"..x..","..y end return path end The problem is that for some reason I can't change the source data of the svg file already (I tried to do as you said, well, for some reason it doesn't work) - besides, I didn't quite understand working with the arguments of this function, let's say I tried to manually call the function and replace the arguments the same as from the debug, but this it didn't work quite correctly, maybe I didn't quite understand the principle of these arguments of this function, what is responsible for what. Please help me
  5. hello, I really liked your idea with the work of svg, is it possible to find out how to make the progress of reducing the strip in the svg code?
  6. Hello, I ran into a problem with the dxDrawCircle function, I have a shader that allows you to apply a gradient to a texture, but the problem is that I need to make a gradient to a level system where there is a round strip with a gradient and I would like to attach a gradient there, but the problem is that dxDrawCircle does not accept a texture and I would like to somehow attach it there, or if possible, help me!
  7. Hello, I would like to know if it is possible to make a countdown timer without using the SetTimer function? I wanted to do this in a more optimized and correct way because the usual SetTimer does not work quite in time. And I would like to make a dynamic function in which I can enter, say, 60 minutes into the arguments and a countdown timer will start with the output of minutes and seconds and at the same time use getRealTime. I tried to use many ways with this function, but they were all unsuccessful + I have already tried to find solutions on the forum and on the Internet, but all used SetTimer - unfortunately, it will not work to provide a ready-made code for my solution, because not one of them was even close to the solution I was moving towards
  8. Hello, I've been trying to figure out for a very long time how to make a smooth 3d line? In terms of I know that there is a dxDrawLine3D, but this function allows you to create flat lines or to be more precise straight lines, and I need to make a smooth line in the likeness of drawing with a brush in the 3d world, but I can't figure out how to make such a smooth line, I wanted to make it for traces of players and cars
  9. I want to find out how to implement the effect of the web on the screen. I've seen this on websites, in principle I have no idea how to do this, but just how optimized will it be? And is it even possible to implement it using a shader?
  10. create a colshape and track the contact of both colshapes
  11. The speed must be constantly set for this function to work. To do this, use a timer or a render to constantly maintain the speed. I don 't know for sure if it is possible to replace the shooting effect , but I can offer an option to create an object and count the trajectory of the bullet ( and already apply your shader to the object itself )
  12. local cursorShowing = false bindKey("f2", "down", function() cursorShowing = not cursorShowing showCursor(cursorShowing) end) local nameColor = white local nameSize = 1.2 local nameFont = "pricedown" local ped = createPed(0, 0, 0, 3); addEventHandler( "onClientRender", getRootElement(), function( ) --for _, plr in ipairs( getElementsByType( "player" ) ) do -- if not (plr == localPlayer) then local x, y, z = getPedBonePosition( ped, 8 ) local sX, sY = getScreenFromWorldPosition( x, y, z ) if sX then --local id = setElementData(plr, "id") local text if id then text ="Player ["..id.."]" else text = "Player" end local leftX = sX- dxGetTextWidth(text, nameSize, nameFont )/2 local topY = sY-60 local rightX = leftX local buttonY = topY dxDrawText( text, leftX, topY, rightX, buttonY, nameColor, nameSize, nameSize, nameFont, "left", "top", false, false, false, false, false) end -- end --end local w, h = guiGetScreenSize () local tx, ty, tz = getWorldFromScreenPosition ( w/2, h/2, 50 ) local px, py, pz = getCameraMatrix(localPlayer) -- test line -- local line = dxDrawLine3D(px, py, pz, x, y, z) local hit, x, y, z, elementHit = processLineOfSight ( px, py, pz, tx, ty, tz ) if hit then if elementHit then local sX, sY = getScreenFromWorldPosition( x, y, z ) dxDrawText("G", sX, sY, sX, sY, tocolor(255, 255, 255), 1, "default") end end end ) If I understood your idea correctly, then here is the script
  13. it all depends on the animation itself, if the animation itself allows you to walk, then yes, you can walk with animation enabled, but this is not available to all animations. And also you can import your own animations into the game. The Internet is full of guides for creating animations for a character in the game.
×
×
  • Create New...