Add cascaded shadow mapping, test with r_testSunlight 1.

This commit is contained in:
James Canete 2012-06-26 07:09:48 +00:00
parent 9915d6ea56
commit 3d55fd3731
15 changed files with 2220 additions and 1560 deletions

View file

@ -1,3 +1,4 @@
- Add cascaded shadow mapping, test with r_testSunlight 1.
- Add r_depthPrepass. - Add r_depthPrepass.
- Improve parallax mapping - Improve parallax mapping
- Add AVG_MAP, BLACK_LEVEL, and WHITE_LEVEL defines to tonemap shader - Add AVG_MAP, BLACK_LEVEL, and WHITE_LEVEL defines to tonemap shader

View file

@ -355,6 +355,34 @@ extern void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLs
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
#endif #endif
// GL_ARB_draw_buffers
extern void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
#ifndef GL_ARB_draw_buffers
#define GL_ARB_draw_buffers
#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
#define GL_DRAW_BUFFER0_ARB 0x8825
#define GL_DRAW_BUFFER1_ARB 0x8826
#define GL_DRAW_BUFFER2_ARB 0x8827
#define GL_DRAW_BUFFER3_ARB 0x8828
#define GL_DRAW_BUFFER4_ARB 0x8829
#define GL_DRAW_BUFFER5_ARB 0x882A
#define GL_DRAW_BUFFER6_ARB 0x882B
#define GL_DRAW_BUFFER7_ARB 0x882C
#define GL_DRAW_BUFFER8_ARB 0x882D
#define GL_DRAW_BUFFER9_ARB 0x882E
#define GL_DRAW_BUFFER10_ARB 0x882F
#define GL_DRAW_BUFFER11_ARB 0x8830
#define GL_DRAW_BUFFER12_ARB 0x8831
#define GL_DRAW_BUFFER13_ARB 0x8832
#define GL_DRAW_BUFFER14_ARB 0x8833
#define GL_DRAW_BUFFER15_ARB 0x8834
#endif
#ifndef GL_ARB_depth_clamp
#define GL_ARB_depth_clamp
#define GL_DEPTH_CLAMP 0x864F
#endif
#if defined(WIN32) #if defined(WIN32)
// WGL_ARB_create_context // WGL_ARB_create_context
#ifndef WGL_ARB_create_context #ifndef WGL_ARB_create_context

View file

@ -167,7 +167,7 @@ void GL_Cull( int cullType ) {
qglEnable( GL_CULL_FACE ); qglEnable( GL_CULL_FACE );
cullFront = (cullType == CT_FRONT_SIDED); cullFront = (cullType == CT_FRONT_SIDED);
if ( backEnd.viewParms.isMirror && !backEnd.viewParms.isShadowmap ) if ( backEnd.viewParms.isMirror )
{ {
cullFront = !cullFront; cullFront = !cullFront;
} }
@ -590,127 +590,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
// save original time for entity shader offsets // save original time for entity shader offsets
originalTime = backEnd.refdef.floatTime; originalTime = backEnd.refdef.floatTime;
// clear the z buffer, set the modelview, etc
RB_BeginDrawingView ();
fbo = glState.currentFBO; fbo = glState.currentFBO;
if (r_depthPrepass->integer)
{
qboolean skip = qfalse;
// do a depth fill with just the static vbos
backEnd.depthFill = qtrue;
oldEntityNum = -1;
backEnd.currentEntity = &tr.worldEntity;
oldShader = NULL;
oldFogNum = -1;
oldDepthRange = qfalse;
wasCrosshair = qfalse;
oldDlighted = qfalse;
oldPshadowed = qfalse;
oldSort = -1;
depthRange = qfalse;
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) {
if ( drawSurf->sort == oldSort ) {
// fast path, same as previous sort
if (!skip)
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
continue;
}
oldSort = drawSurf->sort;
R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &pshadowed );
skip = qfalse;
if (entityNum != ENTITYNUM_WORLD)
{
skip = qtrue;
continue;
}
if (ShaderRequiresCPUDeforms(shader))
{
skip = qtrue;
continue;
}
if (shader->sort != SS_OPAQUE)
{
skip = qtrue;
continue;
}
{
int stage;
shaderStage_t *pStage = NULL;
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ )
{
if (shader->stages[stage])
{
pStage = shader->stages[stage];
break;
}
}
if (pStage && (pStage->stateBits & GLS_ATEST_BITS) != 0)
{
skip = qtrue;
continue;
}
}
//
// change the tess parameters if needed
// a "entityMergable" shader is a shader that can have surfaces from seperate
// entities merged into a single batch, like smoke and blood puff sprites
if (shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted || pshadowed != oldPshadowed
|| ( entityNum != oldEntityNum && !shader->entityMergable ) ) {
if (oldShader != NULL) {
RB_EndSurface();
}
RB_BeginSurface( shader, fogNum );
backEnd.pc.c_surfBatches++;
oldShader = shader;
oldFogNum = fogNum;
oldDlighted = dlighted;
oldPshadowed = pshadowed;
}
//
// change the modelview matrix if needed
//
if ( entityNum != oldEntityNum ) {
backEnd.currentEntity = &tr.worldEntity;
backEnd.refdef.floatTime = originalTime;
backEnd.or = backEnd.viewParms.world;
// we have to reset the shaderTime as well otherwise image animations on
// the world (like water) continue with the wrong frame
tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
GL_SetModelviewMatrix( backEnd.or.modelMatrix );
oldEntityNum = entityNum;
}
// add the triangles for this surface
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
}
// draw the contents of the last shader batch
if (oldShader != NULL) {
RB_EndSurface();
}
qglColorMask(!backEnd.colorMask[0], !backEnd.colorMask[1], !backEnd.colorMask[2], !backEnd.colorMask[3]);
}
// draw everything // draw everything
backEnd.depthFill = qfalse;
oldEntityNum = -1; oldEntityNum = -1;
backEnd.currentEntity = &tr.worldEntity; backEnd.currentEntity = &tr.worldEntity;
oldShader = NULL; oldShader = NULL;
@ -731,6 +613,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) { for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) {
if ( drawSurf->sort == oldSort ) { if ( drawSurf->sort == oldSort ) {
if (backEnd.depthFill && shader && shader->sort != SS_OPAQUE)
continue;
// fast path, same as previous sort // fast path, same as previous sort
rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface ); rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
continue; continue;
@ -755,6 +640,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
oldPshadowed = pshadowed; oldPshadowed = pshadowed;
} }
if (backEnd.depthFill && shader && shader->sort != SS_OPAQUE)
continue;
// //
// change the modelview matrix if needed // change the modelview matrix if needed
// //
@ -765,7 +653,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
#ifdef REACTION #ifdef REACTION
// if we were rendering to a FBO and the previous entity was a sunflare // if we were rendering to a FBO and the previous entity was a sunflare
// and the current one isn't, switch back to the main fbo // and the current one isn't, switch back to the main fbo
if (oldEntityNum != -1 && fbo && if (oldEntityNum != -1 && fbo && !backEnd.depthFill &&
RF_SUNFLARE == (backEnd.refdef.entities[oldEntityNum].e.renderfx & RF_SUNFLARE) && RF_SUNFLARE == (backEnd.refdef.entities[oldEntityNum].e.renderfx & RF_SUNFLARE) &&
0 == (backEnd.refdef.entities[entityNum].e.renderfx & RF_SUNFLARE)) 0 == (backEnd.refdef.entities[entityNum].e.renderfx & RF_SUNFLARE))
{ {
@ -795,7 +683,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
#ifdef REACTION #ifdef REACTION
// if the current entity is a sunflare // if the current entity is a sunflare
if(backEnd.currentEntity->e.renderfx & RF_SUNFLARE) { if(backEnd.currentEntity->e.renderfx & RF_SUNFLARE && !backEnd.depthFill) {
// if we're rendering to a fbo // if we're rendering to a fbo
if (fbo) { if (fbo) {
VectorCopy(backEnd.currentEntity->e.origin, backEnd.sunFlarePos); VectorCopy(backEnd.currentEntity->e.origin, backEnd.sunFlarePos);
@ -914,7 +802,7 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
} }
#ifdef REACTION #ifdef REACTION
// HACK: flip Z and render black to god rays buffer // HACK: flip Z and render black to god rays buffer
if (backEnd.frameHasSunFlare) if (backEnd.frameHasSunFlare && !backEnd.depthFill)
{ {
vec4_t black; vec4_t black;
VectorSet4(black, 0, 0, 0, 1); VectorSet4(black, 0, 0, 0, 1);
@ -931,18 +819,6 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
//if ( depthRange ) { //if ( depthRange ) {
qglDepthRange (0, 1); qglDepthRange (0, 1);
//} //}
#if 0
RB_DrawSun();
#endif
// darken down any stencil shadows
RB_ShadowFinish();
// add light flares on lights that aren't obscured
RB_RenderFlares();
if (glRefConfig.framebufferObject)
FBO_Bind(NULL);
} }
@ -1307,7 +1183,44 @@ const void *RB_DrawSurfs( const void *data ) {
backEnd.refdef = cmd->refdef; backEnd.refdef = cmd->refdef;
backEnd.viewParms = cmd->viewParms; backEnd.viewParms = cmd->viewParms;
// clear the z buffer, set the modelview, etc
RB_BeginDrawingView ();
if (backEnd.viewParms.isDepthShadow && glRefConfig.depthClamp)
{
qglEnable(GL_DEPTH_CLAMP);
}
if (r_depthPrepass->integer || backEnd.viewParms.isDepthShadow)
{
backEnd.depthFill = qtrue;
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
RB_RenderDrawSurfList( cmd->drawSurfs, cmd->numDrawSurfs ); RB_RenderDrawSurfList( cmd->drawSurfs, cmd->numDrawSurfs );
qglColorMask(!backEnd.colorMask[0], !backEnd.colorMask[1], !backEnd.colorMask[2], !backEnd.colorMask[3]);
backEnd.depthFill = qfalse;
}
if (backEnd.viewParms.isDepthShadow && glRefConfig.depthClamp)
{
qglDisable(GL_DEPTH_CLAMP);
}
if (!backEnd.viewParms.isDepthShadow)
{
RB_RenderDrawSurfList( cmd->drawSurfs, cmd->numDrawSurfs );
#if 0
RB_DrawSun();
#endif
// darken down any stencil shadows
RB_ShadowFinish();
// add light flares on lights that aren't obscured
RB_RenderFlares();
}
if (glRefConfig.framebufferObject)
FBO_Bind(NULL);
return (const void *)(cmd + 1); return (const void *)(cmd + 1);
} }
@ -1632,6 +1545,17 @@ const void *RB_PostProcess(const void *data)
} }
#endif #endif
if (0)
{
vec4i_t dstBox;
VectorSet4(dstBox, 0, 0, 128, 128);
FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
VectorSet4(dstBox, 128, 0, 128, 128);
FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
VectorSet4(dstBox, 256, 0, 128, 128);
FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0);
}
backEnd.framePostProcessed = qtrue; backEnd.framePostProcessed = qtrue;
return (const void *)(cmd + 1); return (const void *)(cmd + 1);

View file

@ -175,6 +175,9 @@ void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, G
void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples, void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height); GLenum internalformat, GLsizei width, GLsizei height);
// GL_ARB_draw_buffers
void (APIENTRY * qglDrawBuffersARB)(GLsizei n, const GLenum *bufs);
static qboolean GLimp_HaveExtension(const char *ext) static qboolean GLimp_HaveExtension(const char *ext)
{ {
const char *ptr = Q_stristr( glConfig.extensions_string, ext ); const char *ptr = Q_stristr( glConfig.extensions_string, ext );
@ -649,4 +652,31 @@ void GLimp_InitExtraExtensions()
{ {
ri.Printf(PRINT_ALL, result[2], extension); ri.Printf(PRINT_ALL, result[2], extension);
} }
// GL_ARB_draw_buffers
extension = "GL_ARB_draw_buffers";
qglDrawBuffersARB = NULL;
if( GLimp_HaveExtension( extension ) )
{
qglDrawBuffersARB = (void *) SDL_GL_GetProcAddress("glDrawBuffersARB");
ri.Printf(PRINT_ALL, result[1], extension);
}
else
{
ri.Printf(PRINT_ALL, result[2], extension);
}
// GL_ARB_depth_clamp
extension = "GL_ARB_depth_clamp";
glRefConfig.depthClamp = qfalse;
if( GLimp_HaveExtension( extension ) )
{
glRefConfig.depthClamp = qtrue;
ri.Printf(PRINT_ALL, result[1], extension);
}
else
{
ri.Printf(PRINT_ALL, result[2], extension);
}
} }

View file

@ -31,9 +31,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// extra refdef flags start at 0x0008 // extra refdef flags start at 0x0008
#define RDF_NOFOG 0x0008 // don't apply fog #define RDF_NOFOG 0x0008 // don't apply fog
#define RDF_EXTRA 0x0010 // Makro - refdefex_t to follow after refdef_t #define RDF_EXTRA 0x0010 // Makro - refdefex_t to follow after refdef_t
#define RDF_SUNLIGHT 0x0020 // SmileTheory - render sunlight and shadows
typedef struct { typedef struct {
float blurFactor; float blurFactor;
float sunDir[3];
float sunCol[3];
} refdefex_t; } refdefex_t;
#endif #endif

View file

@ -477,6 +477,21 @@ void FBO_Init(void)
R_CheckFBO(tr.pshadowFbos[i]); R_CheckFBO(tr.pshadowFbos[i]);
} }
for ( i = 0; i < 3; i++)
{
tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height);
FBO_Bind(tr.sunShadowFbo[i]);
//FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0, 0);
//FBO_AttachTextureImage(tr.sunShadowImage, 0);
qglDrawBuffer(GL_NONE);
//FBO_CreateBuffer(tr.sunShadowFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
R_AttachFBOTextureDepth(tr.sunShadowDepthImage[i]->texnum);
R_CheckFBO(tr.sunShadowFbo[i]);
}
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
{ {
tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height); tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);

View file

@ -302,135 +302,162 @@ static const char *fallbackLightallShader_fp =
"rm sampler2D u_NormalMap;\r\n#endif\r\n\r\n#if defined(USE_DELUXEMAP)\r\nun" "rm sampler2D u_NormalMap;\r\n#endif\r\n\r\n#if defined(USE_DELUXEMAP)\r\nun"
"iform sampler2D u_DeluxeMap;\r\n#endif\r\n\r\n#if defined(USE_SPECULARMAP)" "iform sampler2D u_DeluxeMap;\r\n#endif\r\n\r\n#if defined(USE_SPECULARMAP)"
"\r\nuniform sampler2D u_SpecularMap;\r\n#endif\r\n\r\n#if defined(USE_SHADO" "\r\nuniform sampler2D u_SpecularMap;\r\n#endif\r\n\r\n#if defined(USE_SHADO"
"WMAP)\r\nuniform samplerCube u_ShadowMap;\r\n#endif\r\n\r\nuniform vec3 " "WMAP)\r\nuniform sampler2D u_ShadowMap;\r\n #if defined(USE_SHADOW_CASCADE"
" u_ViewOrigin;\r\n\r\n#if defined(USE_LIGHT_VECTOR)\r\nuniform vec3 u" ")\r\nuniform sampler2D u_ShadowMap2;\r\nuniform sampler2D u_ShadowMap3;\r\n"
"_DirectedLight;\r\nuniform vec3 u_AmbientLight;\r\nuniform float u" " #endif\r\n#endif\r\n\r\nuniform vec3 u_ViewOrigin;\r\n\r\n#if define"
"_LightRadius;\r\n#endif\r\n\r\n#if defined(USE_LIGHT)\r\nuniform vec2 " "d(USE_LIGHT_VECTOR)\r\nuniform vec3 u_DirectedLight;\r\nuniform vec3 "
"u_MaterialInfo;\r\n#endif\r\n\r\nvarying vec2 var_DiffuseTex;\r\n#if d" " u_AmbientLight;\r\nuniform float u_LightRadius;\r\n#endif\r\n\r\n#i"
"efined(USE_LIGHTMAP)\r\nvarying vec2 var_LightTex;\r\n#endif\r\nvaryin" "f defined(USE_SHADOWMAP)\r\nuniform mat4 u_ShadowMvp;\r\n #if defined"
"g vec4 var_Color;\r\nvarying vec3 var_Position;\r\n\r\nvarying ve" "(USE_SHADOW_CASCADE)\r\nuniform mat4 u_ShadowMvp2;\r\nuniform mat4 "
"c3 var_SampleToView;\r\n\r\nvarying vec3 var_Normal;\r\n#if defin" " u_ShadowMvp3;\r\n #endif\r\n#endif\r\n\r\n#if defined(USE_LIGHT)\r\nunif"
"ed(USE_VERT_TANGENT_SPACE)\r\nvarying vec3 var_Tangent;\r\nvarying vec" "orm vec2 u_MaterialInfo;\r\n#endif\r\n\r\nvarying vec2 var_Diffus"
"3 var_Bitangent;\r\n#endif\r\n\r\n#if defined(USE_LIGHT_VECTOR) && def" "eTex;\r\n#if defined(USE_LIGHTMAP)\r\nvarying vec2 var_LightTex;\r\n#e"
"ined(USE_FAST_LIGHT)\r\nvarying vec3 var_VectLight;\r\n#endif\r\n\r\n#" "ndif\r\nvarying vec4 var_Color;\r\nvarying vec3 var_Position;\r\n"
"if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)\r\nvarying vec3 var_W" "\r\nvarying vec3 var_SampleToView;\r\n\r\nvarying vec3 var_Normal"
"orldLight;\r\n#endif\r\n\r\n#define EPSILON 0.00000001\r\n\r\n#if defined(U" ";\r\n#if defined(USE_VERT_TANGENT_SPACE)\r\nvarying vec3 var_Tangent;"
"SE_PARALLAXMAP)\r\nfloat SampleHeight(sampler2D normalMap, vec2 t)\r\n{\r\n" "\r\nvarying vec3 var_Bitangent;\r\n#endif\r\n\r\n#if defined(USE_LIGHT"
" #if defined(SWIZZLE_NORMALMAP)\r\n\treturn texture2D(normalMap, t).r;\r\n" "_VECTOR) && defined(USE_FAST_LIGHT)\r\nvarying vec3 var_VectLight;\r\n"
" #else\r\n\treturn texture2D(normalMap, t).a;\r\n #endif\r\n}\r\n\r\nfloa" "#endif\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)\r\nvarying "
"t RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)\r\n{\r\n\t" "vec3 var_WorldLight;\r\n#endif\r\n\r\n#define EPSILON 0.00000001\r\n\r"
"const int linearSearchSteps = 16;\r\n\tconst int binarySearchSteps = 6;\r\n" "\n#if defined(USE_PARALLAXMAP)\r\nfloat SampleHeight(sampler2D normalMap, v"
"\r\n\tfloat depthStep = 1.0 / float(linearSearchSteps);\r\n\r\n\t// current" "ec2 t)\r\n{\r\n #if defined(SWIZZLE_NORMALMAP)\r\n\treturn texture2D(norma"
" size of search window\r\n\tfloat size = depthStep;\r\n\r\n\t// current dep" "lMap, t).r;\r\n #else\r\n\treturn texture2D(normalMap, t).a;\r\n #endif\r"
"th position\r\n\tfloat depth = 0.0;\r\n\r\n\t// best match found (starts wi" "\n}\r\n\r\nfloat RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normal"
"th last position 1.0)\r\n\tfloat bestDepth = 1.0;\r\n\r\n\t// search front " "Map)\r\n{\r\n\tconst int linearSearchSteps = 16;\r\n\tconst int binarySearc"
"to back for first point inside object\r\n\tfor(int i = 0; i < linearSearchS" "hSteps = 6;\r\n\r\n\tfloat depthStep = 1.0 / float(linearSearchSteps);\r\n"
"teps - 1; ++i)\r\n\t{\r\n\t\tdepth += size;\r\n\t\t\r\n\t\tfloat t = 1.0 - " "\r\n\t// current size of search window\r\n\tfloat size = depthStep;\r\n\r\n"
"SampleHeight(normalMap, dp + ds * depth);\r\n\t\t\r\n\t\tif(bestDepth > 0.9" "\t// current depth position\r\n\tfloat depth = 0.0;\r\n\r\n\t// best match "
"96)\t\t// if no depth found yet\r\n\t\t\tif(depth >= t)\r\n\t\t\t\tbestDept" "found (starts with last position 1.0)\r\n\tfloat bestDepth = 1.0;\r\n\r\n\t"
"h = depth;\t// store best depth\r\n\t}\r\n\r\n\tdepth = bestDepth;\r\n\t\r" "// search front to back for first point inside object\r\n\tfor(int i = 0; i"
"\n\t// recurse around first point (depth) for closest match\r\n\tfor(int i " " < linearSearchSteps - 1; ++i)\r\n\t{\r\n\t\tdepth += size;\r\n\t\t\r\n\t\t"
"= 0; i < binarySearchSteps; ++i)\r\n\t{\r\n\t\tsize *= 0.5;\r\n\r\n\t\tfloa" "float t = 1.0 - SampleHeight(normalMap, dp + ds * depth);\r\n\t\t\r\n\t\tif"
"t t = 1.0 - SampleHeight(normalMap, dp + ds * depth);\r\n\t\t\r\n\t\tif(dep" "(bestDepth > 0.996)\t\t// if no depth found yet\r\n\t\t\tif(depth >= t)\r\n"
"th >= t)\r\n\t\t{\r\n\t\t\tbestDepth = depth;\r\n\t\t\tdepth -= 2.0 * size;" "\t\t\t\tbestDepth = depth;\t// store best depth\r\n\t}\r\n\r\n\tdepth = bes"
"\r\n\t\t}\r\n\r\n\t\tdepth += size;\r\n\t}\r\n\r\n\treturn bestDepth;\r\n}" "tDepth;\r\n\t\r\n\t// recurse around first point (depth) for closest match"
"\r\n#endif\r\n\r\nfloat CalcDiffuse(vec3 N, vec3 L, vec3 E, float NE, float" "\r\n\tfor(int i = 0; i < binarySearchSteps; ++i)\r\n\t{\r\n\t\tsize *= 0.5;"
" NL, float fzero, float shininess)\r\n{\r\n #if defined(USE_OREN_NAYAR)\r" "\r\n\r\n\t\tfloat t = 1.0 - SampleHeight(normalMap, dp + ds * depth);\r\n\t"
"\n\tfloat roughness = sqrt(2.0 / max(shininess, EPSILON));\r\n\r\n\tfloat g" "\t\r\n\t\tif(depth >= t)\r\n\t\t{\r\n\t\t\tbestDepth = depth;\r\n\t\t\tdept"
"amma = dot(E - N * NE, L - N * NL);\r\n\tfloat r_sq = roughness * roughness" "h -= 2.0 * size;\r\n\t\t}\r\n\r\n\t\tdepth += size;\r\n\t}\r\n\r\n\treturn "
";\r\n\r\n\tfloat A = 1.0 - 0.5 * (r_sq / (r_sq + 0.57));\r\n\tfloat B = 0.4" "bestDepth;\r\n}\r\n#endif\r\n\r\nfloat CalcDiffuse(vec3 N, vec3 L, vec3 E, "
"5 * (r_sq / (r_sq + 0.09));\r\n\r\n\tfloat alpha = max(acos(NE), acos(NL));" "float NE, float NL, float fzero, float shininess)\r\n{\r\n #if defined(USE"
"\r\n\tfloat beta = min(acos(NE), acos(NL));\r\n\r\n\tfloat C = sin(alpha) " "_OREN_NAYAR)\r\n\tfloat roughness = sqrt(2.0 / max(shininess, EPSILON));\r"
"* tan(beta);\r\n\r\n\treturn A + B * clamp(gamma, 0.0, 1.0) * C;\r\n #else" "\n\r\n\tfloat gamma = dot(E - N * NE, L - N * NL);\r\n\tfloat r_sq = roughn"
"\r\n\treturn 1.0 - fzero;\r\n #endif\r\n}\r\n\r\n#if defined(USE_SPECULARM" "ess * roughness;\r\n\r\n\tfloat A = 1.0 - 0.5 * (r_sq / (r_sq + 0.57));\r\n"
"AP)\r\nfloat CalcSpecular(float NH, float NL, float NE, float EH, float fze" "\tfloat B = 0.45 * (r_sq / (r_sq + 0.09));\r\n\r\n\tfloat alpha = max(acos("
"ro, float shininess)\r\n{\r\n #if defined(USE_BLINN) || defined(USE_TRIACE" "NE), acos(NL));\r\n\tfloat beta = min(acos(NE), acos(NL));\r\n\r\n\tfloat "
") || defined(USE_TORRANCE_SPARROW)\r\n\tfloat blinn = pow(NH, shininess);\r" "C = sin(alpha) * tan(beta);\r\n\r\n\treturn A + B * clamp(gamma, 0.0, 1.0) "
"\n #endif\r\n\r\n #if defined(USE_BLINN)\r\n\treturn blinn;\r\n #endif\r" "* C;\r\n #else\r\n\treturn 1.0 - fzero;\r\n #endif\r\n}\r\n\r\n#if define"
"\n\r\n #if defined(USE_COOK_TORRANCE) || defined (USE_TRIACE) || defined (" "d(USE_SPECULARMAP)\r\nfloat CalcSpecular(float NH, float NL, float NE, floa"
"USE_TORRANCE_SPARROW)\r\n\tfloat fresnel = fzero + (1.0 - fzero) * pow(1.0 " "t EH, float fzero, float shininess)\r\n{\r\n #if defined(USE_BLINN) || def"
"- EH, 5);\r\n #endif\r\n\r\n #if defined(USE_COOK_TORRANCE) || defined(US" "ined(USE_TRIACE) || defined(USE_TORRANCE_SPARROW)\r\n\tfloat blinn = pow(NH"
"E_TORRANCE_SPARROW)\r\n\tfloat geo = 2.0 * NH * min(NE, NL);\r\n\tgeo /= ma" ", shininess);\r\n #endif\r\n\r\n #if defined(USE_BLINN)\r\n\treturn blinn"
"x(EH, geo);\r\n #endif \r\n\r\n #if defined(USE_COOK_TORRANCE)\r\n\tfloa" ";\r\n #endif\r\n\r\n #if defined(USE_COOK_TORRANCE) || defined (USE_TRIAC"
"t m = sqrt(2.0 / max(shininess, EPSILON));\r\n\r\n\tfloat m_sq = m * m;\r\n" "E) || defined (USE_TORRANCE_SPARROW)\r\n\tfloat fresnel = fzero + (1.0 - fz"
"\tfloat NH_sq = NH * NH;\r\n\tfloat beckmann = exp((NH_sq - 1.0) / max(m_sq" "ero) * pow(1.0 - EH, 5);\r\n #endif\r\n\r\n #if defined(USE_COOK_TORRANCE"
" * NH_sq, EPSILON)) / max(4.0 * m_sq * NH_sq * NH_sq, EPSILON);\r\n\r\n\tre" ") || defined(USE_TORRANCE_SPARROW)\r\n\tfloat geo = 2.0 * NH * min(NE, NL);"
"turn fresnel * geo * beckmann / max(NE, EPSILON);\r\n #endif\r\n\r\n #if " "\r\n\tgeo /= max(EH, geo);\r\n #endif \r\n\r\n #if defined(USE_COOK_TORR"
"defined(USE_TRIACE)\r\n\tfloat scale = 0.1248582 * shininess + 0.2691817;\r" "ANCE)\r\n\tfloat m = sqrt(2.0 / max(shininess, EPSILON));\r\n\r\n\tfloat m_"
"\n\r\n\treturn fresnel * scale * blinn / max(max(NL, NE), EPSILON);\r\n #e" "sq = m * m;\r\n\tfloat NH_sq = NH * NH;\r\n\tfloat beckmann = exp((NH_sq - "
"ndif\r\n \r\n #if defined(USE_TORRANCE_SPARROW)\r\n\tfloat scale = 0.125 " "1.0) / max(m_sq * NH_sq, EPSILON)) / max(4.0 * m_sq * NH_sq * NH_sq, EPSILO"
"* shininess + 1.0;\r\n\r\n\treturn fresnel * geo * scale * blinn / max(NE, " "N);\r\n\r\n\treturn fresnel * geo * beckmann / max(NE, EPSILON);\r\n #endi"
"EPSILON);\r\n #endif\r\n}\r\n#endif\r\n\r\nvoid main()\r\n{\r\n#if defined" "f\r\n\r\n #if defined(USE_TRIACE)\r\n\tfloat scale = 0.1248582 * shininess"
"(USE_DELUXEMAP)\r\n\tvec3 worldLight = 2.0 * texture2D(u_DeluxeMap, var_Lig" " + 0.2691817;\r\n\r\n\treturn fresnel * scale * blinn / max(max(NL, NE), EP"
"htTex).xyz - vec3(1.0);\r\n\t//worldLight += var_WorldLight * 0.0001;\r\n#e" "SILON);\r\n #endif\r\n \r\n #if defined(USE_TORRANCE_SPARROW)\r\n\tfloat"
"lif defined(USE_LIGHT)\r\n\tvec3 worldLight = var_WorldLight;\r\n#endif\r\n" " scale = 0.125 * shininess + 1.0;\r\n\r\n\treturn fresnel * geo * scale * b"
"\r\n#if defined(USE_LIGHTMAP)\r\n\tvec4 lightSample = texture2D(u_LightMap," "linn / max(NE, EPSILON);\r\n #endif\r\n}\r\n#endif\r\n\r\nfloat PCF(sample"
" var_LightTex).rgba;\r\n #if defined(RGBE_LIGHTMAP)\r\n\tlightSample.rgb *" "r2D shadowmap, vec2 st, float dist)\r\n{\r\n\tfloat mult;\r\n\t\r\n\tmult "
"= exp2(lightSample.a * 255.0 - 128.0);\r\n #endif\r\n\tvec3 directedLight " "= sign(clamp(texture2D(shadowmap, st + vec2(-0.5, -0.5) / 1024.0).r - dist,"
"= lightSample.rgb;\r\n#elif defined(USE_LIGHT_VECTOR)\r\n #if defined(USE_" " 0.0, 1.0));\r\n\tmult += sign(clamp(texture2D(shadowmap, st + vec2( 0.5, -"
"FAST_LIGHT)\r\n\tvec3 directedLight = var_VectLight;\r\n #else\r\n #if " "0.5) / 1024.0).r - dist, 0.0, 1.0));\r\n\tmult += sign(clamp(texture2D(shad"
"defined(USE_INVSQRLIGHT)\r\n\tfloat intensity = 1.0 / dot(worldLight, world" "owmap, st + vec2(-0.5, 0.5) / 1024.0).r - dist, 0.0, 1.0));\r\n\tmult += s"
"Light);\r\n #else\r\n\tfloat intensity = clamp((1.0 - dot(worldLight, wo" "ign(clamp(texture2D(shadowmap, st + vec2( 0.5, 0.5) / 1024.0).r - dist, 0."
"rldLight) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0);\r\n #end" "0, 1.0));\r\n\tmult *= 0.25;\r\n\t\r\n\treturn mult;\r\n}\r\n\r\nvoid main("
"if\r\n #if defined(USE_SHADOWMAP)\r\n \tvec3 dist3 = textureCube(u_Shad" ")\r\n{\r\n#if defined(USE_LIGHT) || defined(USE_NORMALMAP)\r\n\tvec3 surfNo"
"owMap, worldLight).rgb;\r\n\tfloat dist = dot(dist3, vec3(1.0 / (256.0 * 25" "rmal = normalize(var_Normal);\r\n#endif\r\n\r\n#if defined(USE_DELUXEMAP)\r"
"6.0), 1.0 / 256.0, 1.0)) * u_LightRadius;\r\n\r\n\tintensity *= clamp(sign(" "\n\tvec3 worldLight = 2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3"
"dist - length(worldLight)), 0.0, 1.0);\r\n #endif\r\n\tvec3 directedLigh" "(1.0);\r\n\t//worldLight += var_WorldLight * 0.0001;\r\n#elif defined(USE_L"
"t = u_DirectedLight * intensity;\r\n\tvec3 ambientLight = u_AmbientLight;" "IGHT)\r\n\tvec3 worldLight = var_WorldLight;\r\n#endif\r\n\r\n#if defined(U"
"\r\n #endif\r\n#elif defined(USE_LIGHT_VERTEX)\r\n\tvec3 directedLight = v" "SE_LIGHTMAP)\r\n\tvec4 lightSample = texture2D(u_LightMap, var_LightTex).rg"
"ar_Color.rgb;\r\n#endif\r\n\t\r\n#if defined(USE_NORMALMAP) || defined(USE_" "ba;\r\n #if defined(RGBE_LIGHTMAP)\r\n\tlightSample.rgb *= exp2(lightSampl"
"LIGHT) && !defined(USE_FAST_LIGHT)\r\n\tvec3 SampleToView = normalize(var_S" "e.a * 255.0 - 128.0);\r\n #endif\r\n\tvec3 directedLight = lightSample.rgb"
"ampleToView);\r\n#endif\r\n\tvec2 tex = var_DiffuseTex;\r\n\r\n\tfloat ambi" ";\r\n#elif defined(USE_LIGHT_VECTOR)\r\n #if defined(USE_FAST_LIGHT)\r\n\t"
"entDiff = 1.0;\r\n\r\n#if defined(USE_NORMALMAP)\r\n #if defined(USE_VERT_" "vec3 directedLight = var_VectLight;\r\n #else\r\n #if defined(USE_INVSQ"
"TANGENT_SPACE)\r\n vec3 tangent = normalize(var_Tangent);\r\n\tvec3 bi" "RLIGHT)\r\n\tfloat intensity = 1.0 / dot(worldLight, worldLight);\r\n #e"
"tangent = normalize(var_Bitangent);\r\n #else\r\n\tvec3 q0 = dFdx(var_Pos" "lse\r\n\tfloat intensity = clamp((1.0 - dot(worldLight, worldLight) / (u_Li"
"ition.xyz);\r\n\tvec3 q1 = dFdy(var_Position.xyz);\r\n\tvec2 st0 = dFdx(te" "ghtRadius * u_LightRadius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n\r\n\t#if d"
"x);\r\n\tvec2 st1 = dFdy(tex);\r\n\tfloat dir = sign(st1.t * st0.s - st0.t " "efined(USE_SHADOWMAP)\r\n\tvec4 shadowpos = u_ShadowMvp * vec4(var_Position"
"* st1.s);\r\n\r\n\tvec3 tangent = normalize( q0 * st1.t - q1 * st0.t) * d" ", 1.0);\r\n\tfloat outside1 = dot(vec3(1.0, 1.0, 1.0), sign(clamp(abs(shado"
"ir;\r\n\tvec3 bitangent = -normalize( q0 * st1.s - q1 * st0.s) * dir;\r\n " "wpos.xyz) - 1.0, 0.0, 1.0)));\r\n\t\r\n\t #if defined(USE_SHADOW_CASCADE)"
"#endif\r\n\r\n\tmat3 tangentToWorld = mat3(tangent, bitangent, normalize(va" "\r\n\tvec4 shadowpos2 = u_ShadowMvp2 * vec4(var_Position, 1.0);\r\n\tfloat "
"r_Normal.xyz));\r\n\r\n #if defined(USE_PARALLAXMAP)\r\n\tvec3 offsetDir =" "outside2 = dot(vec3(1.0, 1.0, 1.0), sign(clamp(abs(shadowpos2.xyz) - 1.0, 0"
" normalize(SampleToView * tangentToWorld);\r\n #if 0\r\n float height" ".0, 1.0)));\r\n\r\n\tvec4 shadowpos3 = u_ShadowMvp3 * vec4(var_Position, 1."
" = SampleHeight(u_NormalMap, tex);\r\n\tfloat pdist = 0.05 * height - (0.05" "0);\r\n\tfloat outside3 = dot(vec3(1.0, 1.0, 1.0), sign(clamp(abs(shadowpos"
" / 2.0);\r\n #else\r\n\toffsetDir.xy *= -0.05 / offsetDir.z;\r\n\tfloat " "3.xyz) - 1.0, 0.0, 1.0)));\r\n\t\r\n\tif (outside1 < 1.0)\r\n\t{\r\n\t\tsha"
"pdist = RayIntersectDisplaceMap(tex, offsetDir.xy, u_NormalMap);\r\n #en" "dowpos.xyz = shadowpos.xyz * 0.5 + 0.5;\r\n\t\tintensity *= PCF(u_ShadowMap"
"dif\t\r\n\ttex += offsetDir.xy * pdist;\r\n #endif\r\n #if defined(SWIZZL" ", shadowpos.xy, shadowpos.z);\r\n\t}\r\n\telse if (outside2 < 1.0)\r\n\t{\r"
"E_NORMALMAP)\r\n\tvec3 normal = 2.0 * texture2D(u_NormalMap, tex).agb - 1.0" "\n\t\tshadowpos2.xyz = shadowpos2.xyz * 0.5 + 0.5;\r\n\t\tintensity *= PCF("
";\r\n #else\r\n\tvec3 normal = 2.0 * texture2D(u_NormalMap, tex).rgb - 1.0" "u_ShadowMap2, shadowpos2.xy, shadowpos2.z);\r\n\t}\r\n\telse if (outside3 <"
";\r\n #endif\r\n\tnormal.z = sqrt(clamp(1.0 - dot(normal.xy, normal.xy), 0" " 1.0)\r\n\t{\r\n\t\tshadowpos3.xyz = shadowpos3.xyz * 0.5 + 0.5;\r\n\t\tint"
".0, 1.0));\r\n\tvec3 worldNormal = tangentToWorld * normal;\r\n #if define" "ensity *= PCF(u_ShadowMap3, shadowpos3.xy, shadowpos3.z);\r\n\t}\r\n\t #el"
"d(r_normalAmbient)\r\n\tambientDiff = 0.781341 * normal.z + 0.218659;\r\n " "se\r\n\tshadowpos.xyz = shadowpos.xyz * 0.5 + 0.5;\r\n\tintensity *= clamp("
"#endif\r\n#else\r\n\tvec3 worldNormal = var_Normal;\r\n#endif\r\n\r\n\tvec4" "PCF(u_ShadowMap, shadowpos.xy, shadowpos.z) - outside1, 1.0, 0.0);\r\n\t #"
" diffuse = texture2D(u_DiffuseMap, tex);\r\n\r\n#if defined(USE_LIGHT) && d" "endif\r\n\t#endif\r\n\t\r\n\tvec3 directedLight = u_DirectedLight * intensi"
"efined(USE_FAST_LIGHT)\r\n\tdiffuse.rgb *= directedLight;\r\n#elif defined(" "ty;\r\n\tvec3 ambientLight = u_AmbientLight;\r\n #endif\r\n#elif defined("
"USE_LIGHT)\r\n\tworldNormal = normalize(worldNormal);\r\n\tworldLight = nor" "USE_LIGHT_VERTEX)\r\n\tvec3 directedLight = var_Color.rgb;\r\n#endif\r\n\t"
"malize(worldLight);\r\n\r\n #if defined(USE_LIGHTMAP) || defined(USE_LIGHT" "\r\n#if defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_L"
"_VERTEX)\r\n\tdirectedLight /= max(dot(normalize(var_Normal), worldLight), " "IGHT)\r\n\tvec3 SampleToView = normalize(var_SampleToView);\r\n#endif\r\n\t"
"0.004);\r\n\r\n #if defined(r_normalAmbient)\r\n\tvec3 ambientLight = di" "vec2 tex = var_DiffuseTex;\r\n\r\n\tfloat ambientDiff = 1.0;\r\n\r\n#if def"
"rectedLight * r_normalAmbient;\r\n\tdirectedLight -= ambientLight;\r\n #" "ined(USE_NORMALMAP)\r\n #if defined(USE_VERT_TANGENT_SPACE)\r\n vec3 "
"else\r\n\tvec3 ambientLight = vec3(0);\r\n #endif\r\n #endif\r\n\r\n\tf" "tangent = normalize(var_Tangent);\r\n\tvec3 bitangent = normalize(var_Bitan"
"loat NL = clamp(dot(worldNormal, worldLight), 0.0, 1.0);\r\n\tfloat NE =" "gent);\r\n #else\r\n\tvec3 q0 = dFdx(var_Position);\r\n\tvec3 q1 = dFdy("
" clamp(dot(worldNormal, SampleToView), 0.0, 1.0);\r\n\t\r\n\tfloat fzero =" "var_Position);\r\n\tvec2 st0 = dFdx(tex);\r\n\tvec2 st1 = dFdy(tex);\r\n\tf"
" u_MaterialInfo.x;\r\n\tfloat shininess = u_MaterialInfo.y;\r\n #if define" "loat dir = sign(st1.t * st0.s - st0.t * st1.s);\r\n\r\n\tvec3 tangent = n"
"d(USE_SPECULARMAP)\r\n\tvec4 specular = texture2D(u_SpecularMap, tex);\r\n" "ormalize( q0 * st1.t - q1 * st0.t) * dir;\r\n\tvec3 bitangent = -normalize("
"\t//specular.rgb = clamp(specular.rgb - diffuse.rgb, 0.0, 1.0);\r\n\tshinin" " q0 * st1.s - q1 * st0.s) * dir;\r\n #endif\r\n\r\n\tmat3 tangentToWorld ="
"ess *= specular.a;\r\n #endif\r\n\tfloat directedDiff = NL * CalcDiffuse(w" " mat3(tangent, bitangent, surfNormal);\r\n\r\n #if defined(USE_PARALLAXMAP"
"orldNormal, worldLight, SampleToView, NE, NL, fzero, shininess);\r\n\tdiffu" ")\r\n\tvec3 offsetDir = normalize(SampleToView * tangentToWorld);\r\n #i"
"se.rgb *= directedLight * directedDiff + ambientDiff * ambientLight;\r\n " "f 0\r\n float height = SampleHeight(u_NormalMap, tex);\r\n\tfloat pdist "
"\r\n #if defined(USE_SPECULARMAP)\r\n\tvec3 halfAngle = normalize(worldLig" "= 0.05 * height - (0.05 / 2.0);\r\n #else\r\n\toffsetDir.xy *= -0.05 / o"
"ht + SampleToView);\r\n\r\n\tfloat EH = clamp(dot(SampleToView, halfAngle)," "ffsetDir.z;\r\n\tfloat pdist = RayIntersectDisplaceMap(tex, offsetDir.xy, u"
" 0.0, 1.0);\r\n\tfloat NH = clamp(dot(worldNormal, halfAngle), 0.0, 1.0);" "_NormalMap);\r\n #endif\t\r\n\ttex += offsetDir.xy * pdist;\r\n #endif"
"\r\n\r\n\tfloat directedSpec = NL * CalcSpecular(NH, NL, NE, EH, fzero, shi" "\r\n #if defined(SWIZZLE_NORMALMAP)\r\n\tvec3 normal = 2.0 * texture2D(u_N"
"niness);\r\n \r\n #if defined(r_normalAmbient)\r\n\tvec3 ambientHalf = " "ormalMap, tex).agb - 1.0;\r\n #else\r\n\tvec3 normal = 2.0 * texture2D(u_N"
"normalize(var_Normal + SampleToView);\r\n\tfloat ambientSpec = max(dot(ambi" "ormalMap, tex).rgb - 1.0;\r\n #endif\r\n\tnormal.z = sqrt(clamp(1.0 - dot("
"entHalf, worldNormal) + 0.5, 0.0);\r\n\tambientSpec *= ambientSpec * 0.44;" "normal.xy, normal.xy), 0.0, 1.0));\r\n\tvec3 worldNormal = tangentToWorld *"
"\r\n\tambientSpec = pow(ambientSpec, shininess) * fzero;\r\n\tspecular.rgb " " normal;\r\n #if defined(r_normalAmbient)\r\n\tambientDiff = 0.781341 * no"
"*= directedSpec * directedLight + ambientSpec * ambientLight;\r\n #else" "rmal.z + 0.218659;\r\n #endif\r\n#elif defined(USE_LIGHT)\r\n\tvec3 worldN"
"\r\n\tspecular.rgb *= directedSpec * directedLight;\r\n #endif\r\n #end" "ormal = surfNormal;\r\n#endif\r\n\r\n\tvec4 diffuse = texture2D(u_DiffuseMa"
"if\r\n#endif\r\n\r\n\tgl_FragColor = diffuse;\r\n\r\n#if defined(USE_SPECUL" "p, tex);\r\n\r\n#if defined(USE_LIGHT) && defined(USE_FAST_LIGHT)\r\n\tdiff"
"ARMAP) && defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)\r\n\tgl_FragColor." "use.rgb *= directedLight;\r\n#elif defined(USE_LIGHT)\r\n\tworldNormal = no"
"rgb += specular.rgb;\r\n#endif\r\n\r\n#if !defined(USE_LIGHT_VERTEX)\r\n\tg" "rmalize(worldNormal);\r\n\tworldLight = normalize(worldLight);\r\n\r\n #if"
"l_FragColor *= var_Color;\r\n#endif\r\n}\r\n"; " 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";
static const char *fallbackShadowfillShader_vp = static const char *fallbackShadowfillShader_vp =
"attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute" "attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute"
@ -1750,6 +1777,17 @@ void GLSL_InitGPUShaders(void)
if (!(i & LIGHTDEF_USE_NORMALMAP) && (i & LIGHTDEF_USE_PARALLAXMAP)) if (!(i & LIGHTDEF_USE_NORMALMAP) && (i & LIGHTDEF_USE_PARALLAXMAP))
continue; continue;
if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHT_VECTOR))
{
if (i & LIGHTDEF_USE_SHADOWMAP)
continue;
if (i & LIGHTDEF_USE_SHADOW_CASCADE)
continue;
}
if ((i & LIGHTDEF_USE_SHADOW_CASCADE) && !(i & LIGHTDEF_USE_SHADOWMAP))
continue;
attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR | ATTR_NORMAL; attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR | ATTR_NORMAL;
extradefines[0] = '\0'; extradefines[0] = '\0';
@ -1837,6 +1875,12 @@ void GLSL_InitGPUShaders(void)
if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer) if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n"); Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
if ((i & LIGHTDEF_USE_SHADOWMAP))
Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
if ((i & LIGHTDEF_USE_SHADOW_CASCADE))
Q_strcat(extradefines, 1024, "#define USE_SHADOW_CASCADE\n");
if (i & LIGHTDEF_TCGEN_ENVIRONMENT) if (i & LIGHTDEF_TCGEN_ENVIRONMENT)
Q_strcat(extradefines, 1024, "#define TCGEN_ENVIRONMENT\n"); Q_strcat(extradefines, 1024, "#define TCGEN_ENVIRONMENT\n");
@ -1871,6 +1915,8 @@ void GLSL_InitGPUShaders(void)
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_DELUXEMAP, "u_DeluxeMap", GLSL_INT); GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_DELUXEMAP, "u_DeluxeMap", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SPECULARMAP, "u_SpecularMap", GLSL_INT); GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SPECULARMAP, "u_SpecularMap", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMAP, "u_ShadowMap", GLSL_INT); GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMAP, "u_ShadowMap", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMAP2, "u_ShadowMap2", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMAP3, "u_ShadowMap3", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_AMBIENTLIGHT, "u_AmbientLight", GLSL_VEC3); GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_AMBIENTLIGHT, "u_AmbientLight", GLSL_VEC3);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_DIRECTEDLIGHT, "u_DirectedLight", GLSL_VEC3); GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_DIRECTEDLIGHT, "u_DirectedLight", GLSL_VEC3);
@ -1883,6 +1929,10 @@ void GLSL_InitGPUShaders(void)
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_VERTCOLOR, "u_VertColor", GLSL_VEC4); GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_VERTCOLOR, "u_VertColor", GLSL_VEC4);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT); GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT);
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_EndUniforms(&tr.lightallShader[i]); GLSL_EndUniforms(&tr.lightallShader[i]);
qglUseProgramObjectARB(tr.lightallShader[i].program); qglUseProgramObjectARB(tr.lightallShader[i].program);
@ -1892,6 +1942,8 @@ void GLSL_InitGPUShaders(void)
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_DELUXEMAP, TB_DELUXEMAP); GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_DELUXEMAP, TB_DELUXEMAP);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_SPECULARMAP, TB_SPECULARMAP); GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_SPECULARMAP, TB_SPECULARMAP);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMAP, TB_SHADOWMAP);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMAP2, TB_SHADOWMAP2);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_SHADOWMAP3, TB_SHADOWMAP3);
qglUseProgramObjectARB(0); qglUseProgramObjectARB(0);
GLSL_FinishGPUShader(&tr.lightallShader[i]); GLSL_FinishGPUShader(&tr.lightallShader[i]);

View file

@ -2983,6 +2983,12 @@ void R_CreateBuiltinImages( void ) {
{ {
tr.pshadowMaps[x] = R_CreateImage(va("*shadowmap%i", x), NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); tr.pshadowMaps[x] = R_CreateImage(va("*shadowmap%i", x), NULL, PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
} }
//tr.sunShadowImage = R_CreateImage("*sunshadowmap", NULL, SUNSHADOW_MAP_SIZE, SUNSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8);
for ( x = 0; x < 3; x++)
{
tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, SUNSHADOW_MAP_SIZE, SUNSHADOW_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT16_ARB);
}
} }

View file

@ -128,6 +128,7 @@ cvar_t *r_imageUpsample;
cvar_t *r_imageUpsampleMaxSize; cvar_t *r_imageUpsampleMaxSize;
cvar_t *r_imageUpsampleType; cvar_t *r_imageUpsampleType;
cvar_t *r_genNormalMaps; cvar_t *r_genNormalMaps;
cvar_t *r_testSunlight;
cvar_t *r_ignoreGLErrors; cvar_t *r_ignoreGLErrors;
cvar_t *r_logFile; cvar_t *r_logFile;
@ -1151,6 +1152,7 @@ void R_Register( void )
r_imageUpsampleMaxSize = ri.Cvar_Get( "r_imageUpsampleMaxSize", "1024", CVAR_ARCHIVE | CVAR_LATCH ); r_imageUpsampleMaxSize = ri.Cvar_Get( "r_imageUpsampleMaxSize", "1024", CVAR_ARCHIVE | CVAR_LATCH );
r_imageUpsampleType = ri.Cvar_Get( "r_imageUpsampleType", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_imageUpsampleType = ri.Cvar_Get( "r_imageUpsampleType", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_genNormalMaps = ri.Cvar_Get( "r_genNormalMaps", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_genNormalMaps = ri.Cvar_Get( "r_genNormalMaps", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_testSunlight = ri.Cvar_Get( "r_testSunlight", "0", CVAR_CHEAT );
// //
// temporary latched variables that can only change over a restart // temporary latched variables that can only change over a restart

View file

@ -67,6 +67,7 @@ typedef unsigned int glIndex_t;
#define MAX_CALC_PSHADOWS 64 #define MAX_CALC_PSHADOWS 64
#define MAX_DRAWN_PSHADOWS 16 // do not increase past 32, because bit flags are used on surfaces #define MAX_DRAWN_PSHADOWS 16 // do not increase past 32, because bit flags are used on surfaces
#define PSHADOW_MAP_SIZE 512 #define PSHADOW_MAP_SIZE 512
#define SUNSHADOW_MAP_SIZE 1024
typedef struct dlight_s { typedef struct dlight_s {
vec3_t origin; vec3_t origin;
@ -409,10 +410,12 @@ enum
TB_DIFFUSEMAP = 0, TB_DIFFUSEMAP = 0,
TB_LIGHTMAP = 1, TB_LIGHTMAP = 1,
TB_LEVELSMAP = 1, TB_LEVELSMAP = 1,
TB_NORMALMAP, TB_SHADOWMAP = 1,
TB_DELUXEMAP, TB_NORMALMAP = 2,
TB_SPECULARMAP, TB_DELUXEMAP = 3,
TB_SHADOWMAP, TB_SHADOWMAP2 = 3,
TB_SPECULARMAP = 4,
TB_SHADOWMAP3 = 5,
NUM_TEXTURE_BUNDLES = 6 NUM_TEXTURE_BUNDLES = 6
}; };
@ -737,10 +740,12 @@ enum
LIGHTDEF_USE_SPECULARMAP = 0x0008, LIGHTDEF_USE_SPECULARMAP = 0x0008,
LIGHTDEF_USE_DELUXEMAP = 0x0010, LIGHTDEF_USE_DELUXEMAP = 0x0010,
LIGHTDEF_USE_PARALLAXMAP = 0x0020, LIGHTDEF_USE_PARALLAXMAP = 0x0020,
LIGHTDEF_TCGEN_ENVIRONMENT = 0x0040, LIGHTDEF_USE_SHADOWMAP = 0x0040,
LIGHTDEF_ENTITY = 0x0080, LIGHTDEF_USE_SHADOW_CASCADE= 0x0080,
LIGHTDEF_ALL = 0x00FF, LIGHTDEF_TCGEN_ENVIRONMENT = 0x0100,
LIGHTDEF_COUNT = 0x0100 LIGHTDEF_ENTITY = 0x0200,
LIGHTDEF_ALL = 0x03FF,
LIGHTDEF_COUNT = 0x0400
}; };
enum enum
@ -836,6 +841,8 @@ enum
GENERIC_UNIFORM_DELUXEMAP, GENERIC_UNIFORM_DELUXEMAP,
GENERIC_UNIFORM_SPECULARMAP, GENERIC_UNIFORM_SPECULARMAP,
GENERIC_UNIFORM_SHADOWMAP, GENERIC_UNIFORM_SHADOWMAP,
GENERIC_UNIFORM_SHADOWMAP2,
GENERIC_UNIFORM_SHADOWMAP3,
GENERIC_UNIFORM_DIFFUSETEXMATRIX, GENERIC_UNIFORM_DIFFUSETEXMATRIX,
//GENERIC_UNIFORM_NORMALTEXMATRIX, //GENERIC_UNIFORM_NORMALTEXMATRIX,
//GENERIC_UNIFORM_SPECULARTEXMATRIX, //GENERIC_UNIFORM_SPECULARTEXMATRIX,
@ -864,6 +871,9 @@ enum
GENERIC_UNIFORM_TIME, GENERIC_UNIFORM_TIME,
GENERIC_UNIFORM_VERTEXLERP, GENERIC_UNIFORM_VERTEXLERP,
GENERIC_UNIFORM_MATERIALINFO, GENERIC_UNIFORM_MATERIALINFO,
GENERIC_UNIFORM_SHADOWMVP,
GENERIC_UNIFORM_SHADOWMVP2,
GENERIC_UNIFORM_SHADOWMVP3,
GENERIC_UNIFORM_COUNT GENERIC_UNIFORM_COUNT
}; };
@ -913,6 +923,10 @@ typedef struct {
unsigned int dlightMask; unsigned int dlightMask;
int num_pshadows; int num_pshadows;
struct pshadow_s *pshadows; struct pshadow_s *pshadows;
float sunShadowMvp[3][16];
float sunDir[4];
float sunCol[4];
} trRefdef_t; } trRefdef_t;
@ -962,6 +976,7 @@ typedef struct {
cplane_t frustum[5]; cplane_t frustum[5];
vec3_t visBounds[2]; vec3_t visBounds[2];
float zFar; float zFar;
float zNear;
stereoFrame_t stereoFrame; stereoFrame_t stereoFrame;
} viewParms_t; } viewParms_t;
@ -1636,6 +1651,8 @@ typedef struct {
qboolean texture_srgb; qboolean texture_srgb;
qboolean framebuffer_srgb; qboolean framebuffer_srgb;
qboolean depthClamp;
} glRefConfig_t; } glRefConfig_t;
@ -1753,6 +1770,7 @@ typedef struct {
image_t *calcLevelsImage; image_t *calcLevelsImage;
image_t *targetLevelsImage; image_t *targetLevelsImage;
image_t *fixedLevelsImage; image_t *fixedLevelsImage;
image_t *sunShadowDepthImage[3];
image_t *textureDepthImage; image_t *textureDepthImage;
@ -1766,6 +1784,7 @@ typedef struct {
FBO_t *quarterFbo[2]; FBO_t *quarterFbo[2];
FBO_t *calcLevelsFbo; FBO_t *calcLevelsFbo;
FBO_t *targetLevelsFbo; FBO_t *targetLevelsFbo;
FBO_t *sunShadowFbo[3];
shader_t *defaultShader; shader_t *defaultShader;
shader_t *shadowShader; shader_t *shadowShader;
@ -2021,6 +2040,7 @@ extern cvar_t *r_imageUpsample;
extern cvar_t *r_imageUpsampleMaxSize; extern cvar_t *r_imageUpsampleMaxSize;
extern cvar_t *r_imageUpsampleType; extern cvar_t *r_imageUpsampleType;
extern cvar_t *r_genNormalMaps; extern cvar_t *r_genNormalMaps;
extern cvar_t *r_testSunlight;
extern cvar_t *r_greyscale; extern cvar_t *r_greyscale;
@ -2050,6 +2070,7 @@ void R_SwapBuffers( int );
void R_RenderView( viewParms_t *parms ); void R_RenderView( viewParms_t *parms );
void R_RenderDlightCubemaps(const refdef_t *fd); void R_RenderDlightCubemaps(const refdef_t *fd);
void R_RenderPshadowMaps(const refdef_t *fd); void R_RenderPshadowMaps(const refdef_t *fd);
void R_RenderSunShadowMaps(const refdef_t *fd, int level);
void R_AddMD3Surfaces( trRefEntity_t *e ); void R_AddMD3Surfaces( trRefEntity_t *e );
void R_AddNullModelSurfaces( trRefEntity_t *e ); void R_AddNullModelSurfaces( trRefEntity_t *e );

View file

@ -1812,6 +1812,8 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
int pshadowed; int pshadowed;
int i; int i;
//ri.Printf(PRINT_ALL, "firstDrawSurf %d numDrawSurfs %d\n", (int)(drawSurfs - tr.refdef.drawSurfs), numDrawSurfs);
// it is possible for some views to not have any surfaces // it is possible for some views to not have any surfaces
if ( numDrawSurfs < 1 ) { if ( numDrawSurfs < 1 ) {
// we still need to add it for hyperspace cases // we still need to add it for hyperspace cases
@ -1829,7 +1831,7 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) {
// sort the drawsurfs by sort type, then orientation, then shader // sort the drawsurfs by sort type, then orientation, then shader
R_RadixSort( drawSurfs, numDrawSurfs ); R_RadixSort( drawSurfs, numDrawSurfs );
if (tr.viewParms.isShadowmap) if (tr.viewParms.isShadowmap || tr.viewParms.isDepthShadow)
{ {
R_AddDrawSurfCmd( drawSurfs, numDrawSurfs ); R_AddDrawSurfCmd( drawSurfs, numDrawSurfs );
return; return;
@ -1881,7 +1883,7 @@ static void R_AddEntitySurface (int entityNum)
// we don't want the hacked weapon position showing in // we don't want the hacked weapon position showing in
// mirrors, because the true body position will already be drawn // mirrors, because the true body position will already be drawn
// //
if ( (ent->e.renderfx & RF_FIRST_PERSON) && (tr.viewParms.isPortal || tr.viewParms.isShadowmap)) { if ( (ent->e.renderfx & RF_FIRST_PERSON) && (tr.viewParms.isPortal || tr.viewParms.isShadowmap || tr.viewParms.isDepthShadow)) {
return; return;
} }
@ -2512,3 +2514,325 @@ void R_RenderPshadowMaps(const refdef_t *fd)
} }
} }
} }
void R_RenderSunShadowMaps(const refdef_t *fd, int level)
{
viewParms_t shadowParms;
vec4_t lightDir, lightCol;
vec3_t up;
vec3_t lightViewAxis[3];
vec3_t lightOrigin;
float xmin, xmax, ymin, ymax, znear, zfar, viewznear, viewzfar;
if (r_testSunlight->integer)
{
int scale = 32768;
float angle = (fd->time % scale) / (float)scale * M_PI;
lightDir[0] = cos(angle);
lightDir[1] = sin(35.0f * M_PI / 180.0f);
lightDir[2] = sin(angle) * cos(35.0f * M_PI / 180.0f);
lightDir[3] = 0.0f;
if (1) //((fd->time % (scale * 2)) < scale)
{
lightCol[0] =
lightCol[1] =
lightCol[2] = CLAMP(sin(angle) * 2.0f, 0.0f, 1.0f) * 2.0f;
lightCol[3] = 1.0f;
}
else
{
lightCol[0] =
lightCol[1] =
lightCol[2] = CLAMP(sin(angle) * 2.0f * 0.1f, 0.0f, 0.1f);
lightCol[3] = 1.0f;
}
VectorCopy4(lightDir, tr.refdef.sunDir);
VectorCopy4(lightCol, tr.refdef.sunCol);
}
else
{
VectorCopy4(tr.refdef.sunDir, lightDir);
}
//viewRadius = 128;
//lightRadius = 4096;
switch(level)
{
case 0:
default:
viewznear = r_znear->value;
viewzfar = 256;
break;
case 1:
viewznear = 256;
viewzfar = 768;
break;
case 2:
viewznear = 768;
viewzfar = 2048;
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);
if ( abs(DotProduct(up, lightViewAxis[0])) > 0.9f )
{
VectorCopy(fd->viewaxis[2], up);
//VectorSet(up, 0, 0, 1);
}
CrossProduct(lightViewAxis[0], up, lightViewAxis[1]);
VectorNormalize(lightViewAxis[1]);
CrossProduct(lightViewAxis[0], lightViewAxis[1], lightViewAxis[2]);
{
matrix_t lightViewMatrix;
vec3_t lightviewBounds[2];
vec4_t point, base, lightViewPoint;
float lx, ly;
base[3] = 1;
point[3] = 1;
lightViewPoint[3] = 1;
lightViewMatrix[0] = lightViewAxis[0][0];
lightViewMatrix[1] = lightViewAxis[1][0];
lightViewMatrix[2] = lightViewAxis[2][0];
lightViewMatrix[3] = 0;
lightViewMatrix[4] = lightViewAxis[0][1];
lightViewMatrix[5] = lightViewAxis[1][1];
lightViewMatrix[6] = lightViewAxis[2][1];
lightViewMatrix[7] = 0;
lightViewMatrix[8] = lightViewAxis[0][2];
lightViewMatrix[9] = lightViewAxis[1][2];
lightViewMatrix[10] = lightViewAxis[2][2];
lightViewMatrix[11] = 0;
lightViewMatrix[12] = -DotProduct(lightOrigin, lightViewAxis[0]);
lightViewMatrix[13] = -DotProduct(lightOrigin, lightViewAxis[1]);
lightViewMatrix[14] = -DotProduct(lightOrigin, lightViewAxis[2]);
lightViewMatrix[15] = 1;
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);
VectorMA(fd->vieworg, viewznear, fd->viewaxis[0], base);
VectorMA(base, lx, fd->viewaxis[1], point);
VectorMA(point, ly, fd->viewaxis[2], point);
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
VectorMA(base, -lx, fd->viewaxis[1], point);
VectorMA(point, ly, fd->viewaxis[2], point);
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
VectorMA(base, lx, fd->viewaxis[1], point);
VectorMA(point, -ly, fd->viewaxis[2], point);
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
VectorMA(base, -lx, fd->viewaxis[1], point);
VectorMA(point, -ly, fd->viewaxis[2], point);
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
// add view far plane
lx = viewzfar * tan(fd->fov_x * M_PI / 360.0f);
ly = viewzfar * tan(fd->fov_y * M_PI / 360.0f);
VectorMA(fd->vieworg, viewzfar, fd->viewaxis[0], base);
VectorMA(base, lx, fd->viewaxis[1], point);
VectorMA(point, ly, fd->viewaxis[2], point);
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
VectorMA(base, -lx, fd->viewaxis[1], point);
VectorMA(point, ly, fd->viewaxis[2], point);
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
VectorMA(base, lx, fd->viewaxis[1], point);
VectorMA(point, -ly, fd->viewaxis[2], point);
Matrix16Transform(lightViewMatrix, point, lightViewPoint);
AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]);
VectorMA(base, -lx, fd->viewaxis[1], point);
VectorMA(point, -ly, fd->viewaxis[2], point);
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)
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, "fovx %f fovy %f xmin %f xmax %f ymin %f ymax %f\n", fd->fov_x, fd->fov_y, xmin, xmax, ymin, ymax);
}
{
int firstDrawSurf;
int j;
Com_Memset( &shadowParms, 0, sizeof( shadowParms ) );
if (glRefConfig.framebufferObject)
{
shadowParms.viewportX = 0;
shadowParms.viewportY = 0;
}
else
{
shadowParms.viewportX = tr.refdef.x;
shadowParms.viewportY = glConfig.vidHeight - ( tr.refdef.y + SUNSHADOW_MAP_SIZE );
}
shadowParms.viewportWidth = SUNSHADOW_MAP_SIZE;
shadowParms.viewportHeight = SUNSHADOW_MAP_SIZE;
shadowParms.isPortal = qfalse;
shadowParms.isMirror = qfalse;
shadowParms.fovX = 90;
shadowParms.fovY = 90;
if (glRefConfig.framebufferObject)
shadowParms.targetFbo = tr.sunShadowFbo[level];
shadowParms.isShadowmap = qfalse;
shadowParms.isDepthShadow = qtrue;
shadowParms.zFar = zfar;
VectorCopy(lightOrigin, shadowParms.or.origin);
VectorCopy(lightViewAxis[0], shadowParms.or.axis[0]);
VectorCopy(lightViewAxis[1], shadowParms.or.axis[1]);
VectorCopy(lightViewAxis[2], shadowParms.or.axis[2]);
VectorCopy(lightOrigin, shadowParms.pvsOrigin );
{
tr.viewCount++;
tr.viewParms = shadowParms;
tr.viewParms.frameSceneNum = tr.frameSceneNum;
tr.viewParms.frameCount = tr.frameCount;
firstDrawSurf = tr.refdef.numDrawSurfs;
tr.viewCount++;
// 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_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 );
}
}
}

View file

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

View file

@ -365,15 +365,29 @@ void RE_RenderScene( const refdef_t *fd ) {
} }
} }
#ifdef REACTION //#ifdef REACTION
// Makro - copy exta info if present // Makro - copy exta info if present
if (fd->rdflags & RDF_EXTRA) { if (fd->rdflags & RDF_EXTRA) {
const refdefex_t* extra = (const refdefex_t*) (fd+1); const refdefex_t* extra = (const refdefex_t*) (fd+1);
#ifdef REACTION
tr.refdef.blurFactor = extra->blurFactor; tr.refdef.blurFactor = extra->blurFactor;
} else {
tr.refdef.blurFactor = 0.f;
}
#endif #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);
}
//#endif
// derived info // derived info
@ -422,6 +436,14 @@ void RE_RenderScene( const refdef_t *fd ) {
R_RenderPshadowMaps(fd); R_RenderPshadowMaps(fd);
} }
// playing with even more shadows
if(!( fd->rdflags & RDF_NOWORLDMODEL ) && ((fd->rdflags & RDF_SUNLIGHT) || r_testSunlight->integer))
{
R_RenderSunShadowMaps(fd, 0);
R_RenderSunShadowMaps(fd, 1);
R_RenderSunShadowMaps(fd, 2);
}
// setup view parms for the initial view // setup view parms for the initial view
// //
// set up viewport // set up viewport

View file

@ -850,6 +850,199 @@ static void ForwardDlight( void ) {
} }
static void ForwardSunlight( void ) {
int l;
//vec3_t origin;
//float scale;
int stage;
int stageGlState[2];
qboolean alphaOverride = qfalse;
int deformGen;
vec5_t deformParams;
vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0};
float eyeT = 0;
shaderCommands_t *input = &tess;
ComputeDeformValues(&deformGen, deformParams);
ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT);
// deal with vertex alpha blended surfaces
if (input->xstages[0] && input->xstages[1] &&
(input->xstages[1]->alphaGen == AGEN_VERTEX || input->xstages[1]->alphaGen == AGEN_ONE_MINUS_VERTEX))
{
stageGlState[0] = input->xstages[0]->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS);
if (stageGlState[0] == 0 || stageGlState[0] == (GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO))
{
stageGlState[1] = input->xstages[1]->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS);
if (stageGlState[1] == (GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA))
{
alphaOverride = qtrue;
stageGlState[0] = GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
stageGlState[1] = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
}
else if (stageGlState[1] == (GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_SRC_ALPHA))
{
alphaOverride = qtrue;
stageGlState[0] = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
stageGlState[1] = GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
}
}
}
if (!alphaOverride)
{
stageGlState[0] =
stageGlState[1] = GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
}
for ( stage = 0; stage < 2 /*MAX_SHADER_STAGES */; stage++ )
{
shaderStage_t *pStage = input->xstages[stage];
shaderProgram_t *sp;
vec4_t vector;
matrix_t matrix;
if ( !pStage )
{
break;
}
//VectorCopy( dl->transformed, origin );
//if (pStage->glslShaderGroup == tr.lightallShader)
{
int index = pStage->glslShaderIndex;
index &= ~(LIGHTDEF_LIGHTTYPE_MASK | LIGHTDEF_USE_DELUXEMAP);
index |= LIGHTDEF_USE_LIGHT_VECTOR | LIGHTDEF_USE_SHADOWMAP | LIGHTDEF_USE_SHADOW_CASCADE;
sp = &tr.lightallShader[index];
}
backEnd.pc.c_lightallDraws++;
GLSL_BindProgram(sp);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, deformGen);
if (deformGen != DGEN_NONE)
{
GLSL_SetUniformFloat5(sp, GENERIC_UNIFORM_DEFORMPARAMS, deformParams);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime);
}
if ( input->fogNum ) {
vec4_t fogColorMask;
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_FOGEYET, eyeT);
ComputeFogColorMask(pStage, fogColorMask);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGCOLORMASK, fogColorMask);
}
{
vec4_t baseColor;
vec4_t vertColor;
ComputeShaderColors(pStage, baseColor, vertColor);
if (alphaOverride)
{
if (input->xstages[1]->alphaGen == AGEN_VERTEX)
{
baseColor[3] = 0.0f;
vertColor[3] = 1.0f;
}
else if (input->xstages[1]->alphaGen == AGEN_ONE_MINUS_VERTEX)
{
baseColor[3] = 1.0f;
vertColor[3] = -1.0f;
}
}
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_BASECOLOR, baseColor);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_VERTCOLOR, vertColor);
}
if (pStage->alphaGen == AGEN_PORTAL)
{
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_PORTALRANGE, tess.shader->portalRange);
}
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, pStage->rgbGen);
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, pStage->alphaGen);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, backEnd.refdef.sunCol);
VectorSet(vector, 0, 0, 0);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, vector);
//VectorSet4(vector, 0, 0, 1, 0);
//VectorSet4(vector, 0.57735f, 0.57735f, 0.57735f, 0);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_LIGHTRADIUS, 9999999999);
GLSL_SetUniformVec2(sp, GENERIC_UNIFORM_MATERIALINFO, pStage->materialInfo);
GL_State( stageGlState[stage] );
Matrix16Identity(matrix);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, matrix);
if (pStage->bundle[TB_DIFFUSEMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP);
if (pStage->bundle[TB_NORMALMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP);
if (pStage->bundle[TB_SPECULARMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP);
{
GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP);
GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2);
GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]);
}
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_DIFFUSETEXMATRIX, matrix);
//
// draw
//
if (input->multiDrawPrimitives)
{
R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes);
}
else
{
R_DrawElementsVBO(input->numIndexes, input->firstIndex);
}
backEnd.pc.c_totalIndexes += tess.numIndexes;
backEnd.pc.c_dlightIndexes += tess.numIndexes;
}
}
static void ProjectPshadowVBOGLSL( void ) { static void ProjectPshadowVBOGLSL( void ) {
int l; int l;
vec3_t origin; vec3_t origin;
@ -1183,7 +1376,10 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
// //
if ( backEnd.depthFill ) if ( backEnd.depthFill )
{ {
if (!(pStage->stateBits & GLS_ATEST_BITS))
GL_BindToTMU( tr.whiteImage, 0 ); GL_BindToTMU( tr.whiteImage, 0 );
else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 )
R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP );
} }
else if ( pStage->glslShaderGroup ) else if ( pStage->glslShaderGroup )
{ {
@ -1275,6 +1471,9 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
{ {
break; break;
} }
if (backEnd.depthFill)
break;
} }
} }
@ -1389,6 +1588,16 @@ void RB_StageIteratorGeneric( void )
// //
// set face culling appropriately // set face culling appropriately
// //
if (backEnd.viewParms.isDepthShadow)
{
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 ); GL_Cull( input->shader->cullType );
// set polygon offset if necessary // set polygon offset if necessary
@ -1403,16 +1612,13 @@ void RB_StageIteratorGeneric( void )
// //
GLSL_VertexAttribsState(vertexAttribs); GLSL_VertexAttribsState(vertexAttribs);
//
// render depth if in depthfill mode
//
if (backEnd.depthFill)
{
RB_IterateStagesGeneric( input );
//
// render shadowmap if in shadowmap mode
//
if (backEnd.viewParms.isShadowmap)
{
if ( input->shader->sort == SS_OPAQUE )
{
RB_RenderShadowmap( input );
}
// //
// reset polygon offset // reset polygon offset
// //
@ -1425,12 +1631,14 @@ void RB_StageIteratorGeneric( void )
} }
// //
// render depth if in depthfill mode // render shadowmap if in shadowmap mode
// //
if (backEnd.depthFill) if (backEnd.viewParms.isShadowmap)
{ {
RB_IterateStagesGeneric( input ); if ( input->shader->sort == SS_OPAQUE )
{
RB_RenderShadowmap( input );
}
// //
// reset polygon offset // reset polygon offset
// //
@ -1473,6 +1681,11 @@ void RB_StageIteratorGeneric( void )
} }
} }
if (((backEnd.refdef.rdflags & RDF_SUNLIGHT) || r_testSunlight->integer) && tess.shader->sort <= SS_OPAQUE
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) {
ForwardSunlight();
}
// //
// now do fog // now do fog
// //

View file

@ -54,7 +54,7 @@ static qboolean R_CullSurface( msurface_t *surf ) {
} }
// shadowmaps draw back surfaces // shadowmaps draw back surfaces
if ( tr.viewParms.isShadowmap ) if ( tr.viewParms.isShadowmap || tr.viewParms.isDepthShadow)
{ {
if (ct == CT_FRONT_SIDED) if (ct == CT_FRONT_SIDED)
{ {
@ -66,6 +66,19 @@ static qboolean R_CullSurface( msurface_t *surf ) {
} }
} }
// FIXME: actually cull properly for depth shadows
if (tr.viewParms.isDepthShadow) {
d = DotProduct(tr.viewParms.or.axis[0], surf->cullinfo.plane.normal);
if ( ct == CT_FRONT_SIDED ) {
if (d > 0)
return qtrue;
} else {
if (d < 0)
return qtrue;
}
return qfalse;
}
d = DotProduct (tr.or.viewOrigin, surf->cullinfo.plane.normal); d = DotProduct (tr.or.viewOrigin, surf->cullinfo.plane.normal);
// don't cull exactly on the plane, because there are levels of rounding // don't cull exactly on the plane, because there are levels of rounding
@ -389,7 +402,8 @@ static void R_RecursiveWorldNode( mnode_t *node, int planeBits, int dlightBits,
unsigned int newPShadows[2]; unsigned int newPShadows[2];
// if the node wasn't marked as potentially visible, exit // if the node wasn't marked as potentially visible, exit
if (node->visCounts[tr.visIndex] != tr.visCounts[tr.visIndex]) { // pvs is skipped for depth shadows
if (!tr.viewParms.isDepthShadow && node->visCounts[tr.visIndex] != tr.visCounts[tr.visIndex]) {
return; return;
} }
@ -772,6 +786,7 @@ void R_AddWorldSurfaces (void) {
tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT; tr.shiftedEntityNum = tr.currentEntityNum << QSORT_ENTITYNUM_SHIFT;
// determine which leaves are in the PVS / areamask // determine which leaves are in the PVS / areamask
if (!tr.viewParms.isDepthShadow)
R_MarkLeaves (); R_MarkLeaves ();
// clear out the visible min/max // clear out the visible min/max
@ -786,7 +801,11 @@ void R_AddWorldSurfaces (void) {
tr.refdef.num_pshadows = 32 ; tr.refdef.num_pshadows = 32 ;
} }
if ( !tr.viewParms.isShadowmap ) if ( tr.viewParms.isDepthShadow )
{
R_RecursiveWorldNode( tr.world->nodes, 31, 0, 0);
}
else if ( !tr.viewParms.isShadowmap )
{ {
R_RecursiveWorldNode( tr.world->nodes, 15, ( 1 << tr.refdef.num_dlights ) - 1, ( 1 << tr.refdef.num_pshadows ) - 1 ); R_RecursiveWorldNode( tr.world->nodes, 15, ( 1 << tr.refdef.num_dlights ) - 1, ( 1 << tr.refdef.num_pshadows ) - 1 );
} }