From 109dc28abecf3bb64659634868985415342802d2 Mon Sep 17 00:00:00 2001 From: Meetric <73554599+meetric1@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:45:34 -0400 Subject: [PATCH] do sprite rotation in vertex shader --- binary/src/flex_renderer.cpp | 126 ++++-------------- binary/src/flex_renderer.h | 2 + binary/src/flex_solver.cpp | 32 ++--- binary/src/flex_solver.h | 2 +- binary/src/shaders/GWaterNormals.h | 6 +- .../src/shaders/fxc/GWaterFinalpass_ps30.fxc | 4 +- binary/src/shaders/fxc/GWaterNormals_ps30.fxc | 3 +- binary/src/shaders/fxc/GWaterNormals_vs30.fxc | 53 +++++--- lua/autorun/client/gwater_menu2.lua | 6 +- lua/autorun/gwater2_init.lua | 4 +- lua/entities/gwater2_emitter.lua | 33 +++++ lua/gwater2_shaders.lua | 8 +- 12 files changed, 129 insertions(+), 150 deletions(-) create mode 100644 lua/entities/gwater2_emitter.lua diff --git a/binary/src/flex_renderer.cpp b/binary/src/flex_renderer.cpp index 8f40e5a..980a91d 100644 --- a/binary/src/flex_renderer.cpp +++ b/binary/src/flex_renderer.cpp @@ -1,5 +1,5 @@ #include "flex_renderer.h" -#include "cdll_client_int.h" +#include "cdll_client_int.h" //IVEngineClient extern IVEngineClient* engine = NULL; @@ -23,7 +23,7 @@ IMesh* _build_water_anisotropy(int id, FlexRendererThreadData data) { // Frustrum culling Vector4D dst; Vector4DMultiply(data.view_projection_matrix, Vector4D(particle_pos.x, particle_pos.y, particle_pos.z, 1), dst); - if (dst.z < data.radius || -dst.x - dst.w > data.radius || dst.x - dst.w > data.radius || -dst.y - dst.w > data.radius || dst.y - dst.w > data.radius) continue; + if (dst.z < 0 || -dst.x - dst.w > data.radius || dst.x - dst.w > data.radius || -dst.y - dst.w > data.radius || dst.y - dst.w > data.radius) continue; // PVS Culling if (!engine->IsBoxVisible(particle_pos, particle_pos)) continue; @@ -33,100 +33,27 @@ IMesh* _build_water_anisotropy(int id, FlexRendererThreadData data) { particles_to_render++; } - - // TODO: Try probe a bunch of points in a grid for lighting and blend smoothly between them - // Vector colour = engine->GetLightForPoint(particle_pos, false); - // Don't even bother if (particles_to_render == 0) return nullptr; - float scale_mult = 10.f / data.radius; // no fucking clue why this works - float inv_scale_mult = data.radius / 10.f; // microoptimization - - IMesh* mesh = materials->GetRenderContext()->CreateStaticMesh(VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D, ""); + IMesh* mesh = materials->GetRenderContext()->CreateStaticMesh(VERTEX_GWATER2, ""); CMeshBuilder mesh_builder; mesh_builder.Begin(mesh, MATERIAL_TRIANGLES, particles_to_render); for (int i = start; i < start + particles_to_render; ++i) { int particle_index = data.render_buffer[i]; - Vector particle_pos = data.particle_positions[particle_index].AsVector3D(); - // calculate triangle rotation - //Vector forward = (eye_pos - particle_pos).Normalized(); - Vector forward = (particle_pos - data.eye_pos).Normalized(); - Vector right = forward.Cross(Vector(0, 0, 1)).Normalized(); - Vector up = right.Cross(forward); - Vector local_pos[3] = { (-up - right * SQRT3), up * 2.0, (-up + right * SQRT3) }; // equalateral triangle - - Vector4D ani0 = data.particle_ani0[particle_index]; ani0.w *= scale_mult; - Vector4D ani1 = data.particle_ani1[particle_index]; ani1.w *= scale_mult; - Vector4D ani2 = data.particle_ani2[particle_index]; ani2.w *= scale_mult; + Vector4D particle_pos = data.particle_positions[particle_index]; + Vector4D ani0 = data.particle_ani0 ? data.particle_ani0[particle_index] : Vector4D(0, 0, 0, 0); + Vector4D ani1 = data.particle_ani1 ? data.particle_ani1[particle_index] : Vector4D(0, 0, 0, 0); + Vector4D ani2 = data.particle_ani2 ? data.particle_ani2[particle_index] : Vector4D(0, 0, 0, 0); for (int i = 0; i < 3; i++) { - // Anisotropy warping (code provided by Spanky) - Vector pos_ani = local_pos[i] * inv_scale_mult; - float dot0 = pos_ani.Dot(ani0.AsVector3D()) * ani0.w; - float dot1 = pos_ani.Dot(ani1.AsVector3D()) * ani1.w; - float dot2 = pos_ani.Dot(ani2.AsVector3D()) * ani2.w; - - pos_ani += ani0.AsVector3D() * dot0 + ani1.AsVector3D() * dot1 + ani2.AsVector3D() * dot2; - - Vector world_pos = particle_pos + pos_ani; mesh_builder.TexCoord2f(0, u[i], v[i]); - mesh_builder.Position3f(world_pos.x, world_pos.y, world_pos.z); - mesh_builder.Normal3f(-forward.x, -forward.y, -forward.z); - mesh_builder.AdvanceVertex(); - } - } - mesh_builder.End(); - - return mesh; -} - -// Builds meshes of water particles without anisotropy -IMesh* _build_water(int id, FlexRendererThreadData data) { - int start = id * MAX_PRIMATIVES; - int end = min((id + 1) * MAX_PRIMATIVES, data.max_particles); - - // We need to figure out how many and which particles are going to be rendered - int particles_to_render = 0; - for (int particle_index = start; particle_index < end; ++particle_index) { - Vector particle_pos = data.particle_positions[particle_index].AsVector3D(); - - // Frustrum culling - Vector4D dst; - Vector4DMultiply(data.view_projection_matrix, Vector4D(particle_pos.x, particle_pos.y, particle_pos.z, 1), dst); - if (dst.z < data.radius || -dst.x - dst.w > data.radius || dst.x - dst.w > data.radius || -dst.y - dst.w > data.radius || dst.y - dst.w > data.radius) continue; - - // PVS Culling - if (!engine->IsBoxVisible(particle_pos, particle_pos)) continue; - - // Add to our buffer - data.render_buffer[start + particles_to_render] = particle_index; - particles_to_render++; - } - - // Don't even bother - if (particles_to_render == 0) return nullptr; - - IMesh* mesh = materials->GetRenderContext()->CreateStaticMesh(VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D, ""); - CMeshBuilder mesh_builder; - mesh_builder.Begin(mesh, MATERIAL_TRIANGLES, particles_to_render); - for (int i = start; i < start + particles_to_render; ++i) { - int particle_index = data.render_buffer[i]; - Vector particle_pos = data.particle_positions[particle_index].AsVector3D(); - - // calculate triangle rotation - //Vector forward = (eye_pos - particle_pos).Normalized(); - Vector forward = (particle_pos - data.eye_pos).Normalized(); - Vector right = forward.Cross(Vector(0, 0, 1)).Normalized(); - Vector up = right.Cross(forward); - Vector local_pos[3] = { (-up - right * SQRT3) * 0.5, up, (-up + right * SQRT3) * 0.5 }; - - for (int i = 0; i < 3; i++) { // Same as above w/o anisotropy warping - Vector world_pos = particle_pos + local_pos[i] * data.radius; - mesh_builder.TexCoord2f(0, u[i], v[i]); - mesh_builder.Position3f(world_pos.x, world_pos.y, world_pos.z); - mesh_builder.Normal3f(-forward.x, -forward.y, -forward.z); + mesh_builder.TexCoord4f(1, ani0.x, ani0.y, ani0.z, ani0.w); // shove anisotropy in + mesh_builder.TexCoord4f(2, ani1.x, ani1.y, ani1.z, ani1.w); + mesh_builder.TexCoord4f(3, ani2.x, ani2.y, ani2.z, ani2.w); + mesh_builder.Position3f(particle_pos.x, particle_pos.y, particle_pos.z); + //mesh_builder.Normal3f(-forward.x, -forward.y, -forward.z); mesh_builder.AdvanceVertex(); } } @@ -222,27 +149,24 @@ void FlexRenderer::build_meshes(FlexSolver* flex, float diffuse_radius) { bool particle_ani = flex->get_parameter("anisotropy_scale") != 0; // Should we do anisotropy calculations? float radius = flex->get_parameter("radius"); - // Water particles - int max_meshes = min(ceil(max_particles / (float)MAX_PRIMATIVES), allocated); - for (int mesh_index = 0; mesh_index < max_meshes; mesh_index++) { - // update thread data - FlexRendererThreadData data; - data.eye_pos = eye_pos; - data.view_projection_matrix = view_projection_matrix; - data.particle_positions = particle_positions; - data.max_particles = max_particles; - data.radius = radius; + // thread data + FlexRendererThreadData data; + data.eye_pos = eye_pos; + data.view_projection_matrix = view_projection_matrix; + data.particle_positions = particle_positions; + data.max_particles = max_particles; + data.radius = radius; + data.render_buffer = water_buffer; + if (flex->get_parameter("anisotropy_scale") != 0) { // Should we do anisotropy calculations? data.particle_ani0 = particle_ani0; data.particle_ani1 = particle_ani1; data.particle_ani2 = particle_ani2; - data.render_buffer = water_buffer; + } + int max_meshes = min(ceil(max_particles / (float)MAX_PRIMATIVES), allocated); + for (int mesh_index = 0; mesh_index < max_meshes; mesh_index++) { // Launch thread - if (particle_ani) { - queue[mesh_index] = threads->enqueue(_build_water_anisotropy, mesh_index, data); - } else { - queue[mesh_index] = threads->enqueue(_build_water, mesh_index, data); - } + queue[mesh_index] = threads->enqueue(_build_water_anisotropy, mesh_index, data); } // Diffuse particles diff --git a/binary/src/flex_renderer.h b/binary/src/flex_renderer.h index a20791e..3966689 100644 --- a/binary/src/flex_renderer.h +++ b/binary/src/flex_renderer.h @@ -1,4 +1,5 @@ #pragma once + #include #include #include "meshutils.h" // Fixes linker errors @@ -11,6 +12,7 @@ #define MAX_PRIMATIVES 21845 #define MAX_THREADS 16 #define SQRT3 1.73205081 +#define VERTEX_GWATER2 VERTEX_POSITION | VERTEX_TEXCOORD0_2D | VERTEX_NORMAL | VERTEX_TEXCOORD_SIZE(1, 4) | VERTEX_TEXCOORD_SIZE(2, 4) | VERTEX_TEXCOORD_SIZE(3, 4) struct FlexRendererThreadData { //IMesh*& water; diff --git a/binary/src/flex_solver.cpp b/binary/src/flex_solver.cpp index 37509d6..c8259ce 100644 --- a/binary/src/flex_solver.cpp +++ b/binary/src/flex_solver.cpp @@ -52,7 +52,7 @@ int FlexSolver::get_max_contacts() { return solver_description.maxContactsPerParticle; } -void* FlexSolver::get_host(std::string name) { +inline void* FlexSolver::get_host(std::string name) { return hosts[name]; } @@ -62,14 +62,14 @@ std::vector* FlexSolver::get_meshes() { // Resets particle to base parameters void FlexSolver::set_particle(int index, Particle particle) { - ((Vector4D*)hosts["particle_pos"])[index] = particle.pos; - ((Vector*)hosts["particle_vel"])[index] = particle.vel; - ((int*)hosts["particle_phase"])[index] = NvFlexMakePhase(0, eNvFlexPhaseSelfCollide | eNvFlexPhaseFluid); - ((int*)hosts["particle_active"])[index] = index; - ((Vector4D*)hosts["particle_smooth"])[index] = particle.pos; - ((Vector4D*)hosts["particle_ani0"])[index] = Vector4D(0, 0, 0, 0); - ((Vector4D*)hosts["particle_ani1"])[index] = Vector4D(0, 0, 0, 0); - ((Vector4D*)hosts["particle_ani2"])[index] = Vector4D(0, 0, 0, 0); + ((Vector4D*)get_host("particle_pos"))[index] = particle.pos; + ((Vector*)get_host("particle_vel"))[index] = particle.vel; + ((int*)get_host("particle_phase"))[index] = NvFlexMakePhase(0, eNvFlexPhaseSelfCollide | eNvFlexPhaseFluid); + ((int*)get_host("particle_active"))[index] = index; + ((Vector4D*)get_host("particle_smooth"))[index] = particle.pos; + ((Vector4D*)get_host("particle_ani0"))[index] = Vector4D(0, 0, 0, 0); + ((Vector4D*)get_host("particle_ani1"))[index] = Vector4D(0, 0, 0, 0); + ((Vector4D*)get_host("particle_ani2"))[index] = Vector4D(0, 0, 0, 0); } void FlexSolver::add_particle(Particle particle) { @@ -127,19 +127,13 @@ bool FlexSolver::tick(float dt, NvFlexMapFlags wait) { Vector4D* particle_pos = (Vector4D*)NvFlexMap(get_buffer("particle_pos"), wait); if (particle_pos) { // Add queued particles - Vector* particle_vel = (Vector*)hosts["particle_vel"]; - int* particle_phase = (int*)hosts["particle_phase"]; - int* particle_active = (int*)hosts["particle_active"]; - Vector4D* particle_smooth = (Vector4D*)hosts["particle_smooth"]; - Vector4D* particle_ani0 = (Vector4D*)hosts["particle_ani0"]; - Vector4D* particle_ani1 = (Vector4D*)hosts["particle_ani1"]; - Vector4D* particle_ani2 = (Vector4D*)hosts["particle_ani2"]; - for (int i = 0; i < particle_queue.size(); i++) { int particle_index = copy_description->elementCount + i; set_particle(particle_index, particle_queue[i]); } + NvFlexUnmap(get_buffer("particle_pos")); + // Only copy what we just added NvFlexCopyDesc desc; desc.dstOffset = copy_description->elementCount; @@ -152,11 +146,9 @@ bool FlexSolver::tick(float dt, NvFlexMapFlags wait) { NvFlexSetPhases(solver, get_buffer("particle_phase"), &desc); NvFlexSetActive(solver, get_buffer("particle_active"), &desc); NvFlexSetActiveCount(solver, get_active_particles()); - + copy_description->elementCount += particle_queue.size(); particle_queue.clear(); - - NvFlexUnmap(get_buffer("particle_pos")); } else { return false; } diff --git a/binary/src/flex_solver.h b/binary/src/flex_solver.h index 76eba85..f7ea502 100644 --- a/binary/src/flex_solver.h +++ b/binary/src/flex_solver.h @@ -41,7 +41,7 @@ class FlexSolver { std::vector* get_meshes(); inline NvFlexBuffer* get_buffer(std::string name); - void* get_host(std::string name); // Returns a host (pointer of float4s) where FleX buffer data is transferred to. + inline void* get_host(std::string name); // Returns a host (pointer of float4s) where FleX buffer data is transferred to. void add_particle(Particle particle); void set_particle(int index, Particle particle); diff --git a/binary/src/shaders/GWaterNormals.h b/binary/src/shaders/GWaterNormals.h index 645993e..4fa3077 100644 --- a/binary/src/shaders/GWaterNormals.h +++ b/binary/src/shaders/GWaterNormals.h @@ -27,7 +27,8 @@ SHADER_DRAW { SHADOW_STATE { // Note: Removing VERTEX_COLOR makes the shader work on all objects (Like props) - unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TEXCOORD0_2D; + unsigned int flags = VERTEX_GWATER2; + pShaderShadow->VertexShaderVertexFormat(flags, 1, 0, 0); DECLARE_STATIC_VERTEX_SHADER(GWaterNormals_vs30); @@ -44,6 +45,7 @@ SHADER_DRAW { const bool depthfix = params[DEPTHFIX]->GetIntValue(); pShaderAPI->SetPixelShaderConstant(0, &radius); + pShaderAPI->SetVertexShaderConstant(5, &radius); // first 4 constants are in use DECLARE_DYNAMIC_VERTEX_SHADER(GWaterNormals_vs30); SET_DYNAMIC_VERTEX_SHADER(GWaterNormals_vs30); @@ -51,6 +53,8 @@ SHADER_DRAW { DECLARE_DYNAMIC_PIXEL_SHADER(GWaterNormals_ps30); SET_DYNAMIC_PIXEL_SHADER_COMBO(DEPTH, depthfix); SET_DYNAMIC_PIXEL_SHADER(GWaterNormals_ps30); + + } Draw(); diff --git a/binary/src/shaders/fxc/GWaterFinalpass_ps30.fxc b/binary/src/shaders/fxc/GWaterFinalpass_ps30.fxc index a61d44c..1a93179 100644 --- a/binary/src/shaders/fxc/GWaterFinalpass_ps30.fxc +++ b/binary/src/shaders/fxc/GWaterFinalpass_ps30.fxc @@ -103,7 +103,7 @@ float4 main(const PS_INPUT i) : COLOR { DoSpecularFlashlight(g_FlashlightPos, i.pos, flashlightSpacePosition, smoothed_normal, g_FlashlightAttenuationFactors.xyz, g_FlashlightAttenuationFactors.w, FlashlightSampler, ShadowDepthSampler, NormalizeRandRotSampler, FLASHLIGHTDEPTHFILTERMODE, FLASHLIGHTSHADOWS, true, projPos, - SpecularExponent, i.view_dir * -1, false, FRAMEBUFFER, 0, g_ShadowTweaks, + SpecularExponent, -i.view_dir, false, FRAMEBUFFER, 0, g_ShadowTweaks, // These two values are output diffuseLightingFL, specularLightingFL); @@ -125,7 +125,7 @@ float4 main(const PS_INPUT i) : COLOR { float3 rimLightingLL; float3 specularLightingLL; PixelShaderDoSpecularLighting(i.pos, smoothed_normal, - SpecularExponent, i.view_dir * -1, i.lightAtten, + SpecularExponent, -i.view_dir, i.lightAtten, NUM_LIGHTS, cLightInfo, false, 0, false, FRAMEBUFFER, 0, false, 1, // Outputs diff --git a/binary/src/shaders/fxc/GWaterNormals_ps30.fxc b/binary/src/shaders/fxc/GWaterNormals_ps30.fxc index b028fbf..1754c8c 100644 --- a/binary/src/shaders/fxc/GWaterNormals_ps30.fxc +++ b/binary/src/shaders/fxc/GWaterNormals_ps30.fxc @@ -6,7 +6,7 @@ struct PS_INPUT { float2 P : VPOS; float2 coord : TEXCOORD0; float3 pos : TEXCOORD1; - float4x4 proj : TEXCOORD3; + float4x4 proj : TEXCOORD2; float3x3 normal : NORMAL0; }; @@ -40,6 +40,7 @@ PS_OUTPUT main(const PS_INPUT i) { // Output colors to rendertargets PS_OUTPUT o = (PS_OUTPUT)0; o.rt0 = float4(world_normal, bulge_pos.z); + //o.rt0 = float4(i.coord.x, i.coord.y, 0, bulge_pos.z); o.rt1 = float4(uvdmax, 0, 0, 1); #if DEPTH o.depth = bulge_pos.z / bulge_pos.w; diff --git a/binary/src/shaders/fxc/GWaterNormals_vs30.fxc b/binary/src/shaders/fxc/GWaterNormals_vs30.fxc index b29cc33..4bdd7ce 100644 --- a/binary/src/shaders/fxc/GWaterNormals_vs30.fxc +++ b/binary/src/shaders/fxc/GWaterNormals_vs30.fxc @@ -1,36 +1,59 @@ #include "common_vs_fxc.h" +float RADIUS : register(c5); + struct VS_INPUT { float4 vPos : POSITION; // Position - float4 vNormal : NORMAL0; // Normal float4 vTexCoord : TEXCOORD0; // Texture coordinates + float4 ani0 : TEXCOORD1; // cursed anisotropy (we have to shove it in the vertex shader) + float4 ani1 : TEXCOORD2; // its joever + float4 ani2 : TEXCOORD3; }; struct VS_OUTPUT { - float4 projPosSetup : POSITION; // Register 1 - float4 coord : TEXCOORD0; // Register 2 - float3 pos : TEXCOORD1; // Register 3 - float3x3 normal : NORMAL0; // Registers 8 9 10 - float4x4 proj : TEXCOORD3; // Registers 4 5 6 7 + float4 projPosSetup : POSITION; // Register 0 + float4 coord : TEXCOORD0; // Register 1 + float3 pos : TEXCOORD1; // Register 2 + float4x4 proj : TEXCOORD2; // Registers 3 4 5 6 + float3x3 normal : NORMAL0; // Registers 7 8 9 }; VS_OUTPUT main(const VS_INPUT v) { VS_OUTPUT o = (VS_OUTPUT)0; + + // Extract real position + float3 world_pos; + SkinPosition(0, v.vPos, 0, 0, world_pos); + + // extract normal / right and up + float3 world_normal = normalize(cEyePos - world_pos); + float3 right = normalize(cross(world_normal, float3(0, 0, 1))); + float3 up = cross(world_normal, right); + + // to avoid extrusion calculations (above) being called on CPU, we do them here + float3 world_pos_offset = -right * (v.vTexCoord.x - 0.5) + up * (v.vTexCoord.y - 0.5); + world_pos_offset *= (RADIUS * 0.1); - // Extract real position & normal - float3 world_normal, world_pos; - SkinPositionAndNormal(0, v.vPos, v.vNormal, 0, 0, world_pos, world_normal); + //float scale_mult = 10.f / data.radius; // no fucking clue why this works + //float inv_scale_mult = data.radius / 10.f; // microoptimization - float4 vProjPos = mul(float4(world_pos, 1), cViewProj); - vProjPos.z = dot(float4(world_pos, 1), cViewProjZ); // wtf does this even do? + // Anisotropy warping + float dot0 = dot(world_pos_offset, v.ani0.xyz) * v.ani0.w; + float dot1 = dot(world_pos_offset, v.ani1.xyz) * v.ani1.w; + float dot2 = dot(world_pos_offset, v.ani2.xyz) * v.ani2.w; + world_pos_offset += (v.ani0.xyz * dot0 + v.ani1.xyz * dot1 + v.ani2.xyz * dot2); + world_pos_offset *= RADIUS; + //world_pos_offset += (v.ani1 * dot1); + + float3 extruded_world_pos = world_pos + world_pos_offset; + + float4 vProjPos = mul(float4(extruded_world_pos, 1), cViewProj); + //vProjPos.z = dot(float4(extruded_world_pos, 1), cViewProjZ); // wtf does this even do? o.projPosSetup = vProjPos; o.coord = v.vTexCoord; - o.pos = world_pos; + o.pos = extruded_world_pos; o.proj = cViewProj; // Used in spherical depth - - float3 right = normalize(cross(world_normal, float3(0, 0, 1))); - float3 up = cross(world_normal, right); o.normal = float3x3( -right.x, -right.y, -right.z, world_normal.x, world_normal.y, world_normal.z, diff --git a/lua/autorun/client/gwater_menu2.lua b/lua/autorun/client/gwater_menu2.lua index b375525..6a6dc22 100644 --- a/lua/autorun/client/gwater_menu2.lua +++ b/lua/autorun/client/gwater_menu2.lua @@ -460,8 +460,8 @@ concommand.Add("gwater2_menu", function() -- 2d simulation local mat = Matrix() - mat:Translate(Vector(x + 60 + math.random(), 0, y + 50)) - mat:Scale(Vector(1, 1, 1) * options.solver:GetParameter("fluid_rest_distance")) + mat:SetScale(Vector(1, 1, 1) * options.solver:GetParameter("fluid_rest_distance")) + mat:SetTranslation(Vector(x + 60 + math.random(), 0, y + 50)) options.solver:InitBounds(Vector(x, 0, y + 25), Vector(x + 192, options.solver:GetParameter("radius"), y + 390)) options.solver:AddCube(mat, Vector(4, 1, 1), {vel = Vector(0, 0, 50)}) options.solver:Tick(1 / 60) @@ -536,7 +536,7 @@ concommand.Add("gwater2_menu", function() create_label(scrollPanel, "Advanced Physics Parameters", "More technical settings.", 275, 182) labels[8], sliders["Collision Distance"] = create_slider(scrollPanel, "Collision Distance", 0.1, 1, 2, 327, 315, 55) - labels[9], sliders["Fluid Rest Distance"] = create_slider(scrollPanel, "Fluid Rest Distance", 0.55, 0.85, 2, 357, 315, 55) + labels[9], sliders["Fluid Rest Distance"] = create_slider(scrollPanel, "Fluid Rest Distance", 0.55, 0.75, 2, 357, 315, 55) labels[10], sliders["Dynamic Friction"] = create_slider(scrollPanel, "Dynamic Friction", 0, 1, 2, 387, 315, 55) labels[11], sliders["Vorticity Confinement"] = create_slider(scrollPanel, "Vorticity Confinement", 0, 200, 0, 417, 300, 75) diff --git a/lua/autorun/gwater2_init.lua b/lua/autorun/gwater2_init.lua index 1d329eb..eb12655 100644 --- a/lua/autorun/gwater2_init.lua +++ b/lua/autorun/gwater2_init.lua @@ -170,7 +170,7 @@ local function gwater_tick2() gwater2.solver:IterateMeshes(gwater2.update_meshes) hook.Run("gwater2_pretick") - gwater2.solver:Tick(limit_fps, 0) + gwater2.solver:Tick(FrameTime(), 0) end // run whenever possible, as often as possible. we dont know when flex will finish calculations @@ -182,7 +182,7 @@ hook.Add("Think", "gwater_tick", function() gwater2.solver:IterateMeshes(gwater2.update_meshes) end) -timer.Create("gwater2_tick", limit_fps, 0, function() +timer.Create("gwater2_tick", 0, 0, function() if !gwater2.new_ticker then return end gwater_tick2() end) diff --git a/lua/entities/gwater2_emitter.lua b/lua/entities/gwater2_emitter.lua new file mode 100644 index 0000000..30ee788 --- /dev/null +++ b/lua/entities/gwater2_emitter.lua @@ -0,0 +1,33 @@ +AddCSLuaFile() + +ENT.Type = "anim" +ENT.Base = "base_gmodentity" + +ENT.Category = "GWater2" +ENT.PrintName = "Emitter" +ENT.Author = "Mee" +ENT.Purpose = "" +ENT.Instructions = "" +ENT.Spawnable = true + +function ENT:Initialize() + if CLIENT then + hook.Add("gwater2_pretick", self, function() + local mat = Matrix() + mat:SetScale(Vector(6.5, 6.5, 6.5)) + mat:SetAngles(self:LocalToWorldAngles(Angle(0, CurTime() * 200, 0))) + mat:SetTranslation(self:GetPos() + self:GetUp() * 10) + + gwater2.solver:AddCube(mat, Vector(10, 1, 1), {vel = self:GetUp() * 60}) + end) + else + self:SetModel("models/mechanics/wheels/wheel_speed_72.mdl") + self:PhysicsInit(SOLID_VPHYSICS) + self:SetMoveType(MOVETYPE_VPHYSICS) + self:SetSolid(SOLID_VPHYSICS) + end +end + +function ENT:OnRemove() + hook.Remove("gwater2_pretick", self) +end \ No newline at end of file diff --git a/lua/gwater2_shaders.lua b/lua/gwater2_shaders.lua index dfe8610..e55c8d4 100644 --- a/lua/gwater2_shaders.lua +++ b/lua/gwater2_shaders.lua @@ -125,13 +125,13 @@ hook.Add("PostDrawOpaqueRenderables", "gwater2_render", function(depth, sky, sky -- grab normals water_normals:SetFloat("$radius", radius * 0.5) render.SetMaterial(water_normals) - render.PushRenderTarget(cache_normals) + --render.PushRenderTarget(cache_normals) render.SetRenderTargetEx(1, cache_depth) render.ClearDepth() gwater2.renderer:DrawWater() - render.PopRenderTarget() + --render.PopRenderTarget() render.SetRenderTargetEx(1, nil) - + /* -- Blur normals water_blur:SetFloat("$radius", radius) water_blur:SetTexture("$depthtexture", cache_depth) @@ -165,7 +165,7 @@ hook.Add("PostDrawOpaqueRenderables", "gwater2_render", function(depth, sky, sky render.OverrideAlphaWriteEnable(false, false) render.SetMaterial(water_mist) - gwater2.renderer:DrawDiffuse() + gwater2.renderer:DrawDiffuse()*/ -- Debug Draw local dbg = 0