From 83aaee5bc4613cc677378e85cc856dd5dfda9745 Mon Sep 17 00:00:00 2001
From: SmileTheory <SmileTheory@gmail.com>
Date: Sun, 16 Mar 2014 16:29:38 -0700
Subject: OpenGL2: Parallax corrected cubemap (cheaper trick)

---
 src/renderergl2/glsl/lightall_fp.glsl | 17 ++++++++++++++---
 src/renderergl2/tr_glsl.c             |  4 +++-
 src/renderergl2/tr_local.h            |  2 ++
 src/renderergl2/tr_shade.c            | 13 +++++++++++++
 4 files changed, 32 insertions(+), 4 deletions(-)

(limited to 'src/renderergl2')

diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl
index c74d6844..0f50a038 100644
--- a/src/renderergl2/glsl/lightall_fp.glsl
+++ b/src/renderergl2/glsl/lightall_fp.glsl
@@ -44,6 +44,12 @@ uniform vec4      u_NormalScale;
 uniform vec4      u_SpecularScale;
 #endif
 
+#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
+#if defined(USE_CUBEMAP)
+uniform vec4      u_CubeMapInfo;
+#endif
+#endif
+
 varying vec4      var_TexCoords;
 
 varying vec4      var_Color;
@@ -323,19 +329,20 @@ mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv )
 
 void main()
 {
+	vec3 viewDir;
 	vec3 L, N, E, H;
 	float NL, NH, NE, EH;
 
 #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
   #if defined(USE_VERT_TANGENT_SPACE)
 	mat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz);
-	E = vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w);
+	viewDir = vec3(var_Normal.w, var_Tangent.w, var_Bitangent.w);
   #else
 	mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy);
-	E = var_ViewDir;
+	viewDir = var_ViewDir;
   #endif
 
-	E = normalize(E);
+	E = normalize(viewDir);
 
 	L = var_LightDir.xyz;
   #if defined(USE_DELUXEMAP)
@@ -497,6 +504,10 @@ void main()
 
 	vec3 R = reflect(E, N);
 
+	// parallax corrected cubemap (cheaper trick)
+	// from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
+	R += u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;
+
 	vec3 cubeLightColor = textureCubeLod(u_CubeMap, R, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w;
 
 	#if defined(USE_LIGHTMAP)
diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c
index c4a30b60..33dd0497 100644
--- a/src/renderergl2/tr_glsl.c
+++ b/src/renderergl2/tr_glsl.c
@@ -142,7 +142,9 @@ static uniformInfo_t uniformsInfo[] =
 	{ "u_PrimaryLightOrigin",  GLSL_VEC4  },
 	{ "u_PrimaryLightColor",   GLSL_VEC3  },
 	{ "u_PrimaryLightAmbient", GLSL_VEC3  },
-	{ "u_PrimaryLightRadius",  GLSL_FLOAT }
+	{ "u_PrimaryLightRadius",  GLSL_FLOAT },
+
+	{ "u_CubeMapInfo", GLSL_VEC4 },
 };
 
 
diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h
index bdc55d69..26624334 100644
--- a/src/renderergl2/tr_local.h
+++ b/src/renderergl2/tr_local.h
@@ -699,6 +699,8 @@ typedef enum
 	UNIFORM_PRIMARYLIGHTAMBIENT,
 	UNIFORM_PRIMARYLIGHTRADIUS,
 
+	UNIFORM_CUBEMAPINFO,
+
 	UNIFORM_COUNT
 } uniform_t;
 
diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c
index 0925b6d6..11ba5836 100644
--- a/src/renderergl2/tr_shade.c
+++ b/src/renderergl2/tr_shade.c
@@ -1379,8 +1379,21 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
 		// testing cube map
 		//
 		if (!(tr.viewParms.flags & VPF_NOCUBEMAPS) && input->cubemapIndex && r_cubeMapping->integer)
+		{
+			vec4_t vec;
+
 			GL_BindToTMU( tr.cubemaps[input->cubemapIndex - 1], TB_CUBEMAP);
 
+			vec[0] = tr.cubemapOrigins[input->cubemapIndex - 1][0] - backEnd.viewParms.or.origin[0];
+			vec[1] = tr.cubemapOrigins[input->cubemapIndex - 1][1] - backEnd.viewParms.or.origin[1];
+			vec[2] = tr.cubemapOrigins[input->cubemapIndex - 1][2] - backEnd.viewParms.or.origin[2];
+			vec[3] = 1.0f;
+
+			VectorScale4(vec, 1.0f / 1000.0f, vec);
+
+			GLSL_SetUniformVec4(sp, UNIFORM_CUBEMAPINFO, vec);
+		}
+
 		//
 		// draw
 		//
-- 
cgit