- Scale map lights by 0.66 and sunlight by 0.33 when r_testSunlight 1

- Offset shadowmap samples by surface normal and reenable PCF
- Reenabled per vertex tangent space values, fixes visual issues in normal maps
- Simplified some viewparms flags
This commit is contained in:
James Canete 2012-08-07 12:51:33 +00:00
parent 3d55fd3731
commit e100284932
11 changed files with 366 additions and 304 deletions

View file

@ -1,3 +1,7 @@
- Scale map lights by 0.66 and sunlight by 0.33 when r_testSunlight 1
- Offset shadowmap samples by surface normal and reenable PCF
- Reenabled per vertex tangent space values, fixes visual issues in normal maps
- Simplified some viewparms flags
- Add cascaded shadow mapping, test with r_testSunlight 1.
- Add r_depthPrepass.
- Improve parallax mapping

View file

@ -513,7 +513,7 @@ void RB_BeginDrawingView (void) {
}
// clear to white for shadow maps
if (backEnd.viewParms.isShadowmap)
if (backEnd.viewParms.flags & VPF_SHADOWMAP)
{
clearBits |= GL_COLOR_BUFFER_BIT;
qglClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
@ -1186,12 +1186,12 @@ const void *RB_DrawSurfs( const void *data ) {
// clear the z buffer, set the modelview, etc
RB_BeginDrawingView ();
if (backEnd.viewParms.isDepthShadow && glRefConfig.depthClamp)
if ((backEnd.viewParms.flags & VPF_DEPTHCLAMP) && glRefConfig.depthClamp)
{
qglEnable(GL_DEPTH_CLAMP);
}
if (r_depthPrepass->integer || backEnd.viewParms.isDepthShadow)
if (r_depthPrepass->integer || (backEnd.viewParms.flags & VPF_DEPTHSHADOW))
{
backEnd.depthFill = qtrue;
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@ -1200,12 +1200,12 @@ const void *RB_DrawSurfs( const void *data ) {
backEnd.depthFill = qfalse;
}
if (backEnd.viewParms.isDepthShadow && glRefConfig.depthClamp)
if ((backEnd.viewParms.flags & VPF_DEPTHCLAMP) && glRefConfig.depthClamp)
{
qglDisable(GL_DEPTH_CLAMP);
}
if (!backEnd.viewParms.isDepthShadow)
if (!(backEnd.viewParms.flags & VPF_DEPTHSHADOW))
{
RB_RenderDrawSurfList( cmd->drawSurfs, cmd->numDrawSurfs );

View file

@ -278,7 +278,7 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
tr.lightmaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
if (tr.worldDeluxeMapping || r_deluxeMapping->integer == 2)
if (tr.worldDeluxeMapping)
{
tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
}
@ -659,7 +659,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
int i, j;
srfSurfaceFace_t *cv;
srfTriangle_t *tri;
int numVerts, numTriangles;
int numVerts, numTriangles, badTriangles;
int realLightmapNum;
realLightmapNum = LittleLong( ds->lightmapNum );
@ -743,6 +743,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
}
// copy triangles
badTriangles = 0;
indexes += LittleLong(ds->firstIndex);
for(i = 0, tri = cv->triangles; i < numTriangles; i++, tri++)
{
@ -755,6 +756,18 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
ri.Error(ERR_DROP, "Bad index in face surface");
}
}
if ((tri->indexes[0] == tri->indexes[1]) || (tri->indexes[1] == tri->indexes[2]) || (tri->indexes[0] == tri->indexes[2]))
{
tri--;
badTriangles++;
}
}
if (badTriangles)
{
ri.Printf(PRINT_WARNING, "Face has bad triangles, originally shader %s %d tris %d verts, now %d tris\n", surf->shader->name, numTriangles, numVerts, numTriangles - badTriangles);
cv->numTriangles -= badTriangles;
}
// take the plane information from the lightmap vector
@ -997,7 +1010,7 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor
if (badTriangles)
{
ri.Printf(PRINT_WARNING, "Surface has bad triangles, originally shader %s %d tris %d verts, now %d tris\n", surf->shader->name, numTriangles, numVerts, numTriangles - badTriangles);
ri.Printf(PRINT_WARNING, "Trisurf has bad triangles, originally shader %s %d tris %d verts, now %d tris\n", surf->shader->name, numTriangles, numVerts, numTriangles - badTriangles);
cv->numTriangles -= badTriangles;
}
@ -3220,6 +3233,9 @@ void RE_LoadWorldMap( const char *name ) {
ri.Error( ERR_DROP, "ERROR: attempted to redundantly load world map\n" );
}
// set default map light scale
tr.mapLightScale = 1.0;
// set default sun direction to be used if it isn't
// overridden by a shader
tr.sunDirection[0] = 0.45f;

View file

@ -310,154 +310,159 @@ static const char *fallbackLightallShader_fp =
"f defined(USE_SHADOWMAP)\r\nuniform mat4 u_ShadowMvp;\r\n #if defined"
"(USE_SHADOW_CASCADE)\r\nuniform mat4 u_ShadowMvp2;\r\nuniform mat4 "
" u_ShadowMvp3;\r\n #endif\r\n#endif\r\n\r\n#if defined(USE_LIGHT)\r\nunif"
"orm vec2 u_MaterialInfo;\r\n#endif\r\n\r\nvarying vec2 var_Diffus"
"eTex;\r\n#if defined(USE_LIGHTMAP)\r\nvarying vec2 var_LightTex;\r\n#e"
"ndif\r\nvarying vec4 var_Color;\r\nvarying vec3 var_Position;\r\n"
"\r\nvarying vec3 var_SampleToView;\r\n\r\nvarying vec3 var_Normal"
";\r\n#if defined(USE_VERT_TANGENT_SPACE)\r\nvarying vec3 var_Tangent;"
"\r\nvarying vec3 var_Bitangent;\r\n#endif\r\n\r\n#if defined(USE_LIGHT"
"_VECTOR) && defined(USE_FAST_LIGHT)\r\nvarying vec3 var_VectLight;\r\n"
"#endif\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)\r\nvarying "
"vec3 var_WorldLight;\r\n#endif\r\n\r\n#define EPSILON 0.00000001\r\n\r"
"\n#if defined(USE_PARALLAXMAP)\r\nfloat SampleHeight(sampler2D normalMap, v"
"ec2 t)\r\n{\r\n #if defined(SWIZZLE_NORMALMAP)\r\n\treturn texture2D(norma"
"lMap, t).r;\r\n #else\r\n\treturn texture2D(normalMap, t).a;\r\n #endif\r"
"\n}\r\n\r\nfloat RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normal"
"Map)\r\n{\r\n\tconst int linearSearchSteps = 16;\r\n\tconst int binarySearc"
"hSteps = 6;\r\n\r\n\tfloat depthStep = 1.0 / float(linearSearchSteps);\r\n"
"\r\n\t// current size of search window\r\n\tfloat size = depthStep;\r\n\r\n"
"\t// current depth position\r\n\tfloat depth = 0.0;\r\n\r\n\t// best match "
"found (starts with last position 1.0)\r\n\tfloat bestDepth = 1.0;\r\n\r\n\t"
"// search front to back for first point inside object\r\n\tfor(int i = 0; i"
" < linearSearchSteps - 1; ++i)\r\n\t{\r\n\t\tdepth += size;\r\n\t\t\r\n\t\t"
"float t = 1.0 - SampleHeight(normalMap, dp + ds * depth);\r\n\t\t\r\n\t\tif"
"(bestDepth > 0.996)\t\t// if no depth found yet\r\n\t\t\tif(depth >= t)\r\n"
"\t\t\t\tbestDepth = depth;\t// store best depth\r\n\t}\r\n\r\n\tdepth = bes"
"tDepth;\r\n\t\r\n\t// recurse around first point (depth) for closest match"
"\r\n\tfor(int i = 0; i < binarySearchSteps; ++i)\r\n\t{\r\n\t\tsize *= 0.5;"
"\r\n\r\n\t\tfloat t = 1.0 - SampleHeight(normalMap, dp + ds * depth);\r\n\t"
"\t\r\n\t\tif(depth >= t)\r\n\t\t{\r\n\t\t\tbestDepth = depth;\r\n\t\t\tdept"
"h -= 2.0 * size;\r\n\t\t}\r\n\r\n\t\tdepth += size;\r\n\t}\r\n\r\n\treturn "
"bestDepth;\r\n}\r\n#endif\r\n\r\nfloat CalcDiffuse(vec3 N, vec3 L, vec3 E, "
"float NE, float NL, float fzero, float shininess)\r\n{\r\n #if defined(USE"
"_OREN_NAYAR)\r\n\tfloat roughness = sqrt(2.0 / max(shininess, EPSILON));\r"
"\n\r\n\tfloat gamma = dot(E - N * NE, L - N * NL);\r\n\tfloat r_sq = roughn"
"ess * roughness;\r\n\r\n\tfloat A = 1.0 - 0.5 * (r_sq / (r_sq + 0.57));\r\n"
"\tfloat B = 0.45 * (r_sq / (r_sq + 0.09));\r\n\r\n\tfloat alpha = max(acos("
"NE), acos(NL));\r\n\tfloat beta = min(acos(NE), acos(NL));\r\n\r\n\tfloat "
"C = sin(alpha) * tan(beta);\r\n\r\n\treturn A + B * clamp(gamma, 0.0, 1.0) "
"* C;\r\n #else\r\n\treturn 1.0 - fzero;\r\n #endif\r\n}\r\n\r\n#if define"
"d(USE_SPECULARMAP)\r\nfloat CalcSpecular(float NH, float NL, float NE, floa"
"t EH, float fzero, float shininess)\r\n{\r\n #if defined(USE_BLINN) || def"
"ined(USE_TRIACE) || defined(USE_TORRANCE_SPARROW)\r\n\tfloat blinn = pow(NH"
", shininess);\r\n #endif\r\n\r\n #if defined(USE_BLINN)\r\n\treturn blinn"
";\r\n #endif\r\n\r\n #if defined(USE_COOK_TORRANCE) || defined (USE_TRIAC"
"E) || defined (USE_TORRANCE_SPARROW)\r\n\tfloat fresnel = fzero + (1.0 - fz"
"ero) * pow(1.0 - EH, 5);\r\n #endif\r\n\r\n #if defined(USE_COOK_TORRANCE"
") || defined(USE_TORRANCE_SPARROW)\r\n\tfloat geo = 2.0 * NH * min(NE, NL);"
"\r\n\tgeo /= max(EH, geo);\r\n #endif \r\n\r\n #if defined(USE_COOK_TORR"
"ANCE)\r\n\tfloat m = sqrt(2.0 / max(shininess, EPSILON));\r\n\r\n\tfloat m_"
"sq = m * m;\r\n\tfloat NH_sq = NH * NH;\r\n\tfloat beckmann = exp((NH_sq - "
"1.0) / max(m_sq * NH_sq, EPSILON)) / max(4.0 * m_sq * NH_sq * NH_sq, EPSILO"
"N);\r\n\r\n\treturn fresnel * geo * beckmann / max(NE, EPSILON);\r\n #endi"
"f\r\n\r\n #if defined(USE_TRIACE)\r\n\tfloat scale = 0.1248582 * shininess"
" + 0.2691817;\r\n\r\n\treturn fresnel * scale * blinn / max(max(NL, NE), EP"
"SILON);\r\n #endif\r\n \r\n #if defined(USE_TORRANCE_SPARROW)\r\n\tfloat"
" scale = 0.125 * shininess + 1.0;\r\n\r\n\treturn fresnel * geo * scale * b"
"linn / max(NE, EPSILON);\r\n #endif\r\n}\r\n#endif\r\n\r\nfloat PCF(sample"
"r2D shadowmap, vec2 st, float dist)\r\n{\r\n\tfloat mult;\r\n\t\r\n\tmult "
"= sign(clamp(texture2D(shadowmap, st + vec2(-0.5, -0.5) / 1024.0).r - dist,"
" 0.0, 1.0));\r\n\tmult += sign(clamp(texture2D(shadowmap, st + vec2( 0.5, -"
"0.5) / 1024.0).r - dist, 0.0, 1.0));\r\n\tmult += sign(clamp(texture2D(shad"
"owmap, st + vec2(-0.5, 0.5) / 1024.0).r - dist, 0.0, 1.0));\r\n\tmult += s"
"ign(clamp(texture2D(shadowmap, st + vec2( 0.5, 0.5) / 1024.0).r - dist, 0."
"0, 1.0));\r\n\tmult *= 0.25;\r\n\t\r\n\treturn mult;\r\n}\r\n\r\nvoid main("
")\r\n{\r\n#if defined(USE_LIGHT) || defined(USE_NORMALMAP)\r\n\tvec3 surfNo"
"rmal = normalize(var_Normal);\r\n#endif\r\n\r\n#if defined(USE_DELUXEMAP)\r"
"\n\tvec3 worldLight = 2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3"
"(1.0);\r\n\t//worldLight += var_WorldLight * 0.0001;\r\n#elif defined(USE_L"
"IGHT)\r\n\tvec3 worldLight = var_WorldLight;\r\n#endif\r\n\r\n#if defined(U"
"SE_LIGHTMAP)\r\n\tvec4 lightSample = texture2D(u_LightMap, var_LightTex).rg"
"ba;\r\n #if defined(RGBE_LIGHTMAP)\r\n\tlightSample.rgb *= exp2(lightSampl"
"e.a * 255.0 - 128.0);\r\n #endif\r\n\tvec3 directedLight = lightSample.rgb"
";\r\n#elif defined(USE_LIGHT_VECTOR)\r\n #if defined(USE_FAST_LIGHT)\r\n\t"
"vec3 directedLight = var_VectLight;\r\n #else\r\n #if defined(USE_INVSQ"
"RLIGHT)\r\n\tfloat intensity = 1.0 / dot(worldLight, worldLight);\r\n #e"
"lse\r\n\tfloat intensity = clamp((1.0 - dot(worldLight, worldLight) / (u_Li"
"ghtRadius * u_LightRadius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n\r\n\t#if d"
"efined(USE_SHADOWMAP)\r\n\tvec4 shadowpos = u_ShadowMvp * vec4(var_Position"
", 1.0);\r\n\tfloat outside1 = dot(vec3(1.0, 1.0, 1.0), sign(clamp(abs(shado"
"wpos.xyz) - 1.0, 0.0, 1.0)));\r\n\t\r\n\t #if defined(USE_SHADOW_CASCADE)"
"\r\n\tvec4 shadowpos2 = u_ShadowMvp2 * vec4(var_Position, 1.0);\r\n\tfloat "
"outside2 = dot(vec3(1.0, 1.0, 1.0), sign(clamp(abs(shadowpos2.xyz) - 1.0, 0"
".0, 1.0)));\r\n\r\n\tvec4 shadowpos3 = u_ShadowMvp3 * vec4(var_Position, 1."
"0);\r\n\tfloat outside3 = dot(vec3(1.0, 1.0, 1.0), sign(clamp(abs(shadowpos"
"3.xyz) - 1.0, 0.0, 1.0)));\r\n\t\r\n\tif (outside1 < 1.0)\r\n\t{\r\n\t\tsha"
"dowpos.xyz = shadowpos.xyz * 0.5 + 0.5;\r\n\t\tintensity *= PCF(u_ShadowMap"
", shadowpos.xy, shadowpos.z);\r\n\t}\r\n\telse if (outside2 < 1.0)\r\n\t{\r"
"\n\t\tshadowpos2.xyz = shadowpos2.xyz * 0.5 + 0.5;\r\n\t\tintensity *= PCF("
"u_ShadowMap2, shadowpos2.xy, shadowpos2.z);\r\n\t}\r\n\telse if (outside3 <"
" 1.0)\r\n\t{\r\n\t\tshadowpos3.xyz = shadowpos3.xyz * 0.5 + 0.5;\r\n\t\tint"
"ensity *= PCF(u_ShadowMap3, shadowpos3.xy, shadowpos3.z);\r\n\t}\r\n\t #el"
"se\r\n\tshadowpos.xyz = shadowpos.xyz * 0.5 + 0.5;\r\n\tintensity *= clamp("
"PCF(u_ShadowMap, shadowpos.xy, shadowpos.z) - outside1, 1.0, 0.0);\r\n\t #"
"endif\r\n\t#endif\r\n\t\r\n\tvec3 directedLight = u_DirectedLight * intensi"
"ty;\r\n\tvec3 ambientLight = u_AmbientLight;\r\n #endif\r\n#elif defined("
"USE_LIGHT_VERTEX)\r\n\tvec3 directedLight = var_Color.rgb;\r\n#endif\r\n\t"
"\r\n#if defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_L"
"IGHT)\r\n\tvec3 SampleToView = normalize(var_SampleToView);\r\n#endif\r\n\t"
"vec2 tex = var_DiffuseTex;\r\n\r\n\tfloat ambientDiff = 1.0;\r\n\r\n#if def"
"ined(USE_NORMALMAP)\r\n #if defined(USE_VERT_TANGENT_SPACE)\r\n vec3 "
"tangent = normalize(var_Tangent);\r\n\tvec3 bitangent = normalize(var_Bitan"
"gent);\r\n #else\r\n\tvec3 q0 = dFdx(var_Position);\r\n\tvec3 q1 = dFdy("
"var_Position);\r\n\tvec2 st0 = dFdx(tex);\r\n\tvec2 st1 = dFdy(tex);\r\n\tf"
"loat dir = sign(st1.t * st0.s - st0.t * st1.s);\r\n\r\n\tvec3 tangent = n"
"ormalize( q0 * st1.t - q1 * st0.t) * dir;\r\n\tvec3 bitangent = -normalize("
" q0 * st1.s - q1 * st0.s) * dir;\r\n #endif\r\n\r\n\tmat3 tangentToWorld ="
" mat3(tangent, bitangent, surfNormal);\r\n\r\n #if defined(USE_PARALLAXMAP"
")\r\n\tvec3 offsetDir = normalize(SampleToView * tangentToWorld);\r\n #i"
"f 0\r\n float height = SampleHeight(u_NormalMap, tex);\r\n\tfloat pdist "
"= 0.05 * height - (0.05 / 2.0);\r\n #else\r\n\toffsetDir.xy *= -0.05 / o"
"ffsetDir.z;\r\n\tfloat pdist = RayIntersectDisplaceMap(tex, offsetDir.xy, u"
"_NormalMap);\r\n #endif\t\r\n\ttex += offsetDir.xy * pdist;\r\n #endif"
"\r\n #if defined(SWIZZLE_NORMALMAP)\r\n\tvec3 normal = 2.0 * texture2D(u_N"
"ormalMap, tex).agb - 1.0;\r\n #else\r\n\tvec3 normal = 2.0 * texture2D(u_N"
"ormalMap, tex).rgb - 1.0;\r\n #endif\r\n\tnormal.z = sqrt(clamp(1.0 - dot("
"normal.xy, normal.xy), 0.0, 1.0));\r\n\tvec3 worldNormal = tangentToWorld *"
" normal;\r\n #if defined(r_normalAmbient)\r\n\tambientDiff = 0.781341 * no"
"rmal.z + 0.218659;\r\n #endif\r\n#elif defined(USE_LIGHT)\r\n\tvec3 worldN"
"ormal = surfNormal;\r\n#endif\r\n\r\n\tvec4 diffuse = texture2D(u_DiffuseMa"
"p, tex);\r\n\r\n#if defined(USE_LIGHT) && defined(USE_FAST_LIGHT)\r\n\tdiff"
"use.rgb *= directedLight;\r\n#elif defined(USE_LIGHT)\r\n\tworldNormal = no"
"rmalize(worldNormal);\r\n\tworldLight = normalize(worldLight);\r\n\r\n #if"
" defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)\r\n\tdirectedLight /= m"
"ax(dot(surfNormal, worldLight), 0.004);\r\n\r\n #if defined(r_normalAmbi"
"ent)\r\n\tvec3 ambientLight = directedLight * r_normalAmbient;\r\n\tdirecte"
"dLight -= ambientLight;\r\n #else\r\n\tvec3 ambientLight = vec3(0);\r\n "
" #endif\r\n #endif\r\n\r\n\tfloat NL = clamp(dot(worldNormal, worldLigh"
"t), 0.0, 1.0);\r\n\tfloat surfNL = clamp(dot(var_Normal, worldLight), "
"0.0, 1.0);\r\n\tNL = min(NL, surfNL * 2.0);\r\n\tfloat NE = clamp(dot(world"
"Normal, SampleToView), 0.0, 1.0);\r\n\t\r\n\tfloat fzero = u_MaterialInfo."
"x;\r\n\tfloat shininess = u_MaterialInfo.y;\r\n #if defined(USE_SPECULARMA"
"P)\r\n\tvec4 specular = texture2D(u_SpecularMap, tex);\r\n\t//specular.rgb "
"= clamp(specular.rgb - diffuse.rgb, 0.0, 1.0);\r\n\tshininess *= specular.a"
";\r\n #endif\r\n\tfloat directedDiff = NL * CalcDiffuse(worldNormal, world"
"Light, SampleToView, NE, NL, fzero, shininess);\r\n\tdiffuse.rgb *= directe"
"dLight * directedDiff + ambientDiff * ambientLight;\r\n \r\n #if defined("
"USE_SPECULARMAP)\r\n\tvec3 halfAngle = normalize(worldLight + SampleToView)"
";\r\n\r\n\tfloat EH = clamp(dot(SampleToView, halfAngle), 0.0, 1.0);\r\n\tf"
"loat NH = clamp(dot(worldNormal, halfAngle), 0.0, 1.0);\r\n\r\n\tfloat dir"
"ectedSpec = NL * CalcSpecular(NH, NL, NE, EH, fzero, shininess);\r\n \r\n "
" #if defined(r_normalAmbient)\r\n\tvec3 ambientHalf = normalize(surfNorma"
"l + SampleToView);\r\n\tfloat ambientSpec = max(dot(ambientHalf, worldNorma"
"l) + 0.5, 0.0);\r\n\tambientSpec *= ambientSpec * 0.44;\r\n\tambientSpec = "
"pow(ambientSpec, shininess) * fzero;\r\n\tspecular.rgb *= directedSpec * di"
"rectedLight + ambientSpec * ambientLight;\r\n #else\r\n\tspecular.rgb *="
" directedSpec * directedLight;\r\n #endif\r\n #endif\r\n#endif\r\n\r\n"
"\tgl_FragColor = diffuse;\r\n\r\n#if defined(USE_SPECULARMAP) && defined(US"
"E_LIGHT) && !defined(USE_FAST_LIGHT)\r\n\tgl_FragColor.rgb += specular.rgb;"
"\r\n#endif\r\n\r\n#if !defined(USE_LIGHT_VERTEX)\r\n\tgl_FragColor *= var_C"
"olor;\r\n#endif\r\n}\r\n";
"orm vec2 u_MaterialInfo;\r\n#endif\r\n\r\n#if defined(USE_LIGHTMAP) ||"
" defined(USE_LIGHT_VERTEX)\r\nuniform float u_MapLightScale;\r\n#endif"
"\r\n\r\nvarying vec2 var_DiffuseTex;\r\n#if defined(USE_LIGHTMAP)\r\nv"
"arying vec2 var_LightTex;\r\n#endif\r\nvarying vec4 var_Color;\r"
"\nvarying vec3 var_Position;\r\n\r\nvarying vec3 var_SampleToView"
";\r\n\r\nvarying vec3 var_Normal;\r\n#if defined(USE_VERT_TANGENT_SPAC"
"E)\r\nvarying vec3 var_Tangent;\r\nvarying vec3 var_Bitangent;\r"
"\n#endif\r\n\r\n#if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)\r"
"\nvarying vec3 var_VectLight;\r\n#endif\r\n\r\n#if defined(USE_LIGHT) "
"&& !defined(USE_DELUXEMAP)\r\nvarying vec3 var_WorldLight;\r\n#endif\r"
"\n\r\n#define EPSILON 0.00000001\r\n\r\n#if defined(USE_PARALLAXMAP)\r\nflo"
"at SampleHeight(sampler2D normalMap, vec2 t)\r\n{\r\n #if defined(SWIZZLE_"
"NORMALMAP)\r\n\treturn texture2D(normalMap, t).r;\r\n #else\r\n\treturn te"
"xture2D(normalMap, t).a;\r\n #endif\r\n}\r\n\r\nfloat RayIntersectDisplace"
"Map(vec2 dp, vec2 ds, sampler2D normalMap)\r\n{\r\n\tconst int linearSearch"
"Steps = 16;\r\n\tconst int binarySearchSteps = 6;\r\n\r\n\tfloat depthStep "
"= 1.0 / float(linearSearchSteps);\r\n\r\n\t// current size of search window"
"\r\n\tfloat size = depthStep;\r\n\r\n\t// current depth position\r\n\tfloat"
" depth = 0.0;\r\n\r\n\t// best match found (starts with last position 1.0)"
"\r\n\tfloat bestDepth = 1.0;\r\n\r\n\t// search front to back for first poi"
"nt inside object\r\n\tfor(int i = 0; i < linearSearchSteps - 1; ++i)\r\n\t{"
"\r\n\t\tdepth += size;\r\n\t\t\r\n\t\tfloat t = 1.0 - SampleHeight(normalMa"
"p, dp + ds * depth);\r\n\t\t\r\n\t\tif(bestDepth > 0.996)\t\t// if no depth"
" found yet\r\n\t\t\tif(depth >= t)\r\n\t\t\t\tbestDepth = depth;\t// store "
"best depth\r\n\t}\r\n\r\n\tdepth = bestDepth;\r\n\t\r\n\t// recurse around "
"first point (depth) for closest match\r\n\tfor(int i = 0; i < binarySearchS"
"teps; ++i)\r\n\t{\r\n\t\tsize *= 0.5;\r\n\r\n\t\tfloat t = 1.0 - SampleHeig"
"ht(normalMap, dp + ds * depth);\r\n\t\t\r\n\t\tif(depth >= t)\r\n\t\t{\r\n"
"\t\t\tbestDepth = depth;\r\n\t\t\tdepth -= 2.0 * size;\r\n\t\t}\r\n\r\n\t\t"
"depth += size;\r\n\t}\r\n\r\n\treturn bestDepth;\r\n}\r\n#endif\r\n\r\nfloa"
"t CalcDiffuse(vec3 N, vec3 L, vec3 E, float NE, float NL, float fzero, floa"
"t shininess)\r\n{\r\n #if defined(USE_OREN_NAYAR)\r\n\tfloat roughness = s"
"qrt(2.0 / max(shininess, EPSILON));\r\n\r\n\tfloat gamma = dot(E - N * NE, "
"L - N * NL);\r\n\tfloat r_sq = roughness * roughness;\r\n\r\n\tfloat A = 1."
"0 - 0.5 * (r_sq / (r_sq + 0.57));\r\n\tfloat B = 0.45 * (r_sq / (r_sq + 0.0"
"9));\r\n\r\n\tfloat alpha = max(acos(NE), acos(NL));\r\n\tfloat beta = min"
"(acos(NE), acos(NL));\r\n\r\n\tfloat C = sin(alpha) * tan(beta);\r\n\r\n\tr"
"eturn A + B * clamp(gamma, 0.0, 1.0) * C;\r\n #else\r\n\treturn 1.0 - fzer"
"o;\r\n #endif\r\n}\r\n\r\n#if defined(USE_SPECULARMAP)\r\nfloat CalcSpecul"
"ar(float NH, float NL, float NE, float EH, float fzero, float shininess)\r"
"\n{\r\n #if defined(USE_BLINN) || defined(USE_TRIACE) || defined(USE_TORRA"
"NCE_SPARROW)\r\n\tfloat blinn = pow(NH, shininess);\r\n #endif\r\n\r\n #i"
"f defined(USE_BLINN)\r\n\treturn blinn;\r\n #endif\r\n\r\n #if defined(US"
"E_COOK_TORRANCE) || defined (USE_TRIACE) || defined (USE_TORRANCE_SPARROW)"
"\r\n\tfloat fresnel = fzero + (1.0 - fzero) * pow(1.0 - EH, 5);\r\n #endif"
"\r\n\r\n #if defined(USE_COOK_TORRANCE) || defined(USE_TORRANCE_SPARROW)\r"
"\n\tfloat geo = 2.0 * NH * min(NE, NL);\r\n\tgeo /= max(EH, geo);\r\n #end"
"if \r\n\r\n #if defined(USE_COOK_TORRANCE)\r\n\tfloat m = sqrt(2.0 / max("
"shininess, EPSILON));\r\n\r\n\tfloat m_sq = m * m;\r\n\tfloat NH_sq = NH * "
"NH;\r\n\tfloat beckmann = exp((NH_sq - 1.0) / max(m_sq * NH_sq, EPSILON)) /"
" max(4.0 * m_sq * NH_sq * NH_sq, EPSILON);\r\n\r\n\treturn fresnel * geo * "
"beckmann / max(NE, EPSILON);\r\n #endif\r\n\r\n #if defined(USE_TRIACE)\r"
"\n\tfloat scale = 0.1248582 * shininess + 0.2691817;\r\n\r\n\treturn fresne"
"l * scale * blinn / max(max(NL, NE), EPSILON);\r\n #endif\r\n \r\n #if d"
"efined(USE_TORRANCE_SPARROW)\r\n\tfloat scale = 0.125 * shininess + 1.0;\r"
"\n\r\n\treturn fresnel * geo * scale * blinn / max(NE, EPSILON);\r\n #endi"
"f\r\n}\r\n#endif\r\n\r\nfloat PCF(sampler2D shadowmap, vec2 st, float dist)"
"\r\n{\r\n\tfloat mult;\r\n\t\r\n\tmult = sign(clamp(texture2D(shadowmap, s"
"t + vec2(-1.0, -1.0) / 1024.0).r - dist, 0.0, 1.0));\r\n\tmult += sign(clam"
"p(texture2D(shadowmap, st + vec2( 1.0, -1.0) / 1024.0).r - dist, 0.0, 1.0))"
";\r\n\tmult += sign(clamp(texture2D(shadowmap, st + vec2(-1.0, 1.0) / 1024"
".0).r - dist, 0.0, 1.0));\r\n\tmult += sign(clamp(texture2D(shadowmap, st +"
" vec2( 1.0, 1.0) / 1024.0).r - dist, 0.0, 1.0));\r\n\tmult *= 0.25;\r\n\t"
"\r\n\t//mult = sign(clamp(texture2D(shadowmap, st).r - dist, 0.0, 1.0));\r"
"\n\t\t\r\n\treturn mult;\r\n}\r\n\r\nvoid main()\r\n{\r\n#if defined(USE_LI"
"GHT) || defined(USE_NORMALMAP)\r\n\tvec3 surfNormal = normalize(var_Normal)"
";\r\n#endif\r\n\r\n#if defined(USE_DELUXEMAP)\r\n\tvec3 worldLight = 2.0 * "
"texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0);\r\n\t//worldLight += "
"var_WorldLight * 0.0001;\r\n#elif defined(USE_LIGHT)\r\n\tvec3 worldLight ="
" var_WorldLight;\r\n#endif\r\n\r\n#if defined(USE_LIGHTMAP)\r\n\tvec4 light"
"Sample = texture2D(u_LightMap, var_LightTex).rgba;\r\n #if defined(RGBE_LI"
"GHTMAP)\r\n\tlightSample.rgb *= exp2(lightSample.a * 255.0 - 128.0);\r\n #"
"endif\r\n\tvec3 directedLight = lightSample.rgb * u_MapLightScale;\r\n#elif"
" defined(USE_LIGHT_VECTOR)\r\n #if defined(USE_FAST_LIGHT)\r\n\tvec3 direc"
"tedLight = var_VectLight;\r\n #else\r\n #if defined(USE_INVSQRLIGHT)\r"
"\n\tfloat intensity = 1.0 / dot(worldLight, worldLight);\r\n #else\r\n\t"
"float intensity = clamp((1.0 - dot(worldLight, worldLight) / (u_LightRadius"
" * u_LightRadius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n\r\n\tvec3 directedL"
"ight = u_DirectedLight * intensity;\r\n\tvec3 ambientLight = u_AmbientLigh"
"t;\r\n #endif\r\n\r\n #if defined(USE_SHADOWMAP)\r\n\tvec4 biasPos = vec4"
"(var_Position + surfNormal * (length(var_SampleToView) * 0.005 + 0.05), 1.0"
");\r\n\tvec4 shadowpos = u_ShadowMvp * biasPos;\r\n\tfloat outside1 = dot(v"
"ec3(1.0, 1.0, 1.0), sign(clamp(abs(shadowpos.xyz) - 1.0, 0.0, 1.0)));\r\n\t"
"\r\n\t#if defined(USE_SHADOW_CASCADE)\r\n\tvec4 shadowpos2 = u_ShadowMvp2 *"
" biasPos;\r\n\tfloat outside2 = dot(vec3(1.0, 1.0, 1.0), sign(clamp(abs(sha"
"dowpos2.xyz) - 1.0, 0.0, 1.0)));\r\n\r\n\tvec4 shadowpos3 = u_ShadowMvp3 * "
"biasPos;\r\n\tfloat outside3 = dot(vec3(1.0, 1.0, 1.0), sign(clamp(abs(shad"
"owpos3.xyz) - 1.0, 0.0, 1.0)));\r\n\t\r\n\tif (outside1 < 1.0)\r\n\t{\r\n\t"
"\tshadowpos.xyz = shadowpos.xyz * 0.5 + 0.5;\r\n\t\tdirectedLight *= PCF(u_"
"ShadowMap, shadowpos.xy, shadowpos.z);\r\n\t}\r\n\telse if (outside2 < 1.0)"
"\r\n\t{\r\n\t\tshadowpos2.xyz = shadowpos2.xyz * 0.5 + 0.5;\r\n\t\tdirected"
"Light *= PCF(u_ShadowMap2, shadowpos2.xy, shadowpos2.z);\r\n\t}\r\n\telse i"
"f (outside3 < 1.0)\r\n\t{\r\n\t\tshadowpos3.xyz = shadowpos3.xyz * 0.5 + 0."
"5;\r\n\t\tfloat mult = PCF(u_ShadowMap3, shadowpos3.xy, shadowpos3.z) + cla"
"mp(length(var_SampleToView) / 1024.0 - 0.95, 0.0, 1.0);\r\n\t\tdirectedLigh"
"t *= clamp(mult, 0.0, 1.0);\r\n\t}\r\n\t\r\n\t#else\r\n\tshadowpos.xyz = sh"
"adowpos.xyz * 0.5 + 0.5;\r\n\tdirectedLight *= clamp(PCF(u_ShadowMap, shado"
"wpos.xy, shadowpos.z) - outside1, 1.0, 0.0);\r\n\t#endif\r\n #endif\r\n#el"
"if defined(USE_LIGHT_VERTEX)\r\n\tvec3 directedLight = var_Color.rgb * u_Ma"
"pLightScale;\r\n#endif\r\n\t\r\n#if defined(USE_NORMALMAP) || defined(USE_L"
"IGHT) && !defined(USE_FAST_LIGHT)\r\n\tvec3 SampleToView = normalize(var_Sa"
"mpleToView);\r\n#endif\r\n\tvec2 tex = var_DiffuseTex;\r\n\r\n\tfloat ambie"
"ntDiff = 1.0;\r\n\r\n#if defined(USE_NORMALMAP)\r\n #if defined(USE_VERT_T"
"ANGENT_SPACE)\r\n vec3 tangent = normalize(var_Tangent);\r\n\tvec3 bit"
"angent = normalize(var_Bitangent);\r\n #else\r\n\tvec3 q0 = dFdx(var_Posi"
"tion);\r\n\tvec3 q1 = dFdy(var_Position);\r\n\tvec2 st0 = dFdx(tex);\r\n\t"
"vec2 st1 = dFdy(tex);\r\n\tfloat dir = sign(st1.t * st0.s - st0.t * st1.s);"
"\r\n\r\n\tvec3 tangent = normalize( q0 * st1.t - q1 * st0.t) * dir;\r\n\t"
"vec3 bitangent = -normalize( q0 * st1.s - q1 * st0.s) * dir;\r\n #endif\r"
"\n\r\n\tmat3 tangentToWorld = mat3(tangent, bitangent, surfNormal);\r\n\r\n"
" #if defined(USE_PARALLAXMAP)\r\n\tvec3 offsetDir = normalize(SampleToView"
" * tangentToWorld);\r\n #if 0\r\n float height = SampleHeight(u_Norma"
"lMap, tex);\r\n\tfloat pdist = 0.05 * height - (0.05 / 2.0);\r\n #else\r"
"\n\toffsetDir.xy *= -0.05 / offsetDir.z;\r\n\tfloat pdist = RayIntersectDis"
"placeMap(tex, offsetDir.xy, u_NormalMap);\r\n #endif\t\r\n\ttex += offse"
"tDir.xy * pdist;\r\n #endif\r\n #if defined(SWIZZLE_NORMALMAP)\r\n\tvec3 "
"normal = 2.0 * texture2D(u_NormalMap, tex).agb - 1.0;\r\n #else\r\n\tvec3 "
"normal = 2.0 * texture2D(u_NormalMap, tex).rgb - 1.0;\r\n #endif\r\n\tnorm"
"al.z = sqrt(clamp(1.0 - dot(normal.xy, normal.xy), 0.0, 1.0));\r\n\tvec3 wo"
"rldNormal = tangentToWorld * normal;\r\n #if defined(r_normalAmbient)\r\n"
"\tambientDiff = 0.781341 * normal.z + 0.218659;\r\n #endif\r\n#elif define"
"d(USE_LIGHT)\r\n\tvec3 worldNormal = surfNormal;\r\n#endif\r\n\r\n\tvec4 di"
"ffuse = texture2D(u_DiffuseMap, tex);\r\n\r\n#if defined(USE_LIGHT) && defi"
"ned(USE_FAST_LIGHT)\r\n\tdiffuse.rgb *= directedLight;\r\n#elif defined(USE"
"_LIGHT)\r\n\tworldNormal = normalize(worldNormal);\r\n\tworldLight = normal"
"ize(worldLight);\r\n\r\n #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VE"
"RTEX)\r\n\tdirectedLight /= max(dot(surfNormal, worldLight), 0.004);\r\n\r"
"\n #if defined(r_normalAmbient)\r\n\tvec3 ambientLight = directedLight *"
" r_normalAmbient;\r\n\tdirectedLight -= ambientLight;\r\n #else\r\n\tvec"
"3 ambientLight = vec3(0);\r\n #endif\r\n #endif\r\n\r\n\tfloat NL = cla"
"mp(dot(worldNormal, worldLight), 0.0, 1.0);\r\n\tfloat surfNL = clamp(do"
"t(surfNormal, worldLight), 0.0, 1.0);\r\n\tNL = min(NL, surfNL * 2.0);\r"
"\n\tfloat NE = clamp(dot(worldNormal, SampleToView), 0.0, 1.0);\r\n\t\r\n"
"\tfloat fzero = u_MaterialInfo.x;\r\n\tfloat shininess = u_MaterialInfo.y;"
"\r\n #if defined(USE_SPECULARMAP)\r\n\tvec4 specular = texture2D(u_Specula"
"rMap, tex);\r\n\t//specular.rgb = clamp(specular.rgb - diffuse.rgb, 0.0, 1."
"0);\r\n\tshininess *= specular.a;\r\n #endif\r\n\tfloat directedDiff = NL "
"* CalcDiffuse(worldNormal, worldLight, SampleToView, NE, NL, fzero, shinine"
"ss);\r\n\tdiffuse.rgb *= directedLight * directedDiff + ambientDiff * ambie"
"ntLight;\r\n \r\n #if defined(USE_SPECULARMAP)\r\n\tvec3 halfAngle = norm"
"alize(worldLight + SampleToView);\r\n\r\n\tfloat EH = clamp(dot(SampleToVie"
"w, halfAngle), 0.0, 1.0);\r\n\tfloat NH = clamp(dot(worldNormal, halfAngle"
"), 0.0, 1.0);\r\n\r\n\tfloat directedSpec = NL * CalcSpecular(NH, NL, NE, E"
"H, fzero, shininess);\r\n \r\n #if defined(r_normalAmbient)\r\n\tvec3 a"
"mbientHalf = normalize(surfNormal + SampleToView);\r\n\tfloat ambientSpec ="
" max(dot(ambientHalf, worldNormal) + 0.5, 0.0);\r\n\tambientSpec *= ambient"
"Spec * 0.44;\r\n\tambientSpec = pow(ambientSpec, shininess) * fzero;\r\n\ts"
"pecular.rgb *= directedSpec * directedLight + ambientSpec * ambientLight;\r"
"\n #else\r\n\tspecular.rgb *= directedSpec * directedLight;\r\n #endi"
"f\r\n #endif\r\n#endif\r\n\r\n\tgl_FragColor = diffuse;\r\n\r\n#if defined"
"(USE_SPECULARMAP) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)\r\n\tgl"
"_FragColor.rgb += specular.rgb;\r\n#endif\r\n\r\n#if !defined(USE_LIGHT_VER"
"TEX)\r\n\tgl_FragColor *= var_Color;\r\n#endif\r\n}\r\n";
static const char *fallbackShadowfillShader_vp =
"attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute"
@ -935,7 +940,7 @@ static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, c
}
//GLSL_PrintInfoLog(shader, qtrue);
//ri.Printf(PRINT_ALL, "%s\n", GLSL_PrintShaderSource(shader));
//GLSL_PrintShaderSource(shader);
if (*prevShader)
{
@ -1839,7 +1844,7 @@ void GLSL_InitGPUShaders(void)
Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n");
#ifdef USE_VERT_TANGENT_SPACE
Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE");
Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n");
attribs |= ATTR_TANGENT | ATTR_BITANGENT;
#endif
}
@ -1875,10 +1880,10 @@ void GLSL_InitGPUShaders(void)
if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
if ((i & LIGHTDEF_USE_SHADOWMAP))
if (i & LIGHTDEF_USE_SHADOWMAP)
Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
if ((i & LIGHTDEF_USE_SHADOW_CASCADE))
if (i & LIGHTDEF_USE_SHADOW_CASCADE)
Q_strcat(extradefines, 1024, "#define USE_SHADOW_CASCADE\n");
if (i & LIGHTDEF_TCGEN_ENVIRONMENT)
@ -1932,6 +1937,8 @@ void GLSL_InitGPUShaders(void)
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMVP, "u_ShadowMvp", GLSL_MAT16);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMVP2, "u_ShadowMvp2", GLSL_MAT16);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMVP3, "u_ShadowMvp3", GLSL_MAT16);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_MAPLIGHTSCALE, "u_MapLightScale", GLSL_FLOAT);
GLSL_EndUniforms(&tr.lightallShader[i]);

View file

@ -69,6 +69,8 @@ typedef unsigned int glIndex_t;
#define PSHADOW_MAP_SIZE 512
#define SUNSHADOW_MAP_SIZE 1024
#define USE_VERT_TANGENT_SPACE
typedef struct dlight_s {
vec3_t origin;
vec3_t color; // range from 0.0 to 1.0, should be color normalized
@ -874,6 +876,7 @@ enum
GENERIC_UNIFORM_SHADOWMVP,
GENERIC_UNIFORM_SHADOWMVP2,
GENERIC_UNIFORM_SHADOWMVP3,
GENERIC_UNIFORM_MAPLIGHTSCALE,
GENERIC_UNIFORM_COUNT
};
@ -901,9 +904,7 @@ typedef struct {
float floatTime; // tr.refdef.time / 1000.0
#ifdef REACTION
float blurFactor;
#endif
// text messages for deform text shaders
char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH];
@ -927,6 +928,7 @@ typedef struct {
float sunShadowMvp[3][16];
float sunDir[4];
float sunCol[4];
float mapLightScale;
} trRefdef_t;
@ -958,14 +960,21 @@ typedef struct {
float surface[4];
} fog_t;
typedef enum {
VPF_NONE = 0x00,
VPF_SHADOWMAP = 0x01,
VPF_DEPTHSHADOW = 0x02,
VPF_DEPTHCLAMP = 0x04,
VPF_ORTHOGRAPHIC = 0x08,
} viewParmFlags_t;
typedef struct {
orientationr_t or;
orientationr_t world;
vec3_t pvsOrigin; // may be different than or.origin for portals
qboolean isPortal; // true if this view is through a portal
qboolean isMirror; // the portal is a mirror, invert the face culling
qboolean isShadowmap;
qboolean isDepthShadow;
viewParmFlags_t flags;
int frameSceneNum; // copied from tr.frameSceneNum
int frameCount; // copied from tr.frameCount
cplane_t portalPlane; // clip anything behind this if mirroring
@ -1837,6 +1846,9 @@ typedef struct {
int viewCluster;
float mapLightScale;
qboolean sunShadows;
vec3_t sunLight; // from the sky shader for this level
vec3_t sunDirection;

View file

@ -1245,6 +1245,79 @@ void R_SetupProjectionZ(viewParms_t *dest)
}
/*
===============
R_SetupProjectionOrtho
===============
*/
void R_SetupProjectionOrtho(viewParms_t *dest, vec3_t viewBounds[2])
{
float xmin, xmax, ymin, ymax, znear, zfar;
//viewParms_t *dest = &tr.viewParms;
int i;
vec3_t pop;
// Quake3: Projection:
//
// Z X Y Z
// | / | /
// |/ |/
// Y--+ +--X
xmin = viewBounds[0][1];
xmax = viewBounds[1][1];
ymin = -viewBounds[1][2];
ymax = -viewBounds[0][2];
znear = viewBounds[0][0];
zfar = viewBounds[1][0];
dest->projectionMatrix[0] = 2 / (xmax - xmin);
dest->projectionMatrix[4] = 0;
dest->projectionMatrix[8] = 0;
dest->projectionMatrix[12] = (xmax + xmin) / (xmax - xmin);
dest->projectionMatrix[1] = 0;
dest->projectionMatrix[5] = 2 / (ymax - ymin);
dest->projectionMatrix[9] = 0;
dest->projectionMatrix[13] = (ymax + ymin) / (ymax - ymin);
dest->projectionMatrix[2] = 0;
dest->projectionMatrix[6] = 0;
dest->projectionMatrix[10] = -2 / (zfar - znear);
dest->projectionMatrix[14] = -(zfar + znear) / (zfar - znear);
dest->projectionMatrix[3] = 0;
dest->projectionMatrix[7] = 0;
dest->projectionMatrix[11] = 0;
dest->projectionMatrix[15] = 1;
VectorScale(dest->or.axis[1], 1.0f, dest->frustum[0].normal);
VectorMA(dest->or.origin, viewBounds[0][1], dest->frustum[0].normal, pop);
dest->frustum[0].dist = DotProduct(pop, dest->frustum[0].normal);
VectorScale(dest->or.axis[1], -1.0f, dest->frustum[1].normal);
VectorMA(dest->or.origin, -viewBounds[1][1], dest->frustum[1].normal, pop);
dest->frustum[1].dist = DotProduct(pop, dest->frustum[1].normal);
VectorScale(dest->or.axis[2], 1.0f, dest->frustum[2].normal);
VectorMA(dest->or.origin, viewBounds[0][2], dest->frustum[2].normal, pop);
dest->frustum[2].dist = DotProduct(pop, dest->frustum[2].normal);
VectorScale(dest->or.axis[2], -1.0f, dest->frustum[3].normal);
VectorMA(dest->or.origin, -viewBounds[1][2], dest->frustum[3].normal, pop);
dest->frustum[3].dist = DotProduct(pop, dest->frustum[3].normal);
VectorScale(dest->or.axis[0], -1.0f, dest->frustum[4].normal);
VectorMA(dest->or.origin, -viewBounds[1][0], dest->frustum[4].normal, pop);
dest->frustum[4].dist = DotProduct(pop, dest->frustum[4].normal);
for (i = 0; i < 5; i++)
{
dest->frustum[i].type = PLANE_NON_AXIAL;
SetPlaneSignbits (&dest->frustum[i]);
}
}
/*
=================
R_MirrorPoint
@ -1831,7 +1904,8 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
// sort the drawsurfs by sort type, then orientation, then shader
R_RadixSort( drawSurfs, numDrawSurfs );
if (tr.viewParms.isShadowmap || tr.viewParms.isDepthShadow)
// skip pass through drawing if rendering a shadow map
if ((tr.viewParms.flags & VPF_SHADOWMAP) || (tr.viewParms.flags & VPF_DEPTHSHADOW))
{
R_AddDrawSurfCmd( drawSurfs, numDrawSurfs );
return;
@ -1883,7 +1957,8 @@ static void R_AddEntitySurface (int entityNum)
// we don't want the hacked weapon position showing in
// mirrors, because the true body position will already be drawn
//
if ( (ent->e.renderfx & RF_FIRST_PERSON) && (tr.viewParms.isPortal || tr.viewParms.isShadowmap || tr.viewParms.isDepthShadow)) {
if ( (ent->e.renderfx & RF_FIRST_PERSON) && (tr.viewParms.isPortal
|| (tr.viewParms.flags & VPF_SHADOWMAP) || (tr.viewParms.flags & VPF_DEPTHSHADOW))) {
return;
}
@ -1983,7 +2058,7 @@ void R_GenerateDrawSurfs( void ) {
// matrix for lod calculation
// dynamically compute far clip plane distance
if (!tr.viewParms.isShadowmap)
if (!(tr.viewParms.flags & VPF_SHADOWMAP))
{
R_SetFarClip();
}
@ -2113,8 +2188,7 @@ void R_RenderDlightCubemaps(const refdef_t *fd)
shadowParms.fovX = 90;
shadowParms.fovY = 90;
shadowParms.isShadowmap = qtrue;
shadowParms.isDepthShadow = qtrue;
shadowParms.flags = VPF_SHADOWMAP | VPF_DEPTHSHADOW;
shadowParms.zFar = tr.refdef.dlights[i].radius;
VectorCopy( tr.refdef.dlights[i].origin, shadowParms.or.origin );
@ -2420,9 +2494,7 @@ void R_RenderPshadowMaps(const refdef_t *fd)
if (glRefConfig.framebufferObject)
shadowParms.targetFbo = tr.pshadowFbos[i];
shadowParms.isShadowmap = qtrue;
shadowParms.isDepthShadow = qtrue;
shadowParms.flags = VPF_SHADOWMAP | VPF_DEPTHSHADOW;
shadowParms.zFar = shadow->lightRadius;
VectorCopy(shadow->lightOrigin, shadowParms.or.origin);
@ -2523,9 +2595,10 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
vec3_t up;
vec3_t lightViewAxis[3];
vec3_t lightOrigin;
float xmin, xmax, ymin, ymax, znear, zfar, viewznear, viewzfar;
float viewznear, viewzfar;
vec3_t lightviewBounds[2];
if (r_testSunlight->integer)
if (r_testSunlight->integer == 2)
{
int scale = 32768;
float angle = (fd->time % scale) / (float)scale * M_PI;
@ -2557,46 +2630,46 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
VectorCopy4(tr.refdef.sunDir, lightDir);
}
//viewRadius = 128;
//lightRadius = 4096;
switch(level)
{
case 0:
default:
//viewznear = r_znear->value;
//viewzfar = 256;
viewznear = r_znear->value;
viewzfar = 256;
viewzfar = 128;
break;
case 1:
viewznear = 256;
viewzfar = 768;
viewznear = 128;
viewzfar = 384;
//viewznear = 256;
//viewzfar = 896;
break;
case 2:
viewznear = 768;
viewzfar = 2048;
viewznear = 384;
viewzfar = 1024;
//viewznear = 896;
//viewzfar = 3072;
break;
}
VectorCopy(fd->vieworg, lightOrigin);
//VectorMA(fd->vieworg, (zfar - znear) / 2, lightDir, lightOrigin);
//VectorMA(lightOrigin, (xmax - xmin) / 2, fd->viewaxis[0], lightOrigin);
//ri.Printf(PRINT_ALL, "viewOrigin %f %f %f\n", fd->vieworg[0], fd->vieworg[1], fd->vieworg[2]);
//ri.Printf(PRINT_ALL, "forward %f %f %f\n", fd->viewaxis[0][0], fd->viewaxis[0][1], fd->viewaxis[0][2]);
//ri.Printf(PRINT_ALL, "right %f %f %f\n", fd->viewaxis[1][0], fd->viewaxis[1][1], fd->viewaxis[1][2]);
//ri.Printf(PRINT_ALL, "up %f %f %f\n", fd->viewaxis[2][0], fd->viewaxis[2][1], fd->viewaxis[2][2]);
//ri.Printf(PRINT_ALL, "lightOrigin %f %f %f\n", lightOrigin[0], lightOrigin[1], lightOrigin[2]);
// make up a projection
VectorScale(lightDir, -1.0f, lightViewAxis[0]);
// try to use player right as up
VectorCopy(fd->viewaxis[1], up);
//VectorSet(up, 0, 1, 0);
// try to use halfway between player right and player forward as up
//VectorCopy(fd->viewaxis[1], up);
VectorScale(fd->viewaxis[0], 0.5f, up);
VectorMA(up, 0.5f, fd->viewaxis[1], up);
if ( abs(DotProduct(up, lightViewAxis[0])) > 0.9f )
{
VectorCopy(fd->viewaxis[2], up);
//VectorSet(up, 0, 0, 1);
// if not, halfway between player up and player forward
//VectorCopy(fd->viewaxis[2], up);
VectorScale(fd->viewaxis[0], 0.5f, up);
VectorMA(up, 0.5f, fd->viewaxis[2], up);
}
CrossProduct(lightViewAxis[0], up, lightViewAxis[1]);
@ -2605,7 +2678,6 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
{
matrix_t lightViewMatrix;
vec3_t lightviewBounds[2];
vec4_t point, base, lightViewPoint;
float lx, ly;
@ -2635,9 +2707,6 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
ClearBounds(lightviewBounds[0], lightviewBounds[1]);
//viewznear = r_znear->value;
//viewzfar = 512;
// add view near plane
lx = viewznear * tan(fd->fov_x * M_PI / 360.0f);
ly = viewznear * tan(fd->fov_y * M_PI / 360.0f);
@ -2689,19 +2758,10 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
xmin = lightviewBounds[0][1];
xmax = lightviewBounds[1][1];
ymin = -lightviewBounds[1][2];
ymax = -lightviewBounds[0][2];
zfar = lightviewBounds[1][0];
if (!glRefConfig.depthClamp)
lightviewBounds[0][0] = lightviewBounds[1][0] - 8192;
if (glRefConfig.depthClamp)
znear = lightviewBounds[0][0];
else
znear = zfar - 8192;
//ri.Printf(PRINT_ALL, "znear %f zfar %f\n", lightviewBounds[0][0], lightviewBounds[1][0]);
//ri.Printf(PRINT_ALL, "znear %f zfar %f\n", lightviewBounds[0][0], lightviewBounds[1][0]);
//ri.Printf(PRINT_ALL, "fovx %f fovy %f xmin %f xmax %f ymin %f ymax %f\n", fd->fov_x, fd->fov_y, xmin, xmax, ymin, ymax);
}
@ -2733,10 +2793,8 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
if (glRefConfig.framebufferObject)
shadowParms.targetFbo = tr.sunShadowFbo[level];
shadowParms.isShadowmap = qfalse;
shadowParms.isDepthShadow = qtrue;
shadowParms.zFar = zfar;
shadowParms.flags = VPF_DEPTHSHADOW | VPF_DEPTHCLAMP | VPF_ORTHOGRAPHIC;
shadowParms.zFar = lightviewBounds[1][0];
VectorCopy(lightOrigin, shadowParms.or.origin);
@ -2760,79 +2818,17 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level)
// set viewParms.world
R_RotateForViewer ();
{
//float xmin, xmax, ymin, ymax, znear, zfar;
viewParms_t *dest = &tr.viewParms;
vec3_t pop;
dest->projectionMatrix[0] = 2 / (xmax - xmin);
dest->projectionMatrix[4] = 0;
dest->projectionMatrix[8] = 0;
dest->projectionMatrix[12] = (xmax + xmin) / (xmax - xmin);
dest->projectionMatrix[1] = 0;
dest->projectionMatrix[5] = 2 / (ymax - ymin);
dest->projectionMatrix[9] = 0;
dest->projectionMatrix[13] = ( ymax + ymin ) / (ymax - ymin);
dest->projectionMatrix[2] = 0;
dest->projectionMatrix[6] = 0;
dest->projectionMatrix[10] = -2 / (zfar - znear);
dest->projectionMatrix[14] = (zfar + znear) / (znear - zfar);
dest->projectionMatrix[3] = 0;
dest->projectionMatrix[7] = 0;
dest->projectionMatrix[11] = 0;
dest->projectionMatrix[15] = 1;
Matrix16Multiply(dest->projectionMatrix, tr.viewParms.world.modelMatrix, tr.refdef.sunShadowMvp[level]);
VectorScale(dest->or.axis[1], 1.0f, dest->frustum[0].normal);
VectorMA(dest->or.origin, xmin, dest->frustum[0].normal, pop);
dest->frustum[0].dist = DotProduct(pop, dest->frustum[0].normal);
VectorScale(dest->or.axis[1], -1.0f, dest->frustum[1].normal);
VectorMA(dest->or.origin, -xmax, dest->frustum[1].normal, pop);
dest->frustum[1].dist = DotProduct(pop, dest->frustum[1].normal);
VectorScale(dest->or.axis[2], 1.0f, dest->frustum[2].normal);
VectorMA(dest->or.origin, -ymax, dest->frustum[2].normal, pop);
dest->frustum[2].dist = DotProduct(pop, dest->frustum[2].normal);
VectorScale(dest->or.axis[2], -1.0f, dest->frustum[3].normal);
VectorMA(dest->or.origin, ymin, dest->frustum[3].normal, pop);
dest->frustum[3].dist = DotProduct(pop, dest->frustum[3].normal);
VectorScale(dest->or.axis[0], -1.0f, dest->frustum[4].normal);
VectorMA(dest->or.origin, -zfar, dest->frustum[4].normal, pop);
dest->frustum[4].dist = DotProduct(pop, dest->frustum[4].normal);
for (j = 0; j < 5; j++)
{
dest->frustum[j].type = PLANE_NON_AXIAL;
SetPlaneSignbits (&dest->frustum[j]);
}
}
R_SetupProjectionOrtho(&tr.viewParms, lightviewBounds);
R_AddWorldSurfaces ();
R_AddPolygonSurfaces();
// set the projection matrix with the minimum zfar
// now that we have the world bounded
// this needs to be done before entities are
// added, because they use the projection
// matrix for lod calculation
// dynamically compute far clip plane distance
//R_SetFarClip();
// we know the size of the clipping volume. Now set the rest of the projection matrix.
//R_SetupProjectionZ (&tr.viewParms);
R_AddEntitySurfaces ();
R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf );
}
Matrix16Multiply(tr.viewParms.projectionMatrix, tr.viewParms.world.modelMatrix, tr.refdef.sunShadowMvp[level]);
}
}

View file

@ -295,7 +295,8 @@ void R_AddMD3Surfaces( trRefEntity_t *ent ) {
qboolean personalModel;
// don't add third_person objects if not in a portal
personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !(tr.viewParms.isPortal || tr.viewParms.isShadowmap || tr.viewParms.isDepthShadow);
personalModel = (ent->e.renderfx & RF_THIRD_PERSON) && !(tr.viewParms.isPortal
|| (tr.viewParms.flags & VPF_SHADOWMAP) || (tr.viewParms.flags & VPF_DEPTHSHADOW));
if ( ent->e.renderfx & RF_WRAP_FRAMES ) {
ent->e.frame %= tr.currentModel->mdv[0]->numFrames;

View file

@ -365,27 +365,37 @@ void RE_RenderScene( const refdef_t *fd ) {
}
}
tr.refdef.sunDir[3] = 0.0f;
tr.refdef.sunCol[3] = 1.0f;
VectorCopy(tr.sunDirection, tr.refdef.sunDir);
if (r_testSunlight->integer == 1)
{
tr.refdef.mapLightScale = 0.66f;
VectorScale(tr.sunLight, pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8) * 0.33f, tr.refdef.sunCol);
}
else
{
tr.refdef.mapLightScale = tr.mapLightScale;
VectorScale(tr.sunLight, pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8), tr.refdef.sunCol);
}
//#ifdef REACTION
// Makro - copy exta info if present
if (fd->rdflags & RDF_EXTRA) {
const refdefex_t* extra = (const refdefex_t*) (fd+1);
#ifdef REACTION
tr.refdef.blurFactor = extra->blurFactor;
#endif
if (fd->rdflags & RDF_SUNLIGHT)
{
VectorCopy(extra->sunDir, tr.refdef.sunDir);
tr.refdef.sunDir[3] = 0.0f;
VectorCopy(extra->sunCol, tr.refdef.sunCol);
tr.refdef.sunCol[3] = 1.0f;
}
} else {
#ifdef REACTION
tr.refdef.blurFactor = 0.f;
#endif
VectorSet4(tr.refdef.sunDir, 0.0f, 1.0f, 0.0f, 0.0f);
VectorSet4(tr.refdef.sunCol, 1.0f, 1.0f, 1.0f, 1.0f);
}
else
{
tr.refdef.blurFactor = 0.0f;
}
//#endif
@ -437,7 +447,7 @@ void RE_RenderScene( const refdef_t *fd ) {
}
// playing with even more shadows
if(!( fd->rdflags & RDF_NOWORLDMODEL ) && ((fd->rdflags & RDF_SUNLIGHT) || r_testSunlight->integer))
if(!( fd->rdflags & RDF_NOWORLDMODEL ) && (r_testSunlight->integer || tr.sunShadows))
{
R_RenderSunShadowMaps(fd, 0);
R_RenderSunShadowMaps(fd, 1);

View file

@ -207,7 +207,7 @@ void RB_BeginSurface( shader_t *shader, int fogNum ) {
tess.shaderTime = tess.shader->clampTime;
}
if (backEnd.viewParms.isShadowmap)
if (backEnd.viewParms.flags & VPF_SHADOWMAP)
{
tess.currentStageIteratorFunc = RB_StageIteratorGeneric;
}
@ -1371,6 +1371,8 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
GLSL_SetUniformVec2(sp, GENERIC_UNIFORM_MATERIALINFO, pStage->materialInfo);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale);
//
// do multitexture
//
@ -1588,14 +1590,17 @@ void RB_StageIteratorGeneric( void )
//
// set face culling appropriately
//
if (backEnd.viewParms.isDepthShadow)
if ((backEnd.viewParms.flags & VPF_DEPTHSHADOW))
{
GL_Cull( CT_TWO_SIDED );
/*
if (input->shader->cullType == CT_TWO_SIDED)
GL_Cull( CT_TWO_SIDED );
else if (input->shader->cullType == CT_FRONT_SIDED)
GL_Cull( CT_BACK_SIDED );
else
GL_Cull( CT_FRONT_SIDED );
*/
}
else
GL_Cull( input->shader->cullType );
@ -1633,7 +1638,7 @@ void RB_StageIteratorGeneric( void )
//
// render shadowmap if in shadowmap mode
//
if (backEnd.viewParms.isShadowmap)
if (backEnd.viewParms.flags & VPF_SHADOWMAP)
{
if ( input->shader->sort == SS_OPAQUE )
{
@ -1681,7 +1686,7 @@ void RB_StageIteratorGeneric( void )
}
}
if (((backEnd.refdef.rdflags & RDF_SUNLIGHT) || r_testSunlight->integer) && tess.shader->sort <= SS_OPAQUE
if ((tr.sunShadows || r_testSunlight->integer) && tess.shader->sort <= SS_OPAQUE
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) {
ForwardSunlight();
}

View file

@ -1606,9 +1606,12 @@ static qboolean ParseShader( char **text )
continue;
}
// sun parms
else if ( !Q_stricmp( token, "q3map_sun" ) ) {
else if ( !Q_stricmp( token, "q3map_sun" ) || !Q_stricmp( token, "q3map_sunExt" ) || !Q_stricmp( token, "q3gl2_sun" ) ) {
float a, b;
if (!Q_stricmp( token, "q3gl2_sun" ) )
tr.sunShadows = qtrue;
token = COM_ParseExt( text, qfalse );
tr.sunLight[0] = atof( token );
token = COM_ParseExt( text, qfalse );
@ -1633,6 +1636,8 @@ static qboolean ParseShader( char **text )
tr.sunDirection[0] = cos( a ) * cos( b );
tr.sunDirection[1] = sin( a ) * cos( b );
tr.sunDirection[2] = sin( b );
SkipRestOfLine( text );
}
else if ( !Q_stricmp( token, "deformVertexes" ) ) {
ParseDeform( text );

View file

@ -53,8 +53,14 @@ static qboolean R_CullSurface( msurface_t *surf ) {
return qfalse;
}
// don't cull for depth shadow
if ( (tr.viewParms.flags & VPF_DEPTHSHADOW ) )
{
return qfalse;
}
// shadowmaps draw back surfaces
if ( tr.viewParms.isShadowmap || tr.viewParms.isDepthShadow)
if ( (tr.viewParms.flags & VPF_SHADOWMAP) )
{
if (ct == CT_FRONT_SIDED)
{
@ -66,8 +72,8 @@ static qboolean R_CullSurface( msurface_t *surf ) {
}
}
// FIXME: actually cull properly for depth shadows
if (tr.viewParms.isDepthShadow) {
// do proper cull for orthographic projection
if (tr.viewParms.flags & VPF_ORTHOGRAPHIC) {
d = DotProduct(tr.viewParms.or.axis[0], surf->cullinfo.plane.normal);
if ( ct == CT_FRONT_SIDED ) {
if (d > 0)
@ -403,7 +409,7 @@ static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits,
// if the node wasn't marked as potentially visible, exit
// pvs is skipped for depth shadows
if (!tr.viewParms.isDepthShadow && node->visCounts[tr.visIndex] != tr.visCounts[tr.visIndex]) {
if (!(tr.viewParms.flags & VPF_DEPTHSHADOW) && node->visCounts[tr.visIndex] != tr.visCounts[tr.visIndex]) {
return;
}
@ -786,7 +792,7 @@ void R_AddWorldSurfaces (void) {
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT;
// determine which leaves are in the PVS / areamask
if (!tr.viewParms.isDepthShadow)
if (!(tr.viewParms.flags & VPF_DEPTHSHADOW))
R_MarkLeaves ();
// clear out the visible min/max
@ -801,11 +807,11 @@ void R_AddWorldSurfaces (void) {
tr.refdef.num_pshadows = 32 ;
}
if ( tr.viewParms.isDepthShadow )
if ( tr.viewParms.flags & VPF_DEPTHSHADOW )
{
R_RecursiveWorldNode( tr.world->nodes, 31, 0, 0);
}
else if ( !tr.viewParms.isShadowmap )
else if ( !tr.viewParms.flags & VPF_SHADOWMAP )
{
R_RecursiveWorldNode( tr.world->nodes, 15, ( 1 << tr.refdef.num_dlights ) - 1, ( 1 << tr.refdef.num_pshadows ) - 1 );
}