From 15c4bb50c93dd005870671b9d5e3edb4ff8a0b8c Mon Sep 17 00:00:00 2001 From: Cloudwalk Date: Mon, 10 Aug 2020 07:47:06 -0400 Subject: [PATCH] gl: Ported !29 to master --- gl_rmain.c | 35 ++++++++++++++++++++++++++++++----- render.h | 2 ++ shader_glsl.h | 47 ++++++++++++++++++++++++++--------------------- 3 files changed, 58 insertions(+), 26 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 19f97cf8..6d437892 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -201,6 +201,7 @@ cvar_t r_water_reflectdistort = {CVAR_CLIENT | CVAR_SAVE, "r_water_reflectdistor cvar_t r_water_scissormode = {CVAR_CLIENT, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"}; cvar_t r_water_lowquality = {CVAR_CLIENT, "r_water_lowquality", "0", "special option to accelerate water rendering: 1 disables all dynamic lights, 2 disables particles too"}; cvar_t r_water_hideplayer = {CVAR_CLIENT | CVAR_SAVE, "r_water_hideplayer", "0", "if set to 1 then player will be hidden in refraction views, if set to 2 then player will also be hidden in reflection views, player is always visible in camera views"}; +cvar_t r_water_clipplayerinreflection = {CVAR_CLIENT | CVAR_SAVE, "r_water_clipplayerinreflection", "-1", "if set to -1 the player will not be clipped in the reflection view, else it will be clipped at the given value"}; cvar_t r_lerpsprites = {CVAR_CLIENT | CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"}; cvar_t r_lerpmodels = {CVAR_CLIENT | CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"}; @@ -771,6 +772,7 @@ typedef struct r_glsl_permutation_s int loc_DeferredMod_Specular; int loc_DistortScaleRefractReflect; int loc_EyePosition; + int loc_EyeDirection; int loc_FogColor; int loc_FogHeightFade; int loc_FogPlane; @@ -1206,6 +1208,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode p->loc_DeferredMod_Specular = qglGetUniformLocation(p->program, "DeferredMod_Specular"); p->loc_DistortScaleRefractReflect = qglGetUniformLocation(p->program, "DistortScaleRefractReflect"); p->loc_EyePosition = qglGetUniformLocation(p->program, "EyePosition"); + p->loc_EyeDirection = qglGetUniformLocation(p->program, "EyeDirection"); p->loc_FogColor = qglGetUniformLocation(p->program, "FogColor"); p->loc_FogHeightFade = qglGetUniformLocation(p->program, "FogHeightFade"); p->loc_FogPlane = qglGetUniformLocation(p->program, "FogPlane"); @@ -1988,6 +1991,7 @@ void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdif if (r_glsl_permutation->loc_Color_Glow >= 0) qglUniform3f(r_glsl_permutation->loc_Color_Glow, t->render_glowmod[0], t->render_glowmod[1], t->render_glowmod[2]); if (r_glsl_permutation->loc_Alpha >= 0) qglUniform1f(r_glsl_permutation->loc_Alpha, t->currentalpha * ((t->basematerialflags & MATERIALFLAG_WATERSHADER && r_fb.water.enabled && !r_refdef.view.isoverlay) ? t->r_water_wateralpha : 1)); if (r_glsl_permutation->loc_EyePosition >= 0) qglUniform3f(r_glsl_permutation->loc_EyePosition, rsurface.localvieworigin[0], rsurface.localvieworigin[1], rsurface.localvieworigin[2]); + if (r_glsl_permutation->loc_EyeDirection >= 0) qglUniform3f(r_glsl_permutation->loc_EyeDirection, rsurface.localviewdirection[0], rsurface.localviewdirection[1], rsurface.localviewdirection[2]); if (r_glsl_permutation->loc_Color_Pants >= 0) { if (t->pantstexture) @@ -3369,6 +3373,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_water_scissormode); Cvar_RegisterVariable(&r_water_lowquality); Cvar_RegisterVariable(&r_water_hideplayer); + Cvar_RegisterVariable(&r_water_clipplayerinreflection); Cvar_RegisterVariable(&r_lerpsprites); Cvar_RegisterVariable(&r_lerpmodels); @@ -4444,10 +4449,7 @@ static void R_View_UpdateWithScissor(const int *myscissor) static void R_View_Update(void) { - R_Main_ResizeViewCache(); - R_View_SetFrustum(NULL); - R_View_WorldVisibility(!r_refdef.view.usevieworiginculling); - R_View_UpdateEntityVisible(); + R_View_UpdateWithScissor(NULL); } float viewscalefpsadjusted = 1.0f; @@ -4829,6 +4831,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t r_waterstate_waterplane_t *p; vec3_t visorigin; r_rendertarget_t *rt; + float dotProduct, normalLength, planeDist; originalview = r_refdef.view; @@ -4899,6 +4902,17 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t r_refdef.view.clipplane = p->plane; // reflected view origin may be in solid, so don't cull with it r_refdef.view.usevieworiginculling = false; + + dotProduct = DotProduct(p->plane.normal, r_refdef.view.origin); + normalLength = VectorLength(p->plane.normal); + planeDist = dotProduct/normalLength - p->plane.dist; + if(planeDist > 100) + r_refdef.view.clipplane.dist += 100.0; + else if(planeDist < -100) + r_refdef.view.clipplane.dist -= 100.0; + else + r_refdef.view.clipplane.dist += 0.95*planeDist; + // reverse the cullface settings for this render r_refdef.view.cullface_front = GL_FRONT; r_refdef.view.cullface_back = GL_BACK; @@ -4912,7 +4926,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t memset(r_refdef.viewcache.world_pvsbits, 0xFF, r_refdef.scene.worldmodel->brush.num_pvsclusterbytes); } - r_fb.water.hideplayer = ((r_water_hideplayer.integer >= 2) && !chase_active.integer); + r_fb.water.hideplayer = ((r_water_hideplayer.integer >= 2) && !chase_active.integer) || (abs(planeDist) < r_water_clipplayerinreflection.value); R_ResetViewRendering3D(rt->fbo, rt->depthtexture, rt->colortexture[0], 0, 0, rt->texturewidth, rt->textureheight); GL_ScissorTest(false); R_ClearScreen(r_refdef.fogenabled); @@ -4965,6 +4979,15 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t r_refdef.view.clipplane = p->plane; VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal); r_refdef.view.clipplane.dist = -r_refdef.view.clipplane.dist; + dotProduct = DotProduct(p->plane.normal, r_refdef.view.origin); + normalLength = VectorLength(p->plane.normal); + planeDist = dotProduct/normalLength - p->plane.dist; + if(planeDist > 100) + r_refdef.view.clipplane.dist -= 100.0; + else if(planeDist < -100) + r_refdef.view.clipplane.dist += 100.0; + else + r_refdef.view.clipplane.dist -= 0.95*planeDist; if((p->materialflags & MATERIALFLAG_CAMERA) && p->camera_entity) { @@ -6986,6 +7009,7 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.inversematrixscale = 1.0f / rsurface.matrixscale; R_EntityMatrix(&rsurface.matrix); Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.origin, rsurface.localvieworigin); + Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.forward, rsurface.localviewdirection); Matrix4x4_TransformStandardPlane(&rsurface.inversematrix, r_refdef.fogplane[0], r_refdef.fogplane[1], r_refdef.fogplane[2], r_refdef.fogplane[3], rsurface.fogplane); rsurface.fogplaneviewdist = r_refdef.fogplaneviewdist * rsurface.inversematrixscale; rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale; @@ -7225,6 +7249,7 @@ void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inve rsurface.inversematrixscale = 1.0f / rsurface.matrixscale; R_EntityMatrix(&rsurface.matrix); Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.origin, rsurface.localvieworigin); + Matrix4x4_Transform(&rsurface.inversematrix, r_refdef.view.forward, rsurface.localviewdirection); Matrix4x4_TransformStandardPlane(&rsurface.inversematrix, r_refdef.fogplane[0], r_refdef.fogplane[1], r_refdef.fogplane[2], r_refdef.fogplane[3], rsurface.fogplane); rsurface.fogplaneviewdist *= rsurface.inversematrixscale; rsurface.fograngerecip = r_refdef.fograngerecip * rsurface.matrixscale; diff --git a/render.h b/render.h index c8d63be8..0561ec0d 100644 --- a/render.h +++ b/render.h @@ -473,6 +473,8 @@ typedef struct rsurfacestate_s skeleton_t *skeleton; // view location in model space vec3_t localvieworigin; + // view directoion in model space + vec3_t localviewdirection; // polygon offset data for submodels float basepolygonfactor; float basepolygonoffset; diff --git a/shader_glsl.h b/shader_glsl.h index 11ec83dc..2ae203a7 100644 --- a/shader_glsl.h +++ b/shader_glsl.h @@ -639,6 +639,7 @@ "\n", "#ifdef FRAGMENT_SHADER\n", "uniform sampler2D Texture_Normal;\n", +"uniform vec3 EyeDirection;\n", "uniform sampler2D Texture_Refraction;\n", "uniform sampler2D Texture_Reflection;\n", "\n", @@ -656,10 +657,9 @@ "\n", "void main(void)\n", "{\n", +" // correctly shift and scale the texture coordinates\n", " vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n", -" //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(vec3(dp_texture2D(Texture_Normal, TexCoord)) - vec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n", " vec4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n", -" //SafeScreenTexCoord = gl_FragCoord.xyxy * vec4(1.0 / 1920.0, 1.0 / 1200.0, 1.0 / 1920.0, 1.0 / 1200.0);\n", " // slight water animation via 2 layer scrolling (todo: tweak)\n", "#ifdef USEALPHAGENVERTEX\n", " vec4 distort = DistortScaleRefractReflect * VertexColor.a;\n", @@ -672,30 +672,35 @@ " float reflectfactor = ReflectFactor;\n", " vec4 refractcolor = RefractColor;\n", "#endif\n", -" #ifdef USENORMALMAPSCROLLBLEND\n", -" vec3 normal = dp_texture2D(Texture_Normal, (TexCoord + vec2(0.08, 0.08)*ClientTime*NormalmapScrollBlend.x*0.5)*NormalmapScrollBlend.y).rgb - vec3(1.0);\n", -" normal += dp_texture2D(Texture_Normal, (TexCoord + vec2(-0.06, -0.09)*ClientTime*NormalmapScrollBlend.x)*NormalmapScrollBlend.y*0.75).rgb;\n", -" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(normal) + vec3(0.15)).xyxy * distort;\n", -" #else\n", -" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(dp_texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * distort;\n", -" #endif\n", +//" #ifdef USENORMALMAPSCROLLBLEND\n", +//" vec3 normal = dp_texture2D(Texture_Normal, (TexCoord + vec2(0.08, 0.08)*ClientTime*NormalmapScrollBlend.x*0.5)*NormalmapScrollBlend.y).rgb - vec3(1.0);\n", +//" normal += dp_texture2D(Texture_Normal, (TexCoord + vec2(-0.06, -0.09)*ClientTime*NormalmapScrollBlend.x)*NormalmapScrollBlend.y*0.75).rgb;\n", +//" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(normal) + vec3(0.15)).xyxy * distort;\n", +//" #else\n", +//" vec4 ScreenTexCoord = SafeScreenTexCoord + vec2(normalize(vec3(dp_texture2D(Texture_Normal, TexCoord)) - vec3(0.5))).xyxy * distort;\n", +//" #endif\n", " // FIXME temporary hack to detect the case that the reflection\n", " // gets blackened at edges due to leaving the area that contains actual\n", " // content.\n", " // Remove this 'ack once we have a better way to stop this thing from\n", " // 'appening.\n", -" float f = min(1.0, length(dp_texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, 0.01)).rgb) / 0.002);\n", -" f *= min(1.0, length(dp_texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(0.005, -0.01)).rgb) / 0.002);\n", -" f *= min(1.0, length(dp_texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, 0.01)).rgb) / 0.002);\n", -" f *= min(1.0, length(dp_texture2D(Texture_Refraction, ScreenTexCoord.xy + vec2(-0.005, -0.01)).rgb) / 0.002);\n", -" ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n", -" f = min(1.0, length(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.005, 0.005)).rgb) / 0.002);\n", -" f *= min(1.0, length(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(0.005, -0.005)).rgb) / 0.002);\n", -" f *= min(1.0, length(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, 0.005)).rgb) / 0.002);\n", -" f *= min(1.0, length(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw + vec2(-0.005, -0.005)).rgb) / 0.002);\n", -" ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n", -" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * reflectfactor + reflectoffset;\n", -" dp_FragColor = mix(vec4(dp_texture2D(Texture_Refraction, ScreenTexCoord.xy).rgb, 1) * refractcolor, vec4(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw).rgb, 1) * ReflectColor, Fresnel);\n", +" vec4 ScreenTexCoord = SafeScreenTexCoord;\n", +" vec3 normal = normalize(vec3(dp_texture2D(Texture_Normal, TexCoord.xy))) - vec3(0.5, 0.5, 0.5);\n", +" normal = normalize(normal);\n", +" vec3 refrNorm = normal * vec3(0.05, 0.05, 1.0);\n", +" vec3 reflNorm = normal * vec3(0.02, 0.02, 1.0);\n", +" vec4 refl = vec4(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw + reflNorm.xy).rgb, 1.0);\n", +" vec4 refr = vec4(dp_texture2D(Texture_Refraction, ScreenTexCoord.zw + refrNorm.xy).rgb, 1.0);\n", +" vec4 reflN = vec4(dp_texture2D(Texture_Reflection, ScreenTexCoord.zw - reflNorm.xy).rgb, 1.0);\n", +" vec4 refrN = vec4(dp_texture2D(Texture_Refraction, ScreenTexCoord.zw - refrNorm.xy).rgb, 1.0);\n", +" float f = min(1.0, length(refl.rgb) / 0.0002);\n", +" refl = mix(reflN, refl, f);\n", +" f = min(1.0, length(refr.rgb) / 0.0002);\n", +" refr = mix(refrN, refr, f);\n", +" float dotProduct = abs(dot(EyeDirection, reflNorm));\n", +" float Fresnel = 0.02f+max(0, 0.97f*pow((1-dotProduct),5));\n", +" Fresnel = clamp(Fresnel, 0.2, 0.8);\n" +" dp_FragColor = mix(refr, refl, Fresnel);\n", "}\n", "#endif\n", "#else // !MODE_WATER\n", -- 2.39.2