mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
276 lines
9.1 KiB
Lua
276 lines
9.1 KiB
Lua
--[[
|
|
| 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) |