From ab4f586e7277c4b4b46d7d60543016470e1c92a4 Mon Sep 17 00:00:00 2001 From: James Canete Date: Mon, 16 Apr 2012 09:35:17 +0000 Subject: [PATCH] Speed up tone mapping Add fast light shader path when r_normalMapping and r_specularMapping are 0 Revise FBO blitting code (Still needs more work) --- reaction/Reaction-ChangeLog | 3 + reaction/code/renderergl2/tr_backend.c | 68 +--- reaction/code/renderergl2/tr_fbo.c | 178 ++++++--- reaction/code/renderergl2/tr_glsl.c | 425 +++++++++++---------- reaction/code/renderergl2/tr_image.c | 5 +- reaction/code/renderergl2/tr_local.h | 2 + reaction/code/renderergl2/tr_postprocess.c | 148 +++---- 7 files changed, 418 insertions(+), 411 deletions(-) diff --git a/reaction/Reaction-ChangeLog b/reaction/Reaction-ChangeLog index 7f0bba16..e82d6ea6 100644 --- a/reaction/Reaction-ChangeLog +++ b/reaction/Reaction-ChangeLog @@ -1,3 +1,6 @@ +- Speed up tone mapping +- Add fast light shader path when r_normalMapping and r_specularMapping are 0 +- Revise FBO blitting code (Still needs more work) - Detect GLSL version - Use GL_EXT_draw_range_elements - Reserve FBOs before shaders, as recommended in nvidia docs diff --git a/reaction/code/renderergl2/tr_backend.c b/reaction/code/renderergl2/tr_backend.c index a162ea3b..7e1da669 100644 --- a/reaction/code/renderergl2/tr_backend.c +++ b/reaction/code/renderergl2/tr_backend.c @@ -1353,20 +1353,7 @@ const void *RB_SwapBuffers( const void *data ) { if (glRefConfig.framebufferObject) { // copy final image to screen - vec2_t texScale; - vec4i_t srcBox, dstBox; - vec4_t white; - FBO_t *srcFbo, *dstFbo; - - texScale[0] = - texScale[1] = 1.0f; - - white[0] = - white[1] = - white[2] = - white[3] = 1.0f; - - VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); + vec4_t color; if (backEnd.framePostProcessed) { @@ -1375,49 +1362,34 @@ const void *RB_SwapBuffers( const void *data ) { else if (!glRefConfig.framebuffer_srgb) { // Copy render to screenscratch, possibly resolving MSAA - srcFbo = tr.renderFbo; - dstFbo = tr.screenScratchFbo; - - FBO_FastBlit(srcFbo, NULL, dstFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); + FBO_FastBlit(tr.renderFbo, NULL, tr.screenScratchFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { - srcFbo = tr.renderFbo; + FBO_t *srcFbo = tr.renderFbo; if (tr.msaaResolveFbo) { // Resolve the MSAA before copying - dstFbo = tr.msaaResolveFbo; - - FBO_FastBlit(srcFbo, NULL, dstFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); + FBO_FastBlit(srcFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); srcFbo = tr.msaaResolveFbo; } // need to copy from resolve to screenscratch to fix gamma - dstFbo = tr.screenScratchFbo; - - VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height); - VectorSet4(dstBox, 0, 0, dstFbo->width, dstFbo->height); - - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, white, 0); + FBO_Blit(srcFbo, NULL, NULL, tr.screenScratchFbo, NULL, NULL, NULL, 0); } - - srcFbo = tr.screenScratchFbo; - VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height); - VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); - - white[0] = - white[1] = - white[2] = pow(2, tr.overbrightBits); //exp2(tr.overbrightBits); - white[3] = 1.0f; + color[0] = + color[1] = + color[2] = pow(2, tr.overbrightBits); //exp2(tr.overbrightBits); + color[3] = 1.0f; // turn off colormask when copying final image if (backEnd.colorMask[0] || backEnd.colorMask[1] || backEnd.colorMask[2] || backEnd.colorMask[3]) qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - FBO_Blit(srcFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, white, 0); + FBO_Blit(tr.screenScratchFbo, NULL, NULL, NULL, NULL, NULL, color, 0); if (backEnd.colorMask[0] || backEnd.colorMask[1] || backEnd.colorMask[2] || backEnd.colorMask[3]) qglColorMask(!backEnd.colorMask[0], !backEnd.colorMask[1], !backEnd.colorMask[2], !backEnd.colorMask[3]); @@ -1476,13 +1448,9 @@ RB_PostProcess const void *RB_PostProcess(const void *data) { const postProcessCommand_t *cmd = data; - FBO_t *hdrFbo; - vec2_t texScale; + FBO_t *srcFbo; qboolean autoExposure; - texScale[0] = - texScale[1] = 1.0f; - if (!glRefConfig.framebufferObject) { // do nothing @@ -1491,37 +1459,33 @@ const void *RB_PostProcess(const void *data) return (const void *)(cmd + 1); } - hdrFbo = tr.renderFbo; + srcFbo = tr.renderFbo; if (tr.msaaResolveFbo) { // Resolve the MSAA before anything else FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); - hdrFbo = tr.msaaResolveFbo; + srcFbo = tr.msaaResolveFbo; } if (r_postProcess->integer && r_hdr->integer && (r_toneMap->integer == 2 || (r_toneMap->integer == 1 && tr.autoExposure))) { autoExposure = (r_autoExposure->integer == 1 && tr.autoExposure) || (r_autoExposure->integer == 2); - RB_ToneMap(hdrFbo, autoExposure); + RB_ToneMap(srcFbo, autoExposure); } else if (!glRefConfig.framebuffer_srgb && r_cameraExposure->value == 0.0f) { - FBO_FastBlit(hdrFbo, NULL, tr.screenScratchFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); + FBO_FastBlit(srcFbo, NULL, tr.screenScratchFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { - vec4i_t srcBox, dstBox; vec4_t color; - VectorSet4(srcBox, 0, 0, hdrFbo->width, hdrFbo->height); - VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); - color[0] = color[1] = color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); color[3] = 1.0f; - FBO_Blit(hdrFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0); + FBO_Blit(srcFbo, NULL, NULL, tr.screenScratchFbo, NULL, NULL, color, 0); } #ifdef REACTION diff --git a/reaction/code/renderergl2/tr_fbo.c b/reaction/code/renderergl2/tr_fbo.c index 004cc336..5cbca501 100644 --- a/reaction/code/renderergl2/tr_fbo.c +++ b/reaction/code/renderergl2/tr_fbo.c @@ -498,6 +498,16 @@ void FBO_Init(void) R_CheckFBO(tr.calcLevelsFbo); } + { + tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height); + FBO_Bind(tr.targetLevelsFbo); + + //FBO_CreateBuffer(tr.targetLevelsFbo, hdrFormat, 0, 0); + FBO_AttachTextureImage(tr.targetLevelsImage, 0); + + R_CheckFBO(tr.targetLevelsFbo); + } + { //tr.screenScratchFbo = FBO_Create("_screenscratch", width, height); tr.screenScratchFbo = FBO_Create("_screenscratch", tr.screenScratchImage->width, tr.screenScratchImage->height); @@ -599,40 +609,123 @@ void R_FBOList_f(void) // FIXME extern void RB_SetGL2D (void); -void FBO_BlitFromTexture(struct image_s *src, vec4i_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4i_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend) +void FBO_BlitFromTexture(struct image_s *src, vec4i_t inSrcBox, vec2_t inSrcTexScale, FBO_t *dst, vec4i_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend) { - vec4_t quadVerts[4]; - vec2_t texCoords[4]; - vec2_t invTexRes; + vec4i_t dstBox, srcBox; + vec2_t srcTexScale; + vec4_t color; + vec4_t quadVerts[4]; + vec2_t texCoords[4]; + vec2_t invTexRes; - FBO_Bind(dst); - - RB_SetGL2D(); + if (!src) + return; - GL_SelectTexture(TB_COLORMAP); + if (inSrcBox) + { + VectorSet4(srcBox, inSrcBox[0], inSrcBox[1], inSrcBox[0] + inSrcBox[2], inSrcBox[1] + inSrcBox[3]); + } + else + { + VectorSet4(srcBox, 0, 0, src->width, src->height); + } - GL_Bind(src); + // framebuffers are 0 bottom, Y up. + if (inDstBox) + { + if (dst) + { + dstBox[0] = inDstBox[0]; + dstBox[1] = dst->height - inDstBox[1] - inDstBox[3]; + dstBox[2] = inDstBox[0] + inDstBox[2]; + dstBox[3] = dst->height - inDstBox[1]; + } + else + { + dstBox[0] = inDstBox[0]; + dstBox[1] = glConfig.vidHeight - inDstBox[1] - inDstBox[3]; + dstBox[2] = inDstBox[0] + inDstBox[2]; + dstBox[3] = glConfig.vidHeight - inDstBox[1]; + } + } + else if (dst) + { + VectorSet4(dstBox, 0, dst->height, dst->width, 0); + } + else + { + VectorSet4(dstBox, 0, glConfig.vidHeight, glConfig.vidWidth, 0); + } - VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0, 1); - VectorSet4(quadVerts[1], dstBox[0] + dstBox[2], dstBox[1], 0, 1); - VectorSet4(quadVerts[2], dstBox[0] + dstBox[2], dstBox[1] + dstBox[3], 0, 1); - VectorSet4(quadVerts[3], dstBox[0], dstBox[1] + dstBox[3], 0, 1); + if (inSrcTexScale) + { + VectorCopy2(inSrcTexScale, srcTexScale); + } + else + { + srcTexScale[0] = srcTexScale[1] = 1.0f; + } - texCoords[0][0] = (srcBox[0] ) / (float)src->width; texCoords[0][1] = 1.0f - (srcBox[1] ) / (float)src->height; - texCoords[1][0] = (srcBox[0] + srcBox[2]) / (float)src->width; texCoords[1][1] = 1.0f - (srcBox[1] ) / (float)src->height; - texCoords[2][0] = (srcBox[0] + srcBox[2]) / (float)src->width; texCoords[2][1] = 1.0f - (srcBox[1] + srcBox[3] ) / (float)src->height; - texCoords[3][0] = (srcBox[0] ) / (float)src->width; texCoords[3][1] = 1.0f - (srcBox[1] + srcBox[3] ) / (float)src->height; + if (inColor) + { + VectorCopy4(inColor, color); + } + else + { + color[0] = color[1] = color[2] = color[3] = 1.0f; + } - invTexRes[0] = 1.0f / src->width * srcTexScale[0]; - invTexRes[1] = 1.0f / src->height * srcTexScale[1]; + if (!shaderProgram) + { + shaderProgram = &tr.textureColorShader; + } - GL_State( blend | GLS_DEPTHTEST_DISABLE ); + FBO_Bind(dst); - RB_InstantQuad2(quadVerts, texCoords, color, shaderProgram, invTexRes); + RB_SetGL2D(); + + GL_SelectTexture(TB_COLORMAP); + + GL_Bind(src); + + VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0, 1); + VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0, 1); + VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0, 1); + VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0, 1); + + texCoords[0][0] = srcBox[0] / (float)src->width; texCoords[0][1] = 1.0f - srcBox[1] / (float)src->height; + texCoords[1][0] = srcBox[2] / (float)src->width; texCoords[1][1] = 1.0f - srcBox[1] / (float)src->height; + texCoords[2][0] = srcBox[2] / (float)src->width; texCoords[2][1] = 1.0f - srcBox[3] / (float)src->height; + texCoords[3][0] = srcBox[0] / (float)src->width; texCoords[3][1] = 1.0f - srcBox[3] / (float)src->height; + + invTexRes[0] = 1.0f / src->width * srcTexScale[0]; + invTexRes[1] = 1.0f / src->height * srcTexScale[1]; + + GL_State( blend | GLS_DEPTHTEST_DISABLE ); + + RB_InstantQuad2(quadVerts, texCoords, color, shaderProgram, invTexRes); } -void FBO_Blit(FBO_t *src, vec4i_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4i_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend) +void FBO_Blit(FBO_t *src, vec4i_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, vec4i_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend) { + vec4i_t srcBox; + + if (!src) + return; + + // framebuffers are 0 bottom, Y up. + if (inSrcBox) + { + srcBox[0] = inSrcBox[0]; + srcBox[1] = src->height - inSrcBox[1] - inSrcBox[3]; + srcBox[2] = inSrcBox[2]; + srcBox[3] = inSrcBox[3]; + } + else + { + VectorSet4(srcBox, 0, src->height, src->width, -src->height); + } + FBO_BlitFromTexture(src->colorImage[0], srcBox, srcTexScale, dst, dstBox, shaderProgram, color, blend); } @@ -643,46 +736,7 @@ void FBO_FastBlit(FBO_t *src, vec4i_t srcBox, FBO_t *dst, vec4i_t dstBox, int bu if (!glRefConfig.framebufferBlit) { - vec2_t texScale; - vec4_t white; - - texScale[0] = - texScale[1] = 1.0f; - - white[0] = - white[1] = - white[2] = - white[3] = 1.0f; - - if (!src || !src->colorImage[0]) - return; - - if (srcBox) - { - VectorSet4(srcBoxFinal, srcBox[0], srcBox[1], srcBox[2], srcBox[3]); - } - else - { - VectorSet4(srcBoxFinal, 0, 0, src->width, src->height); - } - - if (dstBox) - { - VectorSet4(dstBoxFinal, dstBox[0], dstBox[1], dstBox[2], dstBox[3]); - } - else - { - if (dst) - { - VectorSet4(dstBoxFinal, 0, 0, dst->width, dst->height); - } - else - { - VectorSet4(dstBoxFinal, 0, 0, glConfig.vidWidth, glConfig.vidHeight); - } - } - - FBO_Blit(src, srcBoxFinal, texScale, dst, dstBoxFinal, &tr.textureColorShader, white, 0); + FBO_Blit(src, srcBox, NULL, dst, dstBox, NULL, NULL, 0); return; } diff --git a/reaction/code/renderergl2/tr_glsl.c b/reaction/code/renderergl2/tr_glsl.c index 249cf48d..82a27fb5 100644 --- a/reaction/code/renderergl2/tr_glsl.c +++ b/reaction/code/renderergl2/tr_glsl.c @@ -230,58 +230,70 @@ static const char *fallbackLightallShader_vp = ";\r\n#endif\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nattribute vec4 attr" "_Position2;\r\nattribute vec3 attr_Normal2;\r\n #if defined(USE_NORMALMAP)" "\r\nattribute vec3 attr_Tangent2;\r\nattribute vec3 attr_Bitangent2;\r\n #" -"endif\r\n#endif\r\n\r\nattribute vec3 attr_LightDirection;\r\n\r\nuniform m" -"at4 u_DiffuseTexMatrix;\r\nuniform vec3 u_ViewOrigin;\r\nuniform mat4 " -" u_ModelViewProjectionMatrix;\r\nuniform vec4 u_BaseColor;\r\nuniform vec" -"4 u_VertColor;\r\n\r\n#if defined(USE_MODELMATRIX)\r\nuniform mat4 u_Mo" -"delMatrix;\r\n#endif\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nuniform fl" -"oat u_VertexLerp;\r\n#endif\r\n\r\n#if defined(USE_LIGHT_VECTOR)\r\nunifor" -"m vec3 u_DirectedLight;\r\nuniform vec3 u_AmbientLight;\r\nuniform vec4" -" u_LightOrigin;\r\nuniform float u_LightRadius;\r\n#endif\r\n\r\nvarying" -" vec2 var_DiffuseTex;\r\n\r\n#if defined(USE_LIGHTMAP)\r\nvarying vec2 " -"var_LightTex;\r\n#endif\r\n\r\nvarying vec4 var_Color;\r\nvarying vec3 " -"var_Position;\r\nvarying vec3 var_Normal;\r\nvarying vec3 var_Tangent;" -"\r\nvarying vec3 var_Bitangent;\r\nvarying vec3 var_WorldLight;\r\nvary" -"ing vec3 var_VectLight;\r\n\r\n\r\nvec2 DoTexMatrix(vec2 st, vec3 positio" -"n, mat4 texMatrix)\r\n{\r\n\tvec2 st2 = (texMatrix * vec4(st, 1, 0)).st;\r" -"\n\r\n\tvec3 offsetPos = position.xyz / 1024.0;\r\n\toffsetPos.x += offsetP" -"os.z;\r\n\r\n\tvec2 texOffset = sin((offsetPos.xy + vec2(texMatrix[3][1])) " -"* 2.0 * M_PI);\r\n\t\r\n\treturn st2 + texOffset * texMatrix[3][0];\r\n}\r" -"\n\r\nvoid main()\r\n{\r\n#if defined(USE_VERTEX_ANIMATION)\r\n\tvec4 posit" -"ion = mix(attr_Position, attr_Position2, u_VertexLerp);\r\n\tvec3 normal " -" = normalize(mix(attr_Normal, attr_Normal2, u_VertexLerp));\r\n #if" -" defined(USE_NORMALMAP)\r\n\tvec3 tangent = normalize(mix(attr_Tangent, " -" attr_Tangent2, u_VertexLerp));\r\n\tvec3 bitangent = normalize(mix(attr_" -"Bitangent, attr_Bitangent2, u_VertexLerp));\r\n #endif\r\n#else\r\n\tvec4 " -"position = attr_Position;\r\n\tvec3 normal = attr_Normal;\r\n #if defi" -"ned(USE_NORMALMAP)\r\n\tvec3 tangent = attr_Tangent;\r\n\tvec3 bitangent " -"= attr_Bitangent;\r\n #endif\r\n#endif\r\n\r\n\tgl_Position = u_ModelViewP" -"rojectionMatrix * position;\r\n\r\n#if defined(TCGEN_ENVIRONMENT)\r\n\tvec2" -" tex;\r\n\tvec3 viewer = normalize(u_ViewOrigin - position.xyz);\r\n\tvec3 " -"reflected = normal * 2.0 * dot(normal, viewer) - viewer;\r\n\r\n\ttex = ref" -"lected.yz * vec2(0.5, -0.5) + 0.5;\r\n#else\r\n\tvec2 tex = attr_TexCoord0." -"st;\r\n#endif\r\n\r\n\tvar_DiffuseTex = DoTexMatrix(tex, position.xyz, u_Di" -"ffuseTexMatrix);\r\n\r\n#if defined(USE_LIGHTMAP)\r\n\tvar_LightTex = attr_" -"TexCoord1.st;\r\n#endif\r\n\r\n\tvar_Color = u_VertColor * attr_Color + u_B" -"aseColor;\r\n\t\r\n\tvec3 lightDirection = attr_LightDirection;\r\n\t\r\n#i" -"f defined(USE_MODELMATRIX)\r\n\tposition = u_ModelMatrix * position;\r\n\t" -"normal = (u_ModelMatrix * vec4(normal, 0.0)).xyz;\r\n\r\n #if defined (" -"USE_NORMALMAP)\r\n\ttangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;\r" -"\n\tbitangent = (u_ModelMatrix * vec4(bitangent, 0.0)).xyz;\r\n #endif\r\n" -"\r\n #if defined(USE_LIGHTMAP)\r\n\tlightDirection = (u_ModelMatrix * vec4" -"(lightDirection, 0.0)).xyz;\r\n #endif\r\n#endif\r\n \r\n\tvar_Position =" -" position.xyz;\r\n\tvar_Normal = normal;\r\n\r\n#if defined (USE_NORMALMAP)" -"\r\n\tvar_Tangent = tangent;\r\n\tvar_Bitangent = bitangent;\r\n#endif\r\n" -"\r\n#if defined(USE_LIGHT_VECTOR)\r\n\tvec3 worldLight = u_LightOrigin.xyz " -"- (var_Position * u_LightOrigin.w);\r\n#else\r\n\tvec3 worldLight = lightDi" -"rection;\r\n#endif\r\n\r\n\tworldLight += normal * 0.0001;\r\n\r\n\tvar_Wor" -"ldLight = worldLight;\r\n\r\n#if !defined(USE_NORMALMAP) && !defined(USE_SP" -"ECULARMAP) && defined(USE_LIGHT_VECTOR)\r\n #if defined(USE_INVSQRLIGHT)\r" -"\n\tfloat intensity = 1.0 / dot(worldLight, worldLight);\r\n #else\r\n\tfl" -"oat intensity = clamp((1.0 - dot(worldLight, worldLight) / (u_LightRadius *" -" u_LightRadius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n\tfloat NL = clamp(dot(n" -"ormal, normalize(worldLight)), 0.0, 1.0);\r\n\r\n\tvar_VectLight = u_Direct" -"edLight * intensity * NL + u_AmbientLight;\r\n#endif\r\n}\r\n"; +"endif\r\n#endif\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)" +"\r\nattribute vec3 attr_LightDirection;\r\n#endif\r\n\r\n#if defined(TCGEN_" +"ENVIRONMENT) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(US" +"E_FAST_LIGHT)\r\nuniform vec3 u_ViewOrigin;\r\n#endif\r\n\r\nuniform mat4" +" u_DiffuseTexMatrix;\r\nuniform mat4 u_ModelViewProjectionMatrix;\r\nun" +"iform vec4 u_BaseColor;\r\nuniform vec4 u_VertColor;\r\n\r\n#if defined" +"(USE_MODELMATRIX)\r\nuniform mat4 u_ModelMatrix;\r\n#endif\r\n\r\n#if def" +"ined(USE_VERTEX_ANIMATION)\r\nuniform float u_VertexLerp;\r\n#endif\r\n\r" +"\n#if defined(USE_LIGHT_VECTOR)\r\nuniform vec4 u_LightOrigin;\r\n #if d" +"efined(USE_FAST_LIGHT)\r\nuniform vec3 u_DirectedLight;\r\nuniform vec3 " +" u_AmbientLight;\r\nuniform float u_LightRadius;\r\n #endif\r\n#endif\r\n" +"\r\nvarying vec2 var_DiffuseTex;\r\n\r\n#if defined(USE_LIGHTMAP)\r\nvary" +"ing vec2 var_LightTex;\r\n#endif\r\n\r\n#if defined(USE_NORMALMAP) || def" +"ined(USE_LIGHT) && !defined(USE_FAST_LIGHT)\r\nvarying vec3 var_SampleToV" +"iew;\r\n#endif\r\n\r\nvarying vec4 var_Color;\r\n//varying vec3 var_Pos" +"ition;\r\nvarying vec3 var_Normal;\r\n#if defined(USE_NORMALMAP)\r\nvaryi" +"ng vec3 var_Tangent;\r\nvarying vec3 var_Bitangent;\r\n#endif\r\n\r\n#i" +"f defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)\r\nvarying vec3 va" +"r_VectLight;\r\n#endif\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_DELUXE" +"MAP)\r\nvarying vec3 var_WorldLight;\r\n#endif\r\n\r\n\r\nvec2 DoTexMatri" +"x(vec2 st, vec3 position, mat4 texMatrix)\r\n{\r\n\tvec2 st2 = (texMatrix *" +" vec4(st, 1, 0)).st;\r\n\r\n\tvec3 offsetPos = position.xyz / 1024.0;\r\n\t" +"offsetPos.x += offsetPos.z;\r\n\r\n\tvec2 texOffset = sin((offsetPos.xy + v" +"ec2(texMatrix[3][1])) * 2.0 * M_PI);\r\n\t\r\n\treturn st2 + texOffset * te" +"xMatrix[3][0];\r\n}\r\n\r\nvoid main()\r\n{\r\n#if defined(USE_VERTEX_ANIMA" +"TION)\r\n\tvec4 position = mix(attr_Position, attr_Position2, u_VertexLerp" +");\r\n\tvec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_V" +"ertexLerp));\r\n #if defined(USE_NORMALMAP)\r\n\tvec3 tangent = normaliz" +"e(mix(attr_Tangent, attr_Tangent2, u_VertexLerp));\r\n\tvec3 bitangent " +"= normalize(mix(attr_Bitangent, attr_Bitangent2, u_VertexLerp));\r\n #endi" +"f\r\n#else\r\n\tvec4 position = attr_Position;\r\n\tvec3 normal = attr_" +"Normal;\r\n #if defined(USE_NORMALMAP)\r\n\tvec3 tangent = attr_Tangent;" +"\r\n\tvec3 bitangent = attr_Bitangent;\r\n #endif\r\n#endif\r\n\r\n\tgl_Po" +"sition = u_ModelViewProjectionMatrix * position;\r\n\r\n#if (defined(USE_LI" +"GHTMAP) || defined(USE_LIGHT_VERTEX)) && !defined(USE_DELUXEMAP)\r\n\tvec3 " +"worldLight = attr_LightDirection;\r\n#endif\r\n\t\r\n#if defined(USE_MODELM" +"ATRIX)\r\n\tposition = u_ModelMatrix * position;\r\n\tnormal = (u_Model" +"Matrix * vec4(normal, 0.0)).xyz;\r\n\r\n #if defined (USE_NORMALMAP)\r\n\t" +"tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;\r\n\tbitangent = (u_M" +"odelMatrix * vec4(bitangent, 0.0)).xyz;\r\n #endif\r\n\r\n #if defined(US" +"E_LIGHTMAP) && !defined(USE_DELUXEMAP)\r\n\tworldLight = (u_ModelMatrix * v" +"ec4(worldLight, 0.0)).xyz;\r\n #endif\r\n#endif\r\n\r\n#if defined(TCGEN_E" +"NVIRONMENT) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE" +"_FAST_LIGHT)\r\n\tvec3 SampleToView = u_ViewOrigin - position.xyz;\r\n#endi" +"f\r\n\r\n#if defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_F" +"AST_LIGHT)\r\n\tvar_SampleToView = SampleToView;\r\n#endif\r\n\r\n#if defin" +"ed(TCGEN_ENVIRONMENT)\r\n\tvec3 viewer = normalize(SampleToView);\r\n\tvec3" +" reflected = normal * 2.0 * dot(normal, viewer) - viewer;\r\n\r\n\tvec2 tex" +" = reflected.yz * vec2(0.5, -0.5) + 0.5;\r\n#else\r\n\tvec2 tex = attr_TexC" +"oord0.st;\r\n#endif\r\n\r\n\tvar_DiffuseTex = DoTexMatrix(tex, position.xyz" +", u_DiffuseTexMatrix);\r\n\r\n#if defined(USE_LIGHTMAP)\r\n\tvar_LightTex =" +" attr_TexCoord1.st;\r\n#endif\r\n\r\n\tvar_Color = u_VertColor * attr_Color" +" + u_BaseColor;\r\n \r\n\tvar_Normal = normal;\r\n\r\n#if defined (USE_NOR" +"MALMAP)\r\n\tvar_Tangent = tangent;\r\n\tvar_Bitangent = bitangent;\r\n#end" +"if\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)\r\n #if define" +"d(USE_LIGHT_VECTOR)\r\n\tvec3 worldLight = u_LightOrigin.xyz - (position.xy" +"z * u_LightOrigin.w);\r\n #endif\r\n\r\n\tworldLight += normal * 0.0001;\r" +"\n\tvar_WorldLight = worldLight;\r\n#endif\r\n\r\n#if defined(USE_LIGHT_VEC" +"TOR) && defined(USE_FAST_LIGHT)\r\n #if defined(USE_INVSQRLIGHT)\r\n\tfloa" +"t intensity = 1.0 / dot(worldLight, worldLight);\r\n #else\r\n\tfloat inte" +"nsity = clamp((1.0 - dot(worldLight, worldLight) / (u_LightRadius * u_Light" +"Radius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n\tfloat NL = clamp(dot(normal, n" +"ormalize(worldLight)), 0.0, 1.0);\r\n\r\n\tvar_VectLight = u_DirectedLight " +"* intensity * NL + u_AmbientLight;\r\n#endif\r\n}\r\n"; static const char *fallbackLightallShader_fp = "uniform sampler2D u_DiffuseMap;\r\n\r\n#if defined(USE_LIGHTMAP)\r\nuniform" @@ -291,127 +303,128 @@ static const char *fallbackLightallShader_fp = "\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 " " u_ViewOrigin;\r\n\r\n#if defined(USE_LIGHT_VECTOR)\r\nuniform vec3 u" -"_DirectedLight;\r\nuniform vec3 u_AmbientLight;\r\nuniform vec4 u" -"_LightOrigin;\r\nuniform float u_LightRadius;\r\n#endif\r\n\r\n#if defi" -"ned(USE_SPECULARMAP)\r\nuniform float u_SpecularReflectance;\r\n#endif" -"\r\n\r\nuniform float u_DiffuseRoughness;\r\n\r\nvarying vec2 var_" -"DiffuseTex;\r\n#if defined(USE_LIGHTMAP)\r\nvarying vec2 var_LightTex;" -"\r\n#endif\r\nvarying vec4 var_Color;\r\n\r\nvarying vec3 var_Pos" -"ition;\r\n\r\nvarying vec3 var_Normal;\r\n#if defined(USE_NORMALMAP)\r" -"\nvarying vec3 var_Tangent;\r\nvarying vec3 var_Bitangent;\r\n#el" -"if defined(USE_LIGHT_VECTOR)\r\nvarying vec3 var_VectLight;\r\n#endif" -"\r\n\r\nvarying vec3 var_WorldLight;\r\n\r\n#define EPSILON 0.00000001" -"\r\n\r\n#if defined(USE_PARALLAXMAP)\r\nfloat SampleHeight(sampler2D normal" -"Map, vec2 t)\r\n{\r\n #if defined(SWIZZLE_NORMALMAP)\r\n\treturn texture2D" -"(normalMap, t).r;\r\n #else\r\n\treturn texture2D(normalMap, t).a;\r\n #e" -"ndif\r\n}\r\n\r\nfloat RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D " -"normalMap)\r\n{\r\n\tconst int linearSearchSteps = 16;\r\n\tconst int binar" -"ySearchSteps = 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\tfloat t = 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 = 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\tdepth -= 2" -".0 * size;\r\n\t\t}\r\n\r\n\t\tdepth += size;\r\n\t}\r\n\r\n\treturn bestDe" -"pth;\r\n}\r\n#endif\r\n\r\nfloat CalcDiffuse(vec3 N, vec3 L, vec3 E, float " -"NE, float NL, float fzero, float roughness)\r\n{\r\n #if defined(USE_OREN_" -"NAYAR)\r\n\tfloat gamma = dot(E - N * NE, L - N * NL);\r\n\tfloat r_sq = ro" -"ughness * 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(a" -"cos(NE), acos(NL));\r\n\tfloat beta = min(acos(NE), acos(NL));\r\n\r\n\tfl" -"oat 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 de" -"fined(USE_SPECULARMAP)\r\nfloat CalcSpecular(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_TORRANCE_SPARROW)\r\n\tfloat blinn = po" -"w(NH, shininess);\r\n #endif\r\n\r\n #if defined(USE_BLINN)\r\n\treturn b" -"linn;\r\n #endif\r\n\r\n #if defined(USE_COOK_TORRANCE) || defined (USE_T" -"RIACE) || 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_TORR" -"ANCE) || 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_" -"TORRANCE)\r\n\tfloat m = sqrt(2.0 / shininess);\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.2691" -"817;\r\n\r\n\treturn fresnel * scale * blinn / max(max(NL, NE), EPSILON);\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 * blinn / ma" -"x(NE, EPSILON);\r\n #endif\r\n}\r\n#endif\r\n\r\nvoid main()\r\n{\r\n#if d" -"efined(USE_DELUXEMAP)\r\n\tvec3 worldLight = 2.0 * texture2D(u_DeluxeMap, v" -"ar_LightTex).xyz - vec3(1.0);\r\n\tworldLight += var_WorldLight * 0.0001;\r" -"\n#elif defined(USE_LIGHT) && (defined(USE_NORMALMAP) || defined(USE_SPECUL" -"ARMAP))\r\n\tvec3 worldLight = var_WorldLight;\r\n#endif\r\n\r\n#if defined" -"(USE_LIGHTMAP)\r\n\tvec4 lightSample = texture2D(u_LightMap, var_LightTex)." -"rgba;\r\n #if defined(RGBE_LIGHTMAP)\r\n\tlightSample.rgb *= exp2(lightSam" -"ple.a * 255.0 - 128.0);\r\n #endif\r\n\tvec3 directedLight = lightSample.r" -"gb;\r\n#elif defined(USE_LIGHT_VECTOR)\r\n #if !defined(USE_NORMALMAP) && " -"!defined(USE_SPECULARMAP)\r\n\tvec3 directedLight = var_VectLight;\r\n #el" -"se\r\n #if defined(USE_INVSQRLIGHT)\r\n\tfloat intensity = 1.0 / dot(wor" -"ldLight, worldLight);\r\n #else\r\n\tfloat intensity = clamp((1.0 - dot(" -"worldLight, worldLight) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0" -");\r\n #endif\r\n #if defined(USE_SHADOWMAP)\r\n \tvec3 dist3 = text" -"ureCube(u_ShadowMap, worldLight).rgb;\r\n\tfloat dist = dot(dist3, vec3(1.0" -" / (256.0 * 256.0), 1.0 / 256.0, 1.0)) * u_LightRadius;\r\n\r\n\tintensity " -"*= clamp(sign(dist - length(worldLight)), 0.0, 1.0);\r\n #endif\r\n\tvec" -"3 directedLight = u_DirectedLight * intensity;\r\n\tvec3 ambientLight = u_" -"AmbientLight;\r\n #endif\r\n#elif defined(USE_LIGHT_VERTEX)\r\n\tvec3 dire" -"ctedLight = var_Color.rgb;\r\n#endif\r\n\t\r\n#if defined(USE_NORMALMAP) ||" -" defined(USE_SPECULARMAP)\r\n\tvec3 SampleToView = normalize(u_ViewOrigin -" -" var_Position);\r\n#endif\r\n\tvec2 tex = var_DiffuseTex;\r\n\r\n\tfloat am" -"bientDiff = 1.0;\r\n\r\n#if defined(USE_NORMALMAP)\r\n\tmat3 tangentToWorld" -" = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz);\r\n\r\n #if d" -"efined(USE_PARALLAXMAP)\r\n\tvec3 offsetDir = normalize(SampleToView * tang" -"entToWorld);\r\n #if 0\r\n float height = SampleHeight(u_NormalMap, t" -"ex);\r\n\tfloat pdist = 0.05 * height - (0.05 / 2.0);\r\n #else\r\n\toff" -"setDir.xy *= 0.02 / offsetDir.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_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\tnormal.z = s" -"qrt(clamp(1.0 - dot(normal.xy, normal.xy), 0.0, 1.0));\r\n\tvec3 worldNorma" -"l = tangentToWorld * normal;\r\n #if defined(r_normalAmbient)\r\n\tambient" -"Diff = 0.781341 * normal.z + 0.218659;\r\n #endif\r\n#else\r\n\tvec3 world" -"Normal = var_Normal;\r\n#endif\r\n\r\n\tvec4 diffuse = texture2D(u_DiffuseM" -"ap, tex);\r\n\r\n#if defined(USE_LIGHT) && !defined(USE_NORMALMAP) && !defi" -"ned(USE_SPECULARMAP)\r\n\tdiffuse.rgb *= directedLight;\r\n#elif defined(US" -"E_LIGHT)\r\n\tworldNormal = normalize(worldNormal);\r\n\tworldLight = norma" -"lize(worldLight);\r\n\r\n #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_V" -"ERTEX)\r\n\tdirectedLight /= max(dot(normalize(var_Normal), worldLight), 0." -"004);\r\n\r\n #if defined(r_normalAmbient)\r\n\tvec3 ambientLight = dire" -"ctedLight * r_normalAmbient;\r\n\tdirectedLight -= ambientLight;\r\n #el" -"se\r\n\tvec3 ambientLight = vec3(0);\r\n #endif\r\n #endif\r\n\r\n\tflo" -"at NL = clamp(dot(worldNormal, worldLight), 0.0, 1.0);\r\n\tfloat NE = c" -"lamp(dot(worldNormal, SampleToView), 0.0, 1.0);\r\n #if defined(USE_SPECU" -"LARMAP)\r\n\tfloat fzero = u_SpecularReflectance;\r\n #else\r\n\tfloat fze" -"ro = 0.0;\r\n #endif\r\n\tfloat directedDiff = NL * CalcDiffuse(worldNorma" -"l, worldLight, SampleToView, NE, NL, fzero, u_DiffuseRoughness);\r\n\tdiffu" -"se.rgb *= directedLight * directedDiff + ambientDiff * ambientLight;\r\n " -"\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\tfloat shininess = specular.a * 255 + 1.0;\r\n\r\n\tvec3 halfAngle " -"= normalize(worldLight + SampleToView);\r\n\r\n\tfloat EH = clamp(dot(Sampl" -"eToView, halfAngle), 0.0, 1.0);\r\n\tfloat NH = clamp(dot(worldNormal, hal" -"fAngle), 0.0, 1.0);\r\n\r\n\tfloat directedSpec = NL * CalcSpecular(NH, NL," -" NE, EH, fzero, shininess);\r\n \r\n #if defined(r_normalAmbient)\r\n\t" -"vec3 ambientHalf = normalize(var_Normal + SampleToView);\r\n\tfloat ambient" -"Spec = max(dot(ambientHalf, worldNormal) + 0.5, 0.0);\r\n\tambientSpec *= a" -"mbientSpec * 0.44;\r\n\tambientSpec = pow(ambientSpec, shininess) * fzero;" -"\r\n #if defined(USE_TRIACE)\r\n\tambientSpec *= 0.1248582 * shininess" -" + 0.2691817;\r\n #endif \r\n\tspecular.rgb *= directedSpec * direc" -"tedLight + ambientSpec * ambientLight;\r\n #else\r\n\tspecular.rgb *= di" -"rectedSpec * 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(USE_LI" -"GHT)\r\n\tgl_FragColor.rgb += specular.rgb;\r\n#endif\r\n\r\n#if !defined(U" -"SE_LIGHT_VERTEX)\r\n\tgl_FragColor *= var_Color;\r\n#endif\r\n}\r\n"; +"_DirectedLight;\r\nuniform vec3 u_AmbientLight;\r\nuniform float u" +"_LightRadius;\r\n#endif\r\n\r\n#if defined(USE_SPECULARMAP)\r\nuniform floa" +"t u_SpecularReflectance;\r\n#endif\r\n\r\n#if !defined(USE_FAST_LIGHT)" +"\r\nuniform float u_DiffuseRoughness;\r\n#endif\r\n\r\nvarying vec2 " +" var_DiffuseTex;\r\n#if defined(USE_LIGHTMAP)\r\nvarying vec2 var_Lig" +"htTex;\r\n#endif\r\nvarying vec4 var_Color;\r\n\r\nvarying vec3 v" +"ar_SampleToView;\r\n\r\nvarying vec3 var_Normal;\r\n#if defined(USE_NO" +"RMALMAP)\r\nvarying vec3 var_Tangent;\r\nvarying vec3 var_Bitange" +"nt;\r\n#endif\r\n\r\n#if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGH" +"T)\r\nvarying vec3 var_VectLight;\r\n#endif\r\n\r\n#if defined(USE_LIG" +"HT) && !defined(USE_DELUXEMAP)\r\nvarying vec3 var_WorldLight;\r\n#end" +"if\r\n\r\n#define EPSILON 0.00000001\r\n\r\n#if defined(USE_PARALLAXMAP)\r" +"\nfloat SampleHeight(sampler2D normalMap, vec2 t)\r\n{\r\n #if defined(SWI" +"ZZLE_NORMALMAP)\r\n\treturn texture2D(normalMap, t).r;\r\n #else\r\n\tretu" +"rn texture2D(normalMap, t).a;\r\n #endif\r\n}\r\n\r\nfloat RayIntersectDis" +"placeMap(vec2 dp, vec2 ds, sampler2D normalMap)\r\n{\r\n\tconst int linearS" +"earchSteps = 16;\r\n\tconst int binarySearchSteps = 6;\r\n\r\n\tfloat depth" +"Step = 1.0 / float(linearSearchSteps);\r\n\r\n\t// current size of search w" +"indow\r\n\tfloat size = depthStep;\r\n\r\n\t// current depth position\r\n\t" +"float 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\tfloat t = 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 b" +"est depth\r\n\t}\r\n\r\n\tdepth = bestDepth;\r\n\t\r\n\t// recurse around f" +"irst point (depth) for closest match\r\n\tfor(int i = 0; i < binarySearchSt" +"eps; ++i)\r\n\t{\r\n\t\tsize *= 0.5;\r\n\r\n\t\tfloat t = SampleHeight(norm" +"alMap, dp + ds * depth);\r\n\t\t\r\n\t\tif(depth >= t)\r\n\t\t{\r\n\t\t\tbe" +"stDepth = depth;\r\n\t\t\tdepth -= 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 CalcDi" +"ffuse(vec3 N, vec3 L, vec3 E, float NE, float NL, float fzero, float roughn" +"ess)\r\n{\r\n #if defined(USE_OREN_NAYAR)\r\n\tfloat gamma = dot(E - N * N" +"E, 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.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 - f" +"zero;\r\n #endif\r\n}\r\n\r\n#if defined(USE_SPECULARMAP)\r\nfloat CalcSpe" +"cular(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_TOR" +"RANCE_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_TRIACE) || defined (USE_TORRANCE_SPARROW" +")\r\n\tfloat fresnel = fzero + (1.0 - fzero) * pow(1.0 - EH, 5);\r\n #endi" +"f\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 #e" +"ndif \r\n\r\n #if defined(USE_COOK_TORRANCE)\r\n\tfloat m = sqrt(2.0 / sh" +"ininess);\r\n\r\n\tfloat m_sq = m * m;\r\n\tfloat NH_sq = NH * NH;\r\n\tflo" +"at 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 / m" +"ax(NE, EPSILON);\r\n #endif\r\n\r\n #if defined(USE_TRIACE)\r\n\tfloat sc" +"ale = 0.1248582 * shininess + 0.2691817;\r\n\r\n\treturn fresnel * scale * " +"blinn / max(max(NL, NE), EPSILON);\r\n #endif\r\n \r\n #if defined(USE_T" +"ORRANCE_SPARROW)\r\n\tfloat scale = 0.125 * shininess + 1.0;\r\n\r\n\tretur" +"n fresnel * geo * scale * blinn / max(NE, EPSILON);\r\n #endif\r\n}\r\n#en" +"dif\r\n\r\nvoid main()\r\n{\r\n#if defined(USE_DELUXEMAP)\r\n\tvec3 worldLi" +"ght = 2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0);\r\n\t//wo" +"rldLight += 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 lightSample = texture2D(u_LightMap, var_LightTex).rgba;\r\n #if def" +"ined(RGBE_LIGHTMAP)\r\n\tlightSample.rgb *= exp2(lightSample.a * 255.0 - 12" +"8.0);\r\n #endif\r\n\tvec3 directedLight = lightSample.rgb;\r\n#elif defin" +"ed(USE_LIGHT_VECTOR)\r\n #if defined(USE_FAST_LIGHT)\r\n\tvec3 directedLig" +"ht = var_VectLight;\r\n #else\r\n #if defined(USE_INVSQRLIGHT)\r\n\tflo" +"at intensity = 1.0 / dot(worldLight, worldLight);\r\n #else\r\n\tfloat i" +"ntensity = clamp((1.0 - dot(worldLight, worldLight) / (u_LightRadius * u_Li" +"ghtRadius)) * 1.07, 0.0, 1.0);\r\n #endif\r\n #if defined(USE_SHADOWM" +"AP)\r\n \tvec3 dist3 = textureCube(u_ShadowMap, worldLight).rgb;\r\n\tfloa" +"t dist = dot(dist3, vec3(1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0)) * u_Ligh" +"tRadius;\r\n\r\n\tintensity *= clamp(sign(dist - length(worldLight)), 0.0, " +"1.0);\r\n #endif\r\n\tvec3 directedLight = u_DirectedLight * intensity;" +"\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_LIGHT" +")\r\n\tvec3 SampleToView = normalize(var_SampleToView);\r\n#endif\r\n\tvec2" +" tex = var_DiffuseTex;\r\n\r\n\tfloat ambientDiff = 1.0;\r\n\r\n#if defined" +"(USE_NORMALMAP)\r\n\tmat3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitang" +"ent.xyz, var_Normal.xyz);\r\n\r\n #if defined(USE_PARALLAXMAP)\r\n\tvec3 o" +"ffsetDir = normalize(SampleToView * tangentToWorld);\r\n #if 0\r\n fl" +"oat height = SampleHeight(u_NormalMap, tex);\r\n\tfloat pdist = 0.05 * heig" +"ht - (0.05 / 2.0);\r\n #else\r\n\toffsetDir.xy *= 0.02 / offsetDir.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 def" +"ined(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\tnormal.z = sqrt(clamp(1.0 - dot(normal.xy, no" +"rmal.xy), 0.0, 1.0));\r\n\tvec3 worldNormal = tangentToWorld * normal;\r\n " +" #if defined(r_normalAmbient)\r\n\tambientDiff = 0.781341 * normal.z + 0.21" +"8659;\r\n #endif\r\n#else\r\n\tvec3 worldNormal = var_Normal;\r\n#endif\r" +"\n\r\n\tvec4 diffuse = texture2D(u_DiffuseMap, tex);\r\n\r\n#if defined(USE" +"_LIGHT) && defined(USE_FAST_LIGHT)\r\n\tdiffuse.rgb *= directedLight;\r\n#e" +"lif defined(USE_LIGHT)\r\n\tworldNormal = normalize(worldNormal);\r\n\tworl" +"dLight = normalize(worldLight);\r\n\r\n #if defined(USE_LIGHTMAP) || defin" +"ed(USE_LIGHT_VERTEX)\r\n\tdirectedLight /= max(dot(normalize(var_Normal), w" +"orldLight), 0.004);\r\n\r\n #if defined(r_normalAmbient)\r\n\tvec3 ambie" +"ntLight = directedLight * r_normalAmbient;\r\n\tdirectedLight -= ambientLig" +"ht;\r\n #else\r\n\tvec3 ambientLight = vec3(0);\r\n #endif\r\n #endi" +"f\r\n\r\n\tfloat NL = clamp(dot(worldNormal, worldLight), 0.0, 1.0);\r\n" +"\tfloat NE = clamp(dot(worldNormal, SampleToView), 0.0, 1.0);\r\n #if def" +"ined(USE_SPECULARMAP)\r\n\tfloat fzero = u_SpecularReflectance;\r\n #else" +"\r\n\tfloat fzero = 0.0;\r\n #endif\r\n\tfloat directedDiff = NL * CalcDif" +"fuse(worldNormal, worldLight, SampleToView, NE, NL, fzero, u_DiffuseRoughne" +"ss);\r\n\tdiffuse.rgb *= directedLight * directedDiff + ambientDiff * ambie" +"ntLight;\r\n \r\n #if defined(USE_SPECULARMAP)\r\n\tvec4 specular = textu" +"re2D(u_SpecularMap, tex);\r\n\t//specular.rgb = clamp(specular.rgb - diffus" +"e.rgb, 0.0, 1.0);\r\n\tfloat shininess = specular.a * 255 + 1.0;\r\n\r\n\tv" +"ec3 halfAngle = normalize(worldLight + SampleToView);\r\n\r\n\tfloat EH = c" +"lamp(dot(SampleToView, halfAngle), 0.0, 1.0);\r\n\tfloat NH = clamp(dot(wor" +"ldNormal, halfAngle), 0.0, 1.0);\r\n\r\n\tfloat directedSpec = NL * CalcSp" +"ecular(NH, NL, NE, EH, fzero, shininess);\r\n \r\n #if defined(r_normal" +"Ambient)\r\n\tvec3 ambientHalf = normalize(var_Normal + SampleToView);\r\n" +"\tfloat ambientSpec = max(dot(ambientHalf, worldNormal) + 0.5, 0.0);\r\n\ta" +"mbientSpec *= ambientSpec * 0.44;\r\n\tambientSpec = pow(ambientSpec, shini" +"ness) * fzero;\r\n #if defined(USE_TRIACE)\r\n\tambientSpec *= 0.12485" +"82 * shininess + 0.2691817;\r\n #endif \r\n\tspecular.rgb *= direct" +"edSpec * directedLight + ambientSpec * ambientLight;\r\n #else\r\n\tspec" +"ular.rgb *= directedSpec * directedLight;\r\n #endif\r\n #endif\r\n#end" +"if\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 += spe" +"cular.rgb;\r\n#endif\r\n\r\n#if !defined(USE_LIGHT_VERTEX)\r\n\tgl_FragColo" +"r *= 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" @@ -623,23 +636,23 @@ static const char *fallbackToneMapShader_fp = "iform vec4 u_Color;\r\n\r\nuniform vec2 u_InvTexRes;\r\nuniform v" "ec2 u_AutoExposureMinMax;\r\n\r\nvarying vec2 var_TexCoords;\r\n" "\r\nconst vec3 LUMINANCE_VECTOR = vec3(0.2125, 0.7154, 0.0721); //vec3(0" -".299, 0.587, 0.114);\r\n\r\nfloat FilmicTonemap(float x)\r\n{\r\n\tfloat sh" -"oulderStrength = 0.22;\r\n\tfloat linearStrength = 0.30;\r\n\tfloat linearA" -"ngle = 0.10;\r\n\tfloat toeStrength = 0.20;\r\n\tfloat toeAngleNumerator = " -"0.01;\r\n\tfloat toeAngleDenominator = 0.30;\r\n float toeAngle = toeAng" -"leNumerator / toeAngleDenominator;\r\n\t\r\n\treturn ((x*(shoulderStrength*" -"x+linearAngle*linearStrength)+toeStrength*toeAngleNumerator)/\r\n\t(x*(shou" -"lderStrength*x+linearStrength)+toeStrength*toeAngleDenominator)) - toeAngle" -";\r\n}\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = texture2D(u_TextureMap, va" -"r_TexCoords) * u_Color;\r\n\tvec3 minAvgMax = texture2D(u_LevelsMap, var_Te" -"xCoords).rgb;\r\n\tvec3 logMinAvgMaxLum = clamp(minAvgMax * 20.0 - 10.0, -u" -"_AutoExposureMinMax.y, -u_AutoExposureMinMax.x);\r\n\t\t\r\n\tfloat avgLum " -"= exp2(logMinAvgMaxLum.y) ;\r\n\tfloat maxLum = exp2(logMinAvgMaxLum.z);\r" -"\n\r\n\tfloat fWhite = 1.0 / FilmicTonemap(avgLum * 2);\r\n\tcolor.r = Film" -"icTonemap(color.r) * fWhite;\r\n\tcolor.g = FilmicTonemap(color.g) * fWhite" -";\r\n\tcolor.b = FilmicTonemap(color.b) * fWhite;\r\n\t\r\n#if defined(r_ob" -"bcorrect)\r\n\tcolor.rgb /= r_obbcorrect;\r\n#endif\r\n\t\r\n\tgl_FragColor" -" = color;\r\n}\r\n"; +".299, 0.587, 0.114);\r\n\r\nvec3 FilmicTonemap(vec3 x)\r\n{\r\n\tconst floa" +"t SS = 0.22; // Shoulder Strength\r\n\tconst float LS = 0.30; // Linear S" +"trength\r\n\tconst float LA = 0.10; // Linear Angle\r\n\tconst float TS =" +" 0.20; // Toe Strength\r\n\tconst float TAN = 0.01; // Toe Angle Numerator" +"\r\n\tconst float TAD = 0.30; // Toe Angle Denominator\r\n\t\r\n\tvec3 SSxx" +" = SS * x * x;\r\n\tvec3 LSx = LS * x;\r\n\tvec3 LALSx = LSx * LA;\r\n\t\r" +"\n\treturn ((SSxx + LALSx + TS * TAN) / (SSxx + LSx + TS * TAD)) - TAN / TA" +"D;\r\n\r\n\t//return ((x*(SS*x+LA*LS)+TS*TAN)/(x*(SS*x+LS)+TS*TAD)) - TAN/T" +"AD;\r\n\r\n}\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = texture2D(u_TextureM" +"ap, var_TexCoords) * u_Color;\r\n\tvec3 minAvgMax = texture2D(u_LevelsMap, " +"var_TexCoords).rgb;\r\n\tvec3 logMinAvgMaxLum = clamp(minAvgMax * 20.0 - 10" +".0, -u_AutoExposureMinMax.y, -u_AutoExposureMinMax.x);\r\n\t\t\r\n\tfloat a" +"vgLum = exp2(logMinAvgMaxLum.y);\r\n\t//float maxLum = exp2(logMinAvgMaxLum" +".z);\r\n\t\r\n\tcolor.rgb /= avgLum;\r\n\r\n\tvec3 fWhite = 1.0 / FilmicTon" +"emap(vec3(2.0));\r\n\tcolor.rgb = FilmicTonemap(color.rgb) * fWhite;\r\n\t" +"\r\n#if defined(r_obbcorrect)\r\n\tcolor.rgb /= r_obbcorrect;\r\n#endif\r\n" +"\t\r\n\tgl_FragColor = color;\r\n}\r\n"; static const char *fallbackCalcLevels4xShader_vp = "attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\n\r\nunif" @@ -658,20 +671,21 @@ static const char *fallbackCalcLevels4xShader_fp = "clamp(log2(lumi), -10.0, 10.0);\r\n\tminAvgMax = vec3(loglumi * 0.05 + 0.5)" ";\r\n#endif\r\n\r\n\treturn vec3(min(current.x, minAvgMax.x), current.y + m" "inAvgMax.y, max(current.z, minAvgMax.z));\r\n}\r\n\r\nvoid main()\r\n{\r\n" -"\tvec3 current = vec3(1.0, 0.0, 0.0);\r\n\r\n\tcurrent = GetValues(vec2(-1." -"5, -1.5), current);\r\n\tcurrent = GetValues(vec2(-0.5, -1.5), current);\r" -"\n\tcurrent = GetValues(vec2( 0.5, -1.5), current);\r\n\tcurrent = GetValue" -"s(vec2( 1.5, -1.5), current);\r\n\t\r\n\tcurrent = GetValues(vec2(-1.5, -0." -"5), current);\r\n\tcurrent = GetValues(vec2(-0.5, -0.5), current);\r\n\tcur" -"rent = GetValues(vec2( 0.5, -0.5), current);\r\n\tcurrent = GetValues(vec2(" -" 1.5, -0.5), current);\r\n\t\r\n\tcurrent = GetValues(vec2(-1.5, 0.5), cur" -"rent);\r\n\tcurrent = GetValues(vec2(-0.5, 0.5), current);\r\n\tcurrent = " -"GetValues(vec2( 0.5, 0.5), current);\r\n\tcurrent = GetValues(vec2( 1.5, " -"0.5), current);\r\n\r\n\tcurrent = GetValues(vec2(-1.5, 1.5), current);\r" -"\n\tcurrent = GetValues(vec2(-0.5, 1.5), current);\r\n\tcurrent = GetValue" -"s(vec2( 0.5, 1.5), current);\r\n\tcurrent = GetValues(vec2( 1.5, 1.5), cu" -"rrent);\r\n\r\n\tcurrent.y *= 0.0625;\r\n\r\n\tgl_FragColor = vec4(current," -" 1.0f);\r\n}\r\n"; +"\tvec3 current = vec3(1.0, 0.0, 0.0);\r\n\r\n#ifdef FIRST_PASS\r\n\tcurrent" +" = GetValues(vec2( 0.0, 0.0), current);\r\n#else\r\n\tcurrent = GetValues(" +"vec2(-1.5, -1.5), current);\r\n\tcurrent = GetValues(vec2(-0.5, -1.5), curr" +"ent);\r\n\tcurrent = GetValues(vec2( 0.5, -1.5), current);\r\n\tcurrent = G" +"etValues(vec2( 1.5, -1.5), current);\r\n\t\r\n\tcurrent = GetValues(vec2(-1" +".5, -0.5), current);\r\n\tcurrent = GetValues(vec2(-0.5, -0.5), current);\r" +"\n\tcurrent = GetValues(vec2( 0.5, -0.5), current);\r\n\tcurrent = GetValue" +"s(vec2( 1.5, -0.5), current);\r\n\t\r\n\tcurrent = GetValues(vec2(-1.5, 0." +"5), current);\r\n\tcurrent = GetValues(vec2(-0.5, 0.5), current);\r\n\tcur" +"rent = GetValues(vec2( 0.5, 0.5), current);\r\n\tcurrent = GetValues(vec2(" +" 1.5, 0.5), current);\r\n\r\n\tcurrent = GetValues(vec2(-1.5, 1.5), curre" +"nt);\r\n\tcurrent = GetValues(vec2(-0.5, 1.5), current);\r\n\tcurrent = Ge" +"tValues(vec2( 0.5, 1.5), current);\r\n\tcurrent = GetValues(vec2( 1.5, 1." +"5), current);\r\n\r\n\tcurrent.y *= 0.0625;\r\n#endif\r\n\r\n\tgl_FragColor" +" = vec4(current, 1.0f);\r\n}\r\n"; @@ -1746,6 +1760,9 @@ void GLSL_InitGPUShaders(void) { Q_strcat(extradefines, 1024, "#define USE_LIGHT\n"); + if (r_normalMapping->integer == 0 && r_specularMapping->integer == 0) + Q_strcat(extradefines, 1024, "#define USE_FAST_LIGHT\n"); + switch (i & LIGHTDEF_LIGHTTYPE_MASK) { case LIGHTDEF_USE_LIGHTMAP: diff --git a/reaction/code/renderergl2/tr_image.c b/reaction/code/renderergl2/tr_image.c index f1fdc79c..5e3a3200 100644 --- a/reaction/code/renderergl2/tr_image.c +++ b/reaction/code/renderergl2/tr_image.c @@ -2825,8 +2825,9 @@ void R_CreateBuiltinImages( void ) { p = data; } - tr.calcLevelsImage = R_CreateImage("*calcLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); - tr.fixedLevelsImage = R_CreateImage("*fixedLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); + tr.calcLevelsImage = R_CreateImage("*calcLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); + tr.targetLevelsImage = R_CreateImage("*targetLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); + tr.fixedLevelsImage = R_CreateImage("*fixedLevels", p, 1, 1, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); } for (x = 0; x < 2; x++) diff --git a/reaction/code/renderergl2/tr_local.h b/reaction/code/renderergl2/tr_local.h index 9b8190bf..fca643ba 100644 --- a/reaction/code/renderergl2/tr_local.h +++ b/reaction/code/renderergl2/tr_local.h @@ -1739,6 +1739,7 @@ typedef struct { image_t *screenScratchImage; image_t *quarterImage[2]; image_t *calcLevelsImage; + image_t *targetLevelsImage; image_t *fixedLevelsImage; image_t *textureDepthImage; @@ -1752,6 +1753,7 @@ typedef struct { FBO_t *screenScratchFbo; FBO_t *quarterFbo[2]; FBO_t *calcLevelsFbo; + FBO_t *targetLevelsFbo; shader_t *defaultShader; shader_t *shadowShader; diff --git a/reaction/code/renderergl2/tr_postprocess.c b/reaction/code/renderergl2/tr_postprocess.c index bdf94643..9a1794f2 100644 --- a/reaction/code/renderergl2/tr_postprocess.c +++ b/reaction/code/renderergl2/tr_postprocess.c @@ -26,43 +26,49 @@ void RB_ToneMap(FBO_t *hdrFbo, int autoExposure) { vec4i_t srcBox, dstBox; vec4_t color; - vec4_t white; - vec2_t texScale; + static int lastFrameCount = 0; - texScale[0] = - texScale[1] = 1.0f; - - VectorSet4(white, 1, 1, 1, 1); - - if (glRefConfig.framebufferObject && autoExposure) + if (autoExposure) { - // determine average log luminance - int size = 256, currentScratch, nextScratch, tmp; - - VectorSet4(srcBox, 0, 0, hdrFbo->width, hdrFbo->height); - VectorSet4(dstBox, 0, 0, 256, 256); - - FBO_Blit(hdrFbo, srcBox, texScale, tr.textureScratchFbo[0], dstBox, &tr.calclevels4xShader[0], white, 0); - - currentScratch = 0; - nextScratch = 1; - - // downscale to 1x1 texture - while (size > 1) + if (lastFrameCount == 0 || tr.frameCount < lastFrameCount || tr.frameCount - lastFrameCount > 5) { - VectorSet4(srcBox, 0, 0, size, size); - size >>= 2; - VectorSet4(dstBox, 0, 0, size, size); - FBO_Blit(tr.textureScratchFbo[currentScratch], srcBox, texScale, tr.textureScratchFbo[nextScratch], dstBox, &tr.calclevels4xShader[1], white, 0); + // determine average log luminance + FBO_t *srcFbo, *dstFbo, *tmp; + int size = 256; - tmp = currentScratch; - currentScratch = nextScratch; - nextScratch = tmp; + lastFrameCount = tr.frameCount; + + VectorSet4(dstBox, 0, 0, size, size); + + srcFbo = hdrFbo; + dstFbo = tr.textureScratchFbo[0]; + FBO_Blit(srcFbo, NULL, NULL, dstFbo, dstBox, &tr.calclevels4xShader[0], NULL, 0); + + srcFbo = tr.textureScratchFbo[0]; + dstFbo = tr.textureScratchFbo[1]; + + // downscale to 1x1 texture + while (size > 1) + { + VectorSet4(srcBox, 0, 0, size, size); + //size >>= 2; + size >>= 1; + VectorSet4(dstBox, 0, 0, size, size); + + if (size == 1) + dstFbo = tr.targetLevelsFbo; + + //FBO_Blit(targetFbo, srcBox, NULL, tr.textureScratchFbo[nextScratch], dstBox, &tr.calclevels4xShader[1], NULL, 0); + FBO_FastBlit(srcFbo, srcBox, dstFbo, dstBox, GL_COLOR_BUFFER_BIT, GL_LINEAR); + + tmp = srcFbo; + srcFbo = dstFbo; + dstFbo = tmp; + } } // blend with old log luminance for gradual change VectorSet4(srcBox, 0, 0, 0, 0); - VectorSet4(dstBox, 0, 0, 1, 1); color[0] = color[1] = @@ -72,27 +78,21 @@ void RB_ToneMap(FBO_t *hdrFbo, int autoExposure) else color[3] = 0.1f; - FBO_Blit(tr.textureScratchFbo[currentScratch], srcBox, texScale, tr.calcLevelsFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + FBO_Blit(tr.targetLevelsFbo, srcBox, NULL, tr.calcLevelsFbo, NULL, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } - if (glRefConfig.framebufferObject) - { - // tonemap - VectorSet4(srcBox, 0, 0, hdrFbo->width, hdrFbo->height); - VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); + // tonemap + color[0] = + color[1] = + color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); + color[3] = 1.0f; - color[0] = - color[1] = - color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); - color[3] = 1.0f; + if (autoExposure) + GL_BindToTMU(tr.calcLevelsImage, TB_LEVELSMAP); + else + GL_BindToTMU(tr.fixedLevelsImage, TB_LEVELSMAP); - if (autoExposure) - GL_BindToTMU(tr.calcLevelsImage, TB_LEVELSMAP); - else - GL_BindToTMU(tr.fixedLevelsImage, TB_LEVELSMAP); - - FBO_Blit(hdrFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.tonemapShader, color, 0); - } + FBO_Blit(hdrFbo, NULL, NULL, tr.screenScratchFbo, NULL, &tr.tonemapShader, color, 0); } @@ -100,13 +100,6 @@ void RB_BokehBlur(float blur) { vec4i_t srcBox, dstBox; vec4_t color; - vec4_t white; - vec2_t texScale; - - texScale[0] = - texScale[1] = 1.0f; - - VectorSet4(white, 1, 1, 1, 1); blur *= 10.0f; @@ -119,58 +112,40 @@ void RB_BokehBlur(float blur) if (blur > 0.0f) { // create a quarter texture - VectorSet4(srcBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); - VectorSet4(dstBox, 0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height); - - FBO_Blit(tr.screenScratchFbo, srcBox, texScale, tr.quarterFbo[0], dstBox, &tr.textureColorShader, white, 0); + FBO_Blit(tr.screenScratchFbo, NULL, NULL, tr.quarterFbo[0], NULL, NULL, NULL, 0); } #ifndef HQ_BLUR if (blur > 1.0f) { // create a 1/16th texture - VectorSet4(srcBox, 0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height); - VectorSet4(dstBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height); - - FBO_Blit(tr.quarterFbo[0], srcBox, texScale, tr.textureScratchFbo[0], dstBox, &tr.textureColorShader, white, 0); + FBO_Blit(tr.quarterFbo[0], NULL, NULL, tr.textureScratchFbo[0], NULL, NULL, NULL, 0); } #endif if (blur > 0.0f && blur <= 1.0f) { // Crossfade original with quarter texture - VectorSet4(srcBox, 0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height); - VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); - VectorSet4(color, 1, 1, 1, blur); - FBO_Blit(tr.quarterFbo[0], srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + FBO_Blit(tr.quarterFbo[0], NULL, NULL, tr.screenScratchFbo, NULL, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } #ifndef HQ_BLUR // ok blur, but can see some pixelization else if (blur > 1.0f && blur <= 2.0f) { // crossfade quarter texture with 1/16th texture - VectorSet4(srcBox, 0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height); - VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); - - FBO_Blit(tr.quarterFbo[0], srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, white, 0); - - VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height); - VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); + FBO_Blit(tr.quarterFbo[0], NULL, NULL, tr.screenScratchFbo, NULL, NULL, NULL, 0); VectorSet4(color, 1, 1, 1, blur - 1.0f); - FBO_Blit(tr.textureScratchFbo[0], srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + FBO_Blit(tr.textureScratchFbo[0], NULL, NULL, tr.screenScratchFbo, NULL, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } else if (blur > 2.0f) { // blur 1/16th texture then replace int i; - VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height); - VectorSet4(dstBox, 0, 0, tr.textureScratchFbo[1]->width, tr.textureScratchFbo[1]->height); - for (i = 0; i < 2; i++) { vec2_t blurTexScale; @@ -187,15 +162,12 @@ void RB_BokehBlur(float blur) color[3] = 1.0f; if (i != 0) - FBO_Blit(tr.textureScratchFbo[0], srcBox, blurTexScale, tr.textureScratchFbo[1], dstBox, &tr.bokehShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); + FBO_Blit(tr.textureScratchFbo[0], NULL, blurTexScale, tr.textureScratchFbo[1], NULL, &tr.bokehShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); else - FBO_Blit(tr.textureScratchFbo[0], srcBox, blurTexScale, tr.textureScratchFbo[1], dstBox, &tr.bokehShader, color, 0); + FBO_Blit(tr.textureScratchFbo[0], NULL, blurTexScale, tr.textureScratchFbo[1], NULL, &tr.bokehShader, color, 0); } - VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[1]->width, tr.textureScratchFbo[1]->height); - VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); - - FBO_Blit(tr.textureScratchFbo[1], srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, white, 0); + FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, tr.screenScratchFbo, NULL, &tr.textureColorShader, NULL, 0); } #else // higher quality blur, but slower else if (blur > 1.0f) @@ -203,9 +175,6 @@ void RB_BokehBlur(float blur) // blur quarter texture then replace int i; - VectorSet4(srcBox, 0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height); - VectorSet4(dstBox, 0, 0, tr.quarterFbo[1]->width, tr.quarterFbo[1]->height); - src = tr.quarterFbo[0]; dst = tr.quarterFbo[1]; @@ -229,13 +198,10 @@ void RB_BokehBlur(float blur) else color[3] = 0.5f; - FBO_Blit(tr.quarterFbo[0], srcBox, blurTexScale, tr.quarterFbo[1], dstBox, &tr.bokehShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + FBO_Blit(tr.quarterFbo[0], NULL, blurTexScale, tr.quarterFbo[1], NULL, &tr.bokehShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } - VectorSet4(srcBox, 0, 0, 512, 512); - VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); - - FBO_Blit(tr.quarterFbo[1], srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, white, 0); + FBO_Blit(tr.quarterFbo[1], NULL, NULL, tr.screenScratchFbo, NULL, &tr.textureColorShader, NULL, 0); } #endif } @@ -354,7 +320,7 @@ void RB_GodRays(void) hpos[3] = 0.5f / hpos[3]; pos[0] = 0.5f + hpos[0] * hpos[3]; - pos[1] = 0.5f + hpos[1] * hpos[3]; + pos[1] = 0.5f - hpos[1] * hpos[3]; // viewport dimensions w = glConfig.vidWidth;