--[[ | This file was obtained through the combined efforts | of Madbluntz & Plymouth Antiquarian Society. | | Credits: lifestorm, Gregory Wayne Rossel JR., | Maloy, DrPepper10 @ RIP, Atle! | | Visit for more: https://plymouth.thetwilightzone.ru/ --]] --[[------------------------------------------------------------------------- Render clouds ---------------------------------------------------------------------------]] local cos,sin,rad = math.cos,math.sin,math.rad local max,min,clamp,ceil,abs = math.max,math.min,math.Clamp,math.ceil,math.abs local z_level = -.8 local eye_mult = -.0001 -- Generate dome mesh local Render_Dome = Mesh() local top_height = 20 local sc = 20 local stage = 0 local e_r = rad(45) local t_s = 1 local function UVMulti(uv,mul) return (uv - 0.5) * mul + 0.5 end mesh.Begin( Render_Dome, MATERIAL_TRIANGLES, 24 ) for i = 1,8 do local yaw = rad(45 * i) -- Generate the top -- L local c,s = cos(yaw),sin(yaw) local L = {Vector(c * sc,s * sc,0.1 * -sc),(1 + c) / 2 * t_s,(1 + s) / 2 * t_s} mesh.Position(L[1]) mesh.TexCoord( stage, L[2], L[3]) mesh.Color(255,255,255,255) mesh.AdvanceVertex() -- R local c,s = cos(yaw + e_r),sin(yaw + e_r) local R = {Vector(c * sc,s * sc,0.1 * -sc),(1 + c) / 2 * t_s, (1 + s) / 2 * t_s} mesh.Position(R[1]) mesh.TexCoord( stage, R[2],R[3] ) mesh.Color(255,255,255,255) mesh.AdvanceVertex() -- T mesh.Position(Vector(0,0,0.1 * top_height)) mesh.TexCoord( stage, 0.5 * t_s,0.5 * t_s ) mesh.Color(255,255,255,255) mesh.AdvanceVertex() -- Generate side1 mesh.Position(L[1]) mesh.TexCoord( stage, L[2], L[3]) mesh.Color(255,255,255,255) mesh.AdvanceVertex() local R2 = {R[1] * 1.4 - Vector(0,0,4),UVMulti(R[2],1.4),UVMulti(R[3],1.4)} mesh.Position(R2[1]) mesh.TexCoord( stage, R2[2],R2[3] ) mesh.Color(255,255,255,0) mesh.AdvanceVertex() mesh.Position(R[1]) mesh.TexCoord( stage, R[2],R[3] ) mesh.Color(255,255,255,255) mesh.AdvanceVertex() -- Generate side 2 mesh.Position(L[1]) mesh.TexCoord( stage, L[2], L[3]) mesh.Color(255,255,255,255) mesh.AdvanceVertex() mesh.Position(L[1] * 1.4 - Vector(0,0,4)) mesh.TexCoord( stage, UVMulti(L[2], 1.4), UVMulti(L[3],1.4)) mesh.Color(255,255,255,0) mesh.AdvanceVertex() mesh.Position(R2[1]) mesh.TexCoord( stage, R2[2],R2[3] ) mesh.Color(255,255,255,0) mesh.AdvanceVertex() end mesh.End() -- Local functions local matrix = Matrix() local function RenderDome(pos,mat,alpha) matrix:Identity() matrix:Translate( vector_origin + pos ) --mat:SetAlpha(alpha) cam.PushModelMatrix(matrix) render.SetBlend(alpha / 255) render.SetMaterial(mat) Render_Dome:Draw() render.SetBlend(1) cam.PopModelMatrix() end local lastRT local function RTRender(RT,blend) lastRT = RT render.PushRenderTarget( RT ) render.ClearDepth() render.Clear( 0, 0, 0, 0 ) cam.Start2D() if not blend then return end render.OverrideAlphaWriteEnable( true, true ) end local function RTMask(srcBlend,destBlend,srcBlendAlpha,destBlendAlpha) local srcBlend = srcBlend or BLEND_ZERO local destBlend = destBlend or BLEND_SRC_ALPHA -- local blendFunc = 0 -- The blend mode used for drawing the color layer local srcBlendAlpha = srcBlendAlpha or BLEND_DST_ALPHA -- Determines how a rendered texture's final alpha should be calculated. local destBlendAlpha = destBlendAlpha or BLEND_ZERO -- local blendFuncAlpha = 0 -- render.OverrideBlend( true, srcBlend, destBlend, blendFunc, srcBlendAlpha, destBlendAlpha, blendFuncAlpha) end local function RTEnd(Mat_Output) render.OverrideBlend( false ) render.OverrideAlphaWriteEnable( false ) cam.End2D() render.PopRenderTarget() -- Apply changes Mat_Output:SetTexture("$basetexture",lastRT) end local function DrawTextureRectWindow(w,h,o_x,o_y) -- Render function that supports fractions (surface libary is whole numbers only) if o_x < 0 then o_x = o_x + w end if o_y < 0 then o_y = o_y + h end o_x = o_x % w o_y = o_y % h local m = Matrix() m:Identity() m:Translate(Vector(o_x % w,o_y % h)) cam.PushModelMatrix(m) surface.DrawTexturedRect(0,0,w,h) surface.DrawTexturedRect(-w,0,w,h) surface.DrawTexturedRect(0,-h,w,h) surface.DrawTexturedRect(-w,-h,w,h) cam.PopModelMatrix() end -- Load materials -- Side clouds local side_clouds = {} for _,fil in ipairs(file.Find("materials/stormfox2/effects/clouds/side_cloud*.png","GAME")) do local png = Material("stormfox2/effects/clouds/" .. fil,"nocull noclamp alphatest") png:SetInt("$flags",2099250) table.insert(side_clouds,{png,png:GetInt("$realwidth") / png:GetInt("$realheight")}) end -- Top clouds local layers = 4 local sky_mats = {} local offset = {} local params = {} params[ "$basetexture" ] = "" params[ "$translucent" ] = 0 params[ "$vertexalpha" ] = 1 params[ "$vertexcolor" ] = 1 params[ "$nofog" ] = 1 params[ "$nolod" ] = 1 params[ "$nomip" ] = 1 params["$additive"] = 0 for i = 1,layers do sky_mats[i] = CreateMaterial("StormFox_RTSKY" .. i,"UnlitGeneric",params) end local cloudbig = Material("stormfox2/effects/clouds/clouds_big.png","nocull noclamp smooth") -- 8240 cloudbig:SetInt("$flags",2099250) cloudbig:SetFloat("$nocull",1) cloudbig:SetFloat("$nocull",1) cloudbig:SetFloat("$additive",0) local sky_rts = {} local texscale = 512 for i = 1,layers do sky_rts[i] = GetRenderTargetEx( "StormFox_Sky" .. i, texscale, texscale, 1, MATERIAL_RT_DEPTH_NONE, 2, CREATERENDERTARGETFLAGS_UNFILTERABLE_OK, IMAGE_FORMAT_RGBA8888) offset[i] = {i * 99,i * 33} end local function safeCall(...) hook.Run("StormFox2.2DSkybox.CloudLayerRender", ...) end local function UpdateCloudMaterial(layer,cloud_alpha) local blend = true local d_seed = layer * 33 render.PushFilterMag( TEXFILTER.ANISOTROPIC ) render.PushFilterMin( TEXFILTER.ANISOTROPIC ) -- Start RT render RTRender(sky_rts[layer],blend) -- Render RT texture surface.SetMaterial(cloudbig) surface.SetDrawColor(Color(255,255,255,cloud_alpha)) --surface.DrawTexturedRect(0,0,texscale,texscale) DrawTextureRectWindow(texscale,texscale,offset[layer][1] + d_seed,offset[layer][2] + d_seed) -- If we error in here, gmod will crash. local b, reason = pcall(safeCall, texscale, texscale, layer) if not b then ErrorNoHalt(reason) end -- Mask RT tex -- RTMask() -- surface.SetDrawColor(Color(255,255,255,255 - cloud_alpha)) -- surface.SetMaterial(cloudbig) -- DrawTextureRectWindow(texscale,texscale,offset[layer][1] + d_seed,offset[layer][2] + d_seed) -- End RT tex RTEnd(sky_mats[layer]) render.PopFilterMag() render.PopFilterMin() end local col = Color(255,255,255,175) local v = Vector(0,0,-20) local function RenderCloud(mat_id,yaw,s_size,alpha, pos) local mat = side_clouds[mat_id] if not mat then return end render.SetMaterial(mat[1]) local pitch = 0.11 * s_size local n = Angle(pitch,yaw,0):Forward() col.a = math.max(175 * alpha, 255) render.DrawQuadEasy( n * -200 + pos + v, n, s_size * mat[2] , s_size, col, 180 ) end local function LerpColor(f, col1, col2) return Color( Lerp(f, col1.r, col2.r), Lerp(f, col1.g, col2.g), Lerp(f, col1.b, col2.b) ) end -- Cloud movement hook.Add("PreRender","StormFox2.Client.CloudMove",function() local w_ang = rad(StormFox2.Wind.GetYaw()) local w_force = max(StormFox2.Wind.GetForce(),0.1) * 0.08 * RealFrameTime() local x_w,y_w = cos(w_ang) * w_force,sin(w_ang) * w_force for i = 1,layers do local ri = (layers - i + 1) local x,y = offset[i][1],offset[i][2] offset[i] = {x + x_w * ri ,y + y_w * ri} end end) hook.Add("StormFox2.2DSkybox.CloudLayer","StormFox2.Client.Clouds",function(eye) if not StormFox2 then return end if not StormFox2.Mixer then return end local cl_amd = StormFox2.Mixer.Get("clouds",0) --if cl_amd <= 0 then return end -- Update material-color local c = StormFox2.Mixer.Get("bottomColor") or Color(204, 255, 255) -- Render sideclouds local vec = Vector(c.r,c.g,c.b) / 255 for k,v in ipairs(side_clouds) do v[1]:SetVector("$color",vec) end local cloud_speed = StormFox2.Time.GetSpeed_RAW() * 0.1 local sideclouds = 10 * cl_amd for i = 1,sideclouds do local a = 1 if i < sideclouds and i == math.floor(sideclouds) then a = sideclouds - math.floor(sideclouds) end local row = math.floor(i / 3) local m_id = i % #side_clouds + 1 local y_start = (i % 3) * 120 + row * 33 local size = (3 + i % 5) * 24 RenderCloud(m_id,y_start + i + SysTime() * cloud_speed, size, a, eye * eye_mult * 10 * i / 10 ) end -- Render top clouds local up = Vector(0,0,1) local n = max(0,min(math.ceil(layers * cl_amd),layers)) local thunder = 0 if StormFox2.Thunder then thunder = min(255,StormFox2.Thunder.GetLight() or 0) / 25 end for i = 1,n do local ri = n - i + layers local cloud_amplifier = 1 + .4 * (1 - (i / n)) if i == 1 then cloud_amplifier = cloud_amplifier + thunder end UpdateCloudMaterial(i,255) sky_mats[i]:SetVector("$color",Vector(min(c.r * cloud_amplifier,255),min(c.g * cloud_amplifier,255),min(c.b * cloud_amplifier,255)) / 255 ) RenderDome(up * (z_level + 0.4 * ri) + eye * eye_mult,sky_mats[i],255) end end)