Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- config
- if me then
- local allowed = {caps, katie, chess, elmo}
- if not table.HasValue(allowed, LocalPlayer()) then return end
- end
- local STEPS = 512
- local DISTANCE = 4096
- local SECTOR_LIMIT = 4096
- local GRID_SIZE = 256
- --
- local eyepos = Vector(0,0,0)
- hook.Add("RenderScene", "grass", function(pos) eyepos = pos end)
- local DATA = _G.GRASS_DATA or {}
- local DATA_LIST = _G.GRASS_DATA_LIST or {}
- _G.GRASS_DATA = DATA
- _G.GRASS_DATA_LIST = DATA_LIST
- local function round(v)
- return
- math.ceil(v.x/GRID_SIZE) * GRID_SIZE,
- math.ceil(v.y/GRID_SIZE) * GRID_SIZE,
- math.ceil(v.z/GRID_SIZE) * GRID_SIZE
- end
- local function get_sector(pos)
- local x,y,z = round(pos)
- DATA[x] = DATA[x] or {}
- DATA[x][y] = DATA[x][y] or {}
- if not DATA[x][y][z] then
- local data = {points = {}, origin = Vector(x,y,z)}
- table.insert(DATA_LIST, data)
- DATA[x][y][z] = data
- end
- return DATA[x][y][z]
- end
- local temp_vec1 = Vector(0,0,0)
- local params = {}
- params.mask = MASK_SOLID_BRUSHONLY
- local function trace(pos, dir)
- params.start = pos
- temp_vec1.x = pos.x + dir.x
- temp_vec1.y = pos.y + dir.y
- temp_vec1.z = pos.z + dir.z
- params.endpos = temp_vec1
- local res = util.TraceLine(params)
- if res.Hit then
- return {HitPos = res.HitPos, HitNormal = res.HitNormal}
- end
- end
- local random_vectors = {}
- local function update()
- if LocalPlayer():GetVelocity() == vector_origin then return end
- for i = 0, STEPS do
- local dir = VectorRand() * DISTANCE--random_vectors[i] or VectorRand():GetNormalized() * DISTANCE
- --random_vectors[i] = dir
- local res = trace(eyepos, dir)
- if res then
- local data = get_sector(res.HitPos)
- if #data.points < SECTOR_LIMIT then
- table.insert(data.points, res)
- else
- data.done = true
- end
- end
- end
- end
- local meshes = _G.GRASS_MESHES or {}
- _G.GRASS_MESHES = meshes
- local temp_ang = Angle(0,0,0)
- local function rot(vec, yaw)
- temp_ang.y = yaw
- temp_ang.p = math.Rand(-10, 10) * 2
- vec:Rotate(temp_ang)
- return vec
- end
- local up = Vector(0,0,1)
- local right = Vector(0,0,1)
- local gravity = physenv.GetGravity():GetNormalized()
- local function generate_meshes()
- for key, sector in pairs(DATA_LIST) do
- if meshes[key] or not sector.done then continue end
- local mesh = Mesh()
- local triangles = {}
- for _, trace_res in pairs(sector.points) do
- local pos = trace_res.HitPos - sector.origin
- local width = math.Rand(-10, 10)
- local nrm = trace_res.HitNormal
- local x, y = math.sin(pos.x/100), math.cos(pos.y/100)
- local height = math.Rand(10, 30) + math.abs((x^3-3*x+y^3-3*y) * 50)
- local v1 = Vector(0, -width, 0)
- local v2 = Vector(0, 0, 0)
- local v3 = Vector(height, width, 0)
- local ang = nrm:Angle()
- ang:RotateAroundAxis(nrm, math.random(360))
- v1:Rotate(ang)
- v2:Rotate(ang)
- v3:Rotate(ang)
- local c = render.GetAmbientLightColor(trace_res.HitPos)
- c = c + render.GetLightColor(trace_res.HitPos)
- --c = c + render.GetSurfaceColor(trace_res.HitPos, trace_res.HitPos + trace_res.Normal * 5)
- c.r = c.r ^ 0.8
- c.g = c.g ^ 0.8
- c.b = c.b ^ 0.8
- c = c * 255 * 2
- c = Color(c.r, c.g, c.b)
- local c2 = Color(c.r / 3, c.g / 3, c.b / 3)
- table.insert(triangles, {u = 1, v = -0, pos = pos + v1, color = c})
- table.insert(triangles, {u = 0, v = -0, pos = pos + v2, color = c2})
- table.insert(triangles, {u = 0.5, v = -1, pos = pos + v3, color = c})
- end
- mesh:BuildFromTriangles(triangles)
- local data = {}
- data.origin = sector.origin
- data.mesh = mesh
- data.pixvis = util.GetPixelVisibleHandle()
- data.rand = math.random()
- meshes[key] = data
- end
- end
- local matrix = Matrix()
- local material = CreateMaterial("grass_lol_" .. os.clock(), "UnlitGeneric",{
- ["$basetexture"] = "models/props_swamp/tallgrass_01",
- ["$vertexcolor"] = 1,
- })
- local lol = ClientsideModel("error.mdl")
- lol:SetModelScale(0,0)
- local temp_vec = Vector(1,1,1)
- local function draw(data)
- render.CullMode(1)
- data.mesh:Draw()
- render.CullMode(0)
- data.mesh:Draw()
- end
- hook.Add("PostDrawOpaqueRenderables", "grass", function()
- local eyepos = LocalPlayer():EyePos()
- local t = RealTime()
- lol:DrawModel()
- render.SetMaterial(material)
- for _, data in pairs(meshes) do
- local alpha = util.PixelVisible(data.origin, GRID_SIZE*2, data.pixvis)
- if alpha > 0 or data.origin:Distance(eyepos) < GRID_SIZE*2 then
- matrix:SetTranslation(data.origin)
- cam.PushModelMatrix(matrix)
- draw(data)
- cam.PopModelMatrix()
- end
- end
- -- if #meshes < 10 then
- update()
- --if math.random() > 0.99 then
- generate_meshes()
- --end
- -- end
- end)
- KillGrass = function()
- hook.Remove("PostDrawOpaqueRenderables", "grass")
- GRASS_DATA = nil
- GRASS_DATA_LIST = nil
- GRASS_MESHES = nil
- collectgarbage("collect")
- end
Add Comment
Please, Sign In to add comment