1
0
forked from 0ad/0ad

Moves terrain lighting calculation to GPU.

Reviewed By: wraitii
Tested By: OptimusShepard, Stan, wraitii
Differential Revision: https://code.wildfiregames.com/D3052
This was SVN commit r24124.
This commit is contained in:
Vladislav Belov 2020-11-04 12:54:17 +00:00
parent 770280436b
commit d7d02a4740
15 changed files with 46 additions and 108 deletions

View File

@ -7,18 +7,19 @@
<uniform name="losTransform" loc="2" type="vec2"/>
<uniform name="shadowTransform" loc="3" type="mat4"/>
<uniform name="shadowScale" loc="7" type="vec4"/>
<uniform name="sunDir" loc="8" type="vec4"/>
<stream name="pos"/>
<stream name="color"/>
<stream name="normal"/>
<stream name="uv0"/>
<stream name="uv1" if="BLEND"/>
<stream name="uv1" if="BLEND"/>
</vertex>
<fragment file="arb/terrain_common.fp">
<uniform name="baseTex" loc="0" type="sampler2D"/>
<uniform name="blendTex" loc="1" type="sampler2D" if="BLEND"/>
<uniform name="blendTex" loc="1" type="sampler2D" if="BLEND"/>
<uniform name="shadowTex" loc="2" type="sampler2DShadow"/>
<uniform name="losTex" loc="3" type="sampler2D"/>
<uniform name="shadingColor" loc="1" type="vec3" if="DECAL"/>
<uniform name="shadingColor" loc="1" type="vec3" if="DECAL"/>
<uniform name="ambient" loc="0" type="vec3"/>
<uniform name="shadowScale" loc="2" type="vec4"/>
</fragment>

View File

@ -9,8 +9,9 @@
<uniform name="losTransform" loc="2" type="vec2"/>
<uniform name="shadowTransform" loc="3" type="mat4"/>
<uniform name="shadowScale" loc="7" type="vec4"/>
<uniform name="sunDir" loc="8" type="vec4"/>
<stream name="pos"/>
<stream name="color"/>
<stream name="normal"/>
<stream name="uv0"/>
<stream name="uv1"/>
</vertex>

View File

@ -3,6 +3,7 @@ PARAM sunColor = program.local[0];
PARAM textureTransform = program.local[1];
PARAM losTransform = program.local[2];
PARAM shadowTransform[4] = { program.local[3..6] };
PARAM sunDir = program.local[8];
#if USE_FP_SHADOW && USE_SHADOW_PCF
PARAM shadowScale = program.local[7];
@ -23,7 +24,10 @@ DP4 result.position.w, state.matrix.mvp.row[3], position;
// Diffuse factor is precomputed in vertex attribute
// Scale diffuse to allow overbrightness (since result.color will be clamped to [0, 1])
MUL lighting, vertex.color, 0.5;
//
DP3 lighting, -sunDir, vertex.normal;
MAX lighting, 0.0, lighting; // DP3_SAT isn't available here.
MUL lighting, lighting, 0.5;
// Apply light color
MUL result.color, lighting, sunColor;
@ -51,7 +55,7 @@ MUL result.color, lighting, sunColor;
DP4 shadowtc.x, shadowTransform[0], position;
DP4 shadowtc.y, shadowTransform[1], position;
MUL result.texcoord[2].xy, shadowtc, shadowScale;
#else
#else
DP4 result.texcoord[2].x, shadowTransform[0], position;
DP4 result.texcoord[2].y, shadowTransform[1], position;
#endif

View File

@ -9,8 +9,9 @@
<uniform name="losTransform" loc="2" type="vec2"/>
<uniform name="shadowTransform" loc="3" type="mat4"/>
<uniform name="shadowScale" loc="7" type="vec4"/>
<uniform name="sunDir" loc="8" type="vec4"/>
<stream name="pos"/>
<stream name="color"/>
<stream name="normal"/>
<stream name="uv0"/>
</vertex>

View File

@ -3,14 +3,12 @@
<vertex file="glsl/terrain_common.vs">
<stream name="pos"/>
<stream name="color"/>
<stream name="uv0"/>
<stream name="uv1" if="BLEND"/>
<stream name="uv1" if="BLEND"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
<attrib name="a_normal" semantics="gl_Normal"/>
<attrib name="a_color" semantics="gl_Color"/>
<attrib name="a_normal" semantics="gl_Normal"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
<attrib name="a_uv1" semantics="gl_MultiTexCoord1" if="BLEND"/>
<attrib name="a_uv1" semantics="gl_MultiTexCoord1" if="BLEND"/>
</vertex>
<fragment file="glsl/terrain_common.fs"/>

View File

@ -5,11 +5,9 @@
<vertex file="glsl/terrain_common.vs">
<stream name="pos"/>
<stream name="color"/>
<stream name="uv0"/>
<stream name="uv1"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
<attrib name="a_color" semantics="gl_Color"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
<attrib name="a_uv1" semantics="gl_MultiTexCoord1"/>
</vertex>

View File

@ -205,7 +205,7 @@ void main()
#endif
normal = normalize(tbn * ntex);
vec3 bumplight = max(dot(-sunDir, normal), 0.0) * sunColor;
vec3 sundiffuse = (bumplight - v_lighting.rgb) * effectSettings.x + v_lighting.rgb;
vec3 sundiffuse = (bumplight - v_lighting.rgb) * effectSettings.x + v_lighting.rgb;
#else
vec3 sundiffuse = v_lighting;
#endif

View File

@ -47,7 +47,6 @@ varying vec3 v_normal;
attribute vec3 a_vertex;
attribute vec3 a_normal;
attribute vec3 a_color;
attribute vec2 a_uv0;
attribute vec2 a_uv1;
@ -61,8 +60,8 @@ void main()
gl_Position = transform * position;
v_lighting = a_color * sunColor;
v_lighting = clamp(-dot(a_normal, sunDir), 0.0, 1.0) * sunColor;
#if DECAL
v_tex.xy = a_uv0;
#else
@ -94,9 +93,9 @@ void main()
v_shadow = shadowTransform * vec4(a_vertex, 1.0);
#if USE_SHADOW_SAMPLER && USE_SHADOW_PCF
v_shadow.xy *= shadowScale.xy;
#endif
#endif
#endif
v_normal = a_normal;
#if USE_SPECULAR || USE_NORMAL_MAP || USE_SPECULAR_MAP || USE_TRIPLANAR

View File

@ -6,11 +6,9 @@
<vertex file="glsl/terrain_common.vs">
<stream name="pos"/>
<stream name="normal"/>
<stream name="color"/>
<stream name="uv0"/>
<attrib name="a_vertex" semantics="gl_Vertex"/>
<attrib name="a_normal" semantics="gl_Normal"/>
<attrib name="a_color" semantics="gl_Color"/>
<attrib name="a_uv0" semantics="gl_MultiTexCoord0"/>
</vertex>

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games.
/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -74,30 +74,6 @@ public:
return color * 0.5f;
}
/**
* Compute the diffuse sun lighting color on terrain, for rendering with CPU lighting.
* To cope with sun overbrightness, the color is scaled by 0.5.
*
* @param normal normal vector (must have length 1)
*/
SColor4ub EvaluateTerrainDiffuseScaled(const CVector3D& normal) const
{
float dot = -normal.Dot(m_SunDir);
return ConvertRGBColorTo4ub(m_SunColor * dot * 0.5f);
}
/**
* Compute the diffuse sun lighting factor on terrain, for rendering with shader lighting.
*
* @param normal normal vector (must have length 1)
*/
SColor4ub EvaluateTerrainDiffuseFactor(const CVector3D& normal) const
{
float dot = -normal.Dot(m_SunDir);
u8 c = static_cast<u8>(Clamp(dot * 255.f, 0.f, 255.f));
return SColor4ub(c, c, c, 255);
}
// Comparison operators
bool operator==(const CLightEnv& o) const
{

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games.
/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -20,7 +20,6 @@
#include "DecalRData.h"
#include "graphics/Decal.h"
#include "graphics/LightEnv.h"
#include "graphics/Model.h"
#include "graphics/ShaderManager.h"
#include "graphics/Terrain.h"
@ -49,10 +48,6 @@ CDecalRData::CDecalRData(CModelDecal* decal, CSimulation2* simulation)
m_Normal.elems = 3;
m_Array.AddAttribute(&m_Normal);
m_DiffuseColor.type = GL_UNSIGNED_BYTE;
m_DiffuseColor.elems = 4;
m_Array.AddAttribute(&m_DiffuseColor);
m_UV.type = GL_FLOAT;
m_UV.elems = 2;
m_Array.AddAttribute(&m_UV);
@ -166,7 +161,6 @@ void CDecalRData::RenderDecals(std::vector<CDecalRData*>& decals, const CShaderD
shader->VertexPointer(3, GL_FLOAT, stride, base + decal->m_Position.offset);
shader->NormalPointer(GL_FLOAT, stride, base + decal->m_Normal.offset);
shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, base + decal->m_DiffuseColor.offset);
shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, stride, base + decal->m_UV.offset);
shader->AssertPointersBound();
@ -213,12 +207,8 @@ void CDecalRData::BuildArrays()
m_Array.Layout();
VertexArrayIterator<CVector3D> Position = m_Position.GetIterator<CVector3D>();
VertexArrayIterator<CVector3D> Normal = m_Normal.GetIterator<CVector3D>();
VertexArrayIterator<SColor4ub> DiffuseColor = m_DiffuseColor.GetIterator<SColor4ub>();
VertexArrayIterator<float[2]> UV = m_UV.GetIterator<float[2]>();
const CLightEnv& lightEnv = g_Renderer.GetLightEnv();
bool cpuLighting = (g_RenderingOptions.GetRenderPath() == RenderPath::FIXED);
for (ssize_t j = j0; j <= j1; ++j)
{
for (ssize_t i = i0; i <= i1; ++i)
@ -237,9 +227,6 @@ void CDecalRData::BuildArrays()
*Normal = normal;
Normal++;
*DiffuseColor = cpuLighting ? lightEnv.EvaluateTerrainDiffuseScaled(normal) : lightEnv.EvaluateTerrainDiffuseFactor(normal);
++DiffuseColor;
// Map from world space back into decal texture space
CVector3D inv = m_Decal->GetInvTransform().Transform(pos);
(*UV)[0] = 0.5f + (inv.X - decal.m_OffsetX) / decal.m_SizeX;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015 Wildfire Games.
/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -49,7 +49,6 @@ private:
VertexArray m_Array;
VertexArray::Attribute m_Position;
VertexArray::Attribute m_Normal;
VertexArray::Attribute m_DiffuseColor;
VertexArray::Attribute m_UV;
CModelDecal* m_Decal;

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games.
/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -367,17 +367,13 @@ void CPatchRData::AddBlend(std::vector<SBlendVertex>& blendVertices, std::vector
SBlendVertex dst;
const CLightEnv& lightEnv = g_Renderer.GetLightEnv();
CVector3D normal;
bool cpuLighting = (g_RenderingOptions.GetRenderPath() == RenderPath::FIXED);
size_t index = blendVertices.size();
terrain->CalcPosition(gx, gz, dst.m_Position);
terrain->CalcNormal(gx, gz, normal);
dst.m_Normal = normal;
dst.m_DiffuseColor = cpuLighting ? lightEnv.EvaluateTerrainDiffuseScaled(normal) : lightEnv.EvaluateTerrainDiffuseFactor(normal);
dst.m_AlphaUVs[0] = vtx[0].m_AlphaUVs[0];
dst.m_AlphaUVs[1] = vtx[0].m_AlphaUVs[1];
blendVertices.push_back(dst);
@ -385,7 +381,6 @@ void CPatchRData::AddBlend(std::vector<SBlendVertex>& blendVertices, std::vector
terrain->CalcPosition(gx + 1, gz, dst.m_Position);
terrain->CalcNormal(gx + 1, gz, normal);
dst.m_Normal = normal;
dst.m_DiffuseColor = cpuLighting ? lightEnv.EvaluateTerrainDiffuseScaled(normal) : lightEnv.EvaluateTerrainDiffuseFactor(normal);
dst.m_AlphaUVs[0] = vtx[1].m_AlphaUVs[0];
dst.m_AlphaUVs[1] = vtx[1].m_AlphaUVs[1];
blendVertices.push_back(dst);
@ -393,7 +388,6 @@ void CPatchRData::AddBlend(std::vector<SBlendVertex>& blendVertices, std::vector
terrain->CalcPosition(gx + 1, gz + 1, dst.m_Position);
terrain->CalcNormal(gx + 1, gz + 1, normal);
dst.m_Normal = normal;
dst.m_DiffuseColor = cpuLighting ? lightEnv.EvaluateTerrainDiffuseScaled(normal) : lightEnv.EvaluateTerrainDiffuseFactor(normal);
dst.m_AlphaUVs[0] = vtx[2].m_AlphaUVs[0];
dst.m_AlphaUVs[1] = vtx[2].m_AlphaUVs[1];
blendVertices.push_back(dst);
@ -401,7 +395,6 @@ void CPatchRData::AddBlend(std::vector<SBlendVertex>& blendVertices, std::vector
terrain->CalcPosition(gx, gz + 1, dst.m_Position);
terrain->CalcNormal(gx, gz + 1, normal);
dst.m_Normal = normal;
dst.m_DiffuseColor = cpuLighting ? lightEnv.EvaluateTerrainDiffuseScaled(normal) : lightEnv.EvaluateTerrainDiffuseFactor(normal);
dst.m_AlphaUVs[0] = vtx[3].m_AlphaUVs[0];
dst.m_AlphaUVs[1] = vtx[3].m_AlphaUVs[1];
blendVertices.push_back(dst);
@ -533,39 +526,32 @@ void CPatchRData::BuildVertices()
// create both vertices and lighting colors
// number of vertices in each direction in each patch
ssize_t vsize=PATCH_SIZE+1;
ssize_t vsize = PATCH_SIZE + 1;
std::vector<SBaseVertex> vertices;
vertices.resize(vsize*vsize);
vertices.resize(vsize * vsize);
// get index of this patch
ssize_t px=m_Patch->m_X;
ssize_t pz=m_Patch->m_Z;
ssize_t px = m_Patch->m_X;
ssize_t pz = m_Patch->m_Z;
CTerrain* terrain=m_Patch->m_Parent;
const CLightEnv& lightEnv = g_Renderer.GetLightEnv();
bool cpuLighting = (g_RenderingOptions.GetRenderPath() == RenderPath::FIXED);
CTerrain* terrain = m_Patch->m_Parent;
// build vertices
for (ssize_t j=0;j<vsize;j++) {
for (ssize_t i=0;i<vsize;i++) {
ssize_t ix=px*PATCH_SIZE+i;
ssize_t iz=pz*PATCH_SIZE+j;
ssize_t v=(j*vsize)+i;
for (ssize_t j = 0; j < vsize; ++j)
{
for (ssize_t i = 0; i < vsize; ++i)
{
ssize_t ix = px * PATCH_SIZE + i;
ssize_t iz = pz * PATCH_SIZE + j;
ssize_t v = j * vsize + i;
// calculate vertex data
terrain->CalcPosition(ix,iz,vertices[v].m_Position);
terrain->CalcPosition(ix, iz, vertices[v].m_Position);
// Calculate diffuse lighting for this vertex
// Ambient is added by the lighting pass (since ambient is the same
// for all vertices, it need not be stored in the vertex structure)
CVector3D normal;
terrain->CalcNormal(ix,iz,normal);
terrain->CalcNormal(ix, iz, normal);
vertices[v].m_Normal = normal;
vertices[v].m_DiffuseColor = cpuLighting ? lightEnv.EvaluateTerrainDiffuseScaled(normal) : lightEnv.EvaluateTerrainDiffuseFactor(normal);
}
}
@ -828,7 +814,6 @@ void CPatchRData::RenderBases(const std::vector<CPatchRData*>& patches, const CS
GLsizei stride = sizeof(SBaseVertex);
SBaseVertex *base = (SBaseVertex *)itv->first->Bind();
shader->VertexPointer(3, GL_FLOAT, stride, &base->m_Position[0]);
shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, &base->m_DiffuseColor);
shader->NormalPointer(GL_FLOAT, stride, &base->m_Normal[0]);
shader->TexCoordPointer(GL_TEXTURE0, 3, GL_FLOAT, stride, &base->m_Position[0]);
@ -1067,7 +1052,6 @@ void CPatchRData::RenderBlends(const std::vector<CPatchRData*>& patches, const C
SBlendVertex *base = (SBlendVertex *)itv->first->Bind();
shader->VertexPointer(3, GL_FLOAT, stride, &base->m_Position[0]);
shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, &base->m_DiffuseColor);
shader->NormalPointer(GL_FLOAT, stride, &base->m_Normal[0]);
shader->TexCoordPointer(GL_TEXTURE0, 3, GL_FLOAT, stride, &base->m_Position[0]);
shader->TexCoordPointer(GL_TEXTURE1, 2, GL_FLOAT, stride, &base->m_AlphaUVs[0]);
@ -1143,7 +1127,7 @@ void CPatchRData::RenderStreams(const std::vector<CPatchRData*>& patches, const
PROFILE_END("compute batches");
ENSURE(!(streamflags & ~(STREAM_POS|STREAM_COLOR|STREAM_POSTOUV0|STREAM_POSTOUV1)));
ENSURE(!(streamflags & ~(STREAM_POS|STREAM_POSTOUV0|STREAM_POSTOUV1)));
// Render each batch
for (VertexBufferBatches::iterator itv = batches.begin(); itv != batches.end(); ++itv)
@ -1156,8 +1140,6 @@ void CPatchRData::RenderStreams(const std::vector<CPatchRData*>& patches, const
shader->TexCoordPointer(GL_TEXTURE0, 3, GL_FLOAT, stride, &base->m_Position);
if (streamflags & STREAM_POSTOUV1)
shader->TexCoordPointer(GL_TEXTURE1, 3, GL_FLOAT, stride, &base->m_Position);
if (streamflags & STREAM_COLOR)
shader->ColorPointer(4, GL_UNSIGNED_BYTE, stride, &base->m_DiffuseColor);
shader->AssertPointersBound();

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games.
/* Copyright (C) 2020 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -80,11 +80,9 @@ private:
struct SBaseVertex {
// vertex position
CVector3D m_Position;
// diffuse color from sunlight
SColor4ub m_DiffuseColor;
CVector3D m_Normal;
// pad to a power of two
u8 m_Padding[4];
u8 m_Padding[8];
};
cassert(sizeof(SBaseVertex) == 32);
@ -99,15 +97,11 @@ private:
struct SBlendVertex {
// vertex position
CVector3D m_Position;
// diffuse color from sunlight
SColor4ub m_DiffuseColor;
// vertex uvs for alpha texture
float m_AlphaUVs[2];
CVector3D m_Normal;
// pad to a power of two
u8 m_Padding[28];
};
cassert(sizeof(SBlendVertex) == 64);
cassert(sizeof(SBlendVertex) == 32);
// Mixed Fancy/Simple water vertex description data structure
struct SWaterVertex {

View File

@ -320,7 +320,7 @@ void TerrainRenderer::RenderTerrainFixed(int cullGroup)
CLOSTexture& losTexture = g_Renderer.GetScene().GetLOSTexture();
int streamflags = STREAM_POS|STREAM_COLOR;
int streamflags = STREAM_POS;
pglActiveTextureARB(GL_TEXTURE0);
// We're not going to use a texture here, but we have to have a valid texture