diff --git a/Src/Graphics/New3D/Model.h b/Src/Graphics/New3D/Model.h index 8ef6b67..d63985b 100644 --- a/Src/Graphics/New3D/Model.h +++ b/Src/Graphics/New3D/Model.h @@ -200,6 +200,7 @@ struct Viewport float angle_right; float angle_top; float angle_bottom; + float cota; Mat4 projectionMatrix; // projection matrix, we will calc this later when we have scene near/far vals diff --git a/Src/Graphics/New3D/New3D.cpp b/Src/Graphics/New3D/New3D.cpp index d494eb5..8e1e2fc 100644 --- a/Src/Graphics/New3D/New3D.cpp +++ b/Src/Graphics/New3D/New3D.cpp @@ -1061,6 +1061,8 @@ void CNew3D::RenderViewport(UINT32 addr) vp->angle_bottom = -(1.0f - io) / cw; vp->angle_top = -(0.0f - io) / cw; + vp->cota = Util::Uint32AsFloat(vpnode[0x3]); + CalcViewport(vp); // Lighting (note that sun vector points toward sun -- away from vertex) diff --git a/Src/Graphics/New3D/R3DShader.cpp b/Src/Graphics/New3D/R3DShader.cpp index ba2cd45..23a5e3b 100644 --- a/Src/Graphics/New3D/R3DShader.cpp +++ b/Src/Graphics/New3D/R3DShader.cpp @@ -149,6 +149,8 @@ bool R3DShader::LoadShader(const char* vertexShader, const char* fragmentShader) m_locHardwareStep = glGetUniformLocation(m_shaderProgram, "hardwareStep"); m_locDiscardAlpha = glGetUniformLocation(m_shaderProgram, "discardAlpha"); + m_locCota = glGetUniformLocation(m_shaderProgram, "cota"); + return true; } @@ -362,6 +364,8 @@ void R3DShader::SetViewportUniforms(const Viewport *vp) glUniformMatrix4fv(m_locProjMat, 1, GL_FALSE, vp->projectionMatrix); glUniform1i(m_locHardwareStep, vp->hardwareStep); + + glUniform1f(m_locCota, vp->cota); } void R3DShader::SetModelStates(const Model* model) diff --git a/Src/Graphics/New3D/R3DShader.h b/Src/Graphics/New3D/R3DShader.h index 734728a..199a9ea 100644 --- a/Src/Graphics/New3D/R3DShader.h +++ b/Src/Graphics/New3D/R3DShader.h @@ -100,6 +100,7 @@ private: GLint m_locFogAttenuation; GLint m_locFogAmbient; GLint m_locProjMat; + GLint m_locCota; // lighting / other GLint m_locLighting; diff --git a/Src/Graphics/New3D/R3DShaderCommon.h b/Src/Graphics/New3D/R3DShaderCommon.h index 8534078..108bdd5 100644 --- a/Src/Graphics/New3D/R3DShaderCommon.h +++ b/Src/Graphics/New3D/R3DShaderCommon.h @@ -119,15 +119,6 @@ ivec2 GetMicroTexturePos(int id) return ivec2(xCoords[id],yCoords[id]); } -float mip_map_level(in vec3 coordinate) -{ - // Real3D uses vertex coordinates rather than texel coordinates to calculate mipmap levels - vec3 dx_vtc = dFdx(coordinate); - vec3 dy_vtc = dFdy(coordinate); - float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc)); - return log2(delta_max_sqr / (fsTextureNP * fsTextureNP)) * 0.5; // result not clamped -} - float LinearTexLocations(int wrapMode, float size, float u, out float u0, out float u1) { float texelSize = 1.0 / size; @@ -209,7 +200,7 @@ vec4 texBiLinear(usampler2D texSampler, ivec2 wrapMode, vec2 texSize, ivec2 texP vec4 GetTextureValue() { - float lod = mip_map_level(fsViewVertex); + float lod = -log2(gl_FragCoord.w * gl_FragCoord.w * fsLODBase); float numLevels = floor(log2(min(float(baseTexInfo.z), float(baseTexInfo.w)))) - 1.0; // r3d only generates down to 2:2 for square textures, otherwise its the min dimension float fLevel = clamp(lod, 0.0, numLevels); @@ -242,7 +233,7 @@ vec4 GetTextureValue() ivec2 tex2Pos = GetMicroTexturePos(microTextureID); tex2Data = texBiLinear(textureBank[(texturePage+1)&1], ivec2(0), ivec2(128), tex2Pos, fsTexCoord * scale, 0); - blendFactor = -(lod + microTextureMinLOD) * 0.25; + blendFactor = -(lod + microTextureMinLOD) * 0.5; blendFactor = clamp(blendFactor, 0.0, 0.5); } diff --git a/Src/Graphics/New3D/R3DShaderQuads.h b/Src/Graphics/New3D/R3DShaderQuads.h index 6b93586..097c8bd 100644 --- a/Src/Graphics/New3D/R3DShaderQuads.h +++ b/Src/Graphics/New3D/R3DShaderQuads.h @@ -8,6 +8,7 @@ static const char *vertexShaderR3DQuads = R"glsl( // uniforms uniform float modelScale; uniform float nodeAlpha; +uniform float cota; uniform mat4 modelMat; uniform mat4 projMat; uniform bool translatorMap; @@ -30,8 +31,8 @@ out VS_OUT vec2 texCoord; vec4 color; float fixedShade; - float textureNP; float discardPoly; // can't have varying bool (glsl spec) + float LODBase; } vs_out; vec4 GetColour(vec4 colour) @@ -64,7 +65,7 @@ void main(void) vs_out.color = GetColour(inColour); vs_out.texCoord = inTexCoord; vs_out.fixedShade = inFixedShade; - vs_out.textureNP = inTextureNP * modelScale; + vs_out.LODBase = -vs_out.discardPoly * cota * inTextureNP; gl_Position = projMat * modelMat * inVertex; } )glsl"; @@ -83,8 +84,8 @@ in VS_OUT vec2 texCoord; vec4 color; float fixedShade; - float textureNP; float discardPoly; // can't have varying bool (glsl spec) + float LODBase; } gs_in[4]; out GS_OUT @@ -99,7 +100,7 @@ out GS_OUT flat vec2 texCoord[4]; flat vec4 color; flat float fixedShade[4]; - flat float textureNP; + flat float LODBase; } gs_out; //a*b - c*d, computed in a stable fashion (Kahan) @@ -133,7 +134,7 @@ void main(void) // flat attributes gs_out.color = gs_in[0].color; - gs_out.textureNP = gs_in[0].textureNP; + gs_out.LODBase = gs_in[0].LODBase; // precompute crossproducts for all vertex combinations to be looked up in loop below for area computation precise float cross[4][4]; @@ -238,7 +239,7 @@ in GS_OUT flat vec2 texCoord[4]; flat vec4 color; flat float fixedShade[4]; - flat float textureNP; + flat float LODBase; } fs_in; //our calculated vertex attributes from the above @@ -247,7 +248,7 @@ vec3 fsViewNormal; vec2 fsTexCoord; float fsFixedShade; vec4 fsColor; -float fsTextureNP; +float fsLODBase; //outputs layout(location = 0) out vec4 out0; // opaque @@ -332,7 +333,7 @@ void QuadraticInterpolation() fsTexCoord = vec2(0.0); fsFixedShade = 0.0; fsColor = fs_in.color; - fsTextureNP = fs_in.textureNP; + fsLODBase = fs_in.LODBase; for (int i=0; i<4; i++) { fsViewVertex += lambda[i] * fs_in.viewVertex[i]; diff --git a/Src/Graphics/New3D/R3DShaderTriangles.h b/Src/Graphics/New3D/R3DShaderTriangles.h index ee45bda..910ae78 100644 --- a/Src/Graphics/New3D/R3DShaderTriangles.h +++ b/Src/Graphics/New3D/R3DShaderTriangles.h @@ -8,6 +8,7 @@ static const char *vertexShaderR3D = R"glsl( // uniforms uniform float modelScale; uniform float nodeAlpha; +uniform float cota; uniform mat4 modelMat; uniform mat4 projMat; uniform bool translatorMap; @@ -28,7 +29,7 @@ out vec2 fsTexCoord; out vec4 fsColor; out float fsDiscard; // can't have varying bool (glsl spec) out float fsFixedShade; -out float fsTextureNP; +out float fsLODBase; vec4 GetColour(vec4 colour) { @@ -60,7 +61,7 @@ void main(void) fsColor = GetColour(inColour); fsTexCoord = inTexCoord; fsFixedShade = inFixedShade; - fsTextureNP = inTextureNP * modelScale; + fsLODBase = -fsDiscard * cota * inTextureNP; gl_Position = projMat * modelMat * inVertex; } )glsl"; @@ -119,7 +120,7 @@ in vec4 fsColor; in vec2 fsTexCoord; in float fsDiscard; in float fsFixedShade; -in float fsTextureNP; +in float fsLODBase; //outputs layout(location = 0) out vec4 out0; // opaque