• Materials/Textures Tutorial? Rendering more than once in one frame with alpha blending
    1 replies, posted
I'm trying to create a script that would render the scene more than once (let's say, 5 times), each with a variation, and blend all these together with equal weights. Conceptually, I think this is what I'm supposed to do: 1. Render scene at 100% alpha 2. Modify scene, render scene at 50% alpha 3. Modify scene, render scene at 33% alpha 4. etc... There are several vanilla post-processing effects that do some variation of this, and they are: [url=https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/postprocess/motion_blur.lua]Accumulation Motion Blur[/url] (most readable with comments) [url=https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/postprocess/frame_blend.lua]Frame Blend[/url] (crap readability) [url=https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/postprocess/super_dof.lua]Super DoF[/url] There may be others as well. The problem is, I've tried and failed to read these scripts. I can't find a good explanation for how Materials and Textures work, and they are basically the entirety of how this is accomplished. I've tried copy-pasting some parts, hacking them together, crossing my fingers for a usable result, trying random things, but to no avail. I just don't have enough (read: any) understanding for how Materials and Textures work, to get this script running. Some key things: * This needs to work with the "poster" command, so I'm doing it in GM:RenderScene. * Processing time is not an issue. It can take an hour for all I care. My current code, quite probably cringe-worthy: [lua]if SERVER then print("SoftPoster must be run clientside!") return end // this is a goddamn client script! // Frame blending code attempted to be copied from: motion_blur.lua local mat_MotionBlur = Material( "pp/motionblur" ) local tex_MotionBlur = render.GetMoBlurTex0() local mat_Screen = Material( "pp/fb" ) function SoftPoster(radius, resmul, split) local i = resmul * resmul + 5 // i = number of calls of GM:RenderScene that need to be hooked, plus 5 for good measure local up = LocalPlayer():GetAngles():Up() local right = LocalPlayer():GetAngles():Right() local origin = LocalPlayer():GetPos() hook.Add("RenderScene", "SoftPoster", function() local alpha = 1 LocalPlayer():SetPos(origin) mat_Screen:SetFloat( "$alpha", 1.0 ) mat_Screen:SetTexture( "$basetexture", tex_MotionBlur ) render.SetMaterial( mat_Screen ) render.RenderView() LocalPlayer():SetPos(origin + (up * radius) + (right * radius)) mat_Screen:SetFloat( "$alpha", 1.0 / 2.0 ) mat_Screen:SetTexture( "$basetexture", tex_MotionBlur ) render.SetMaterial( mat_Screen ) render.RenderView() LocalPlayer():SetPos(origin - (up * radius) + (right * radius)) mat_Screen:SetFloat( "$alpha", 1.0 / 3.0 ) mat_Screen:SetTexture( "$basetexture", tex_MotionBlur ) render.SetMaterial( mat_Screen ) render.RenderView() LocalPlayer():SetPos(origin + (up * radius) - (right * radius)) mat_Screen:SetFloat( "$alpha", 1.0 / 4.0 ) mat_Screen:SetTexture( "$basetexture", tex_MotionBlur ) render.SetMaterial( mat_Screen ) render.RenderView() LocalPlayer():SetPos(origin - (up * radius) - (right * radius)) mat_Screen:SetFloat( "$alpha", 1.0 / 5.0 ) mat_Screen:SetTexture( "$basetexture", tex_MotionBlur ) render.SetMaterial( mat_Screen ) render.RenderView() LocalPlayer():SetPos(origin) -- render.SetMaterial( mat_MotionBlur ) -- render.DrawScreenQuad() print(i) i = i - 1 if (i == 0) then hook.Remove("RenderScene","SoftPoster") print("Removing hook") end return true end) RunConsoleCommand("poster", resmul, split) end[/lua] I put this code in a lua file in garrysmod/lua, and in-game I use the concommand: [b]lua_openscript_cl softposter.lua[/b] I also have the binding: [b]bind semicolon "lua_run_cl SoftPoster(10, 2)"[/b] for testing. I promise the end product that I'm planning will be more elegant to use :P tl;dr Can you please point me at a proper explanation or tutorial for Materials and Textures?
So, after a night's sleep and a second attempt at figuring out how Accumulated Motion Blur works, I think I have a much better understanding of how things play with each other. However, I'm still having problems. Here's the current iteration of my code: [lua]if SERVER then print("SoftPoster must be run clientside!") return end // this is a goddamn client script! // Frame blending code copied from: motion_blur.lua local mat_MotionBlur = Material( "pp/motionblur" ) local mat_Screen = Material( "pp/fb" ) local tex_MotionBlur = render.GetMoBlurTex0() local function RenderWithAlpha(addalpha) render.UpdateScreenEffectTexture() mat_Screen:SetFloat( "$alpha", addalpha ) local oldRT = render.GetRenderTarget() render.SetRenderTarget(tex_MotionBlur) render.SetMaterial(mat_Screen) render.DrawScreenQuad() --render.Clear(255, 0, 0, 255, true, true) render.SetRenderTarget(oldRT) end function SoftPoster(radius, resmul, split) local callsleft = resmul * resmul + 1 -- + 800 -- number of calls of the render hook that need to be hooked, 1 extra called pre-poster local ent = LocalPlayer():GetEyeTrace().Entity local up = ent:GetAngles():Up() local right = ent:GetAngles():Right() local origin = ent:GetPos() print("Starting poster") --hook.Add("RenderScene", "SoftPoster", function() hook.Add("RenderScreenspaceEffects", "SoftPoster", function() mat_MotionBlur:SetFloat("$alpha", 1) mat_MotionBlur:SetTexture( "$basetexture", tex_MotionBlur ) -- Center: ent:SetPos(origin) RenderWithAlpha(1) -- Up Right: ent:SetPos(origin + (up * radius) + (right * radius)) RenderWithAlpha(1/2) -- Down Right: ent:SetPos(origin - (up * radius) + (right * radius)) RenderWithAlpha(1/3) -- Up Left: ent:SetPos(origin + (up * radius) - (right * radius)) RenderWithAlpha(1/4) -- Down Left: ent:SetPos(origin - (up * radius) - (right * radius)) RenderWithAlpha(1/5) -- return to normal: ent:SetPos(origin) -- This part WORKS, it writes whatever was rendered in RenderWithAlpha to screen: render.SetMaterial( mat_MotionBlur ) render.DrawScreenQuad() callsleft = callsleft - 1 if (callsleft == 0) then hook.Remove("RenderScreenspaceEffects","SoftPoster") print("Removing hook") end --return true end) RunConsoleCommand("poster", resmul, split) end[/lua] The problem I'm having is one of two (I have no idea how to check which): either the entity doesn't move inbetween calls to RenderWithAlpha even though SetPos is called, or RenderWithAlpha doesn't work correctly. Please help! :(
Sorry, you need to Log In to post a reply to this thread.