Skip to content

Commit

Permalink
Merge remote-tracking branch 'greebo/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Mott committed Apr 12, 2022
2 parents 9a74899 + 70142f0 commit 7178fb1
Show file tree
Hide file tree
Showing 21 changed files with 260 additions and 156 deletions.
166 changes: 100 additions & 66 deletions install/gl/interaction_fp.glsl
Expand Up @@ -7,10 +7,11 @@ uniform sampler2D u_attenuationmap_xy;
uniform sampler2D u_attenuationmap_z;
uniform sampler2D u_ShadowMap;

uniform vec3 u_view_origin;
uniform vec3 u_light_origin;
uniform vec3 u_light_color;
uniform float u_light_scale;
uniform vec3 u_LocalViewOrigin;
uniform vec3 u_WorldUpLocal; // world 0,0,1 direction in local space
uniform vec3 u_LocalLightOrigin; // Light origin in local space
uniform vec3 u_LightColour; // the RGB colour as defined on the light entity
uniform float u_LightScale;
uniform vec4 u_ColourModulation;
uniform vec4 u_ColourAddition;
uniform mat4 u_ObjectTransform; // object to world
Expand All @@ -20,7 +21,7 @@ uniform vec4 u_ShadowMapRect; // x,y,w,h
uniform bool u_UseShadowMap;

// Activate ambient light mode (brightness unaffected by direction)
uniform bool uAmbientLight;
uniform bool u_IsAmbientLight;

// Texture coords as calculated by the vertex program
varying vec2 var_TexDiffuse;
Expand All @@ -32,6 +33,7 @@ varying vec4 var_tex_atten_xy_z;
varying mat3 var_mat_os2ts;
varying vec4 var_Colour; // colour to be multiplied on the final fragment
varying vec3 var_WorldLightDirection; // direction the light is coming from in world space
varying vec3 var_LocalViewerDirection; // viewer direction in local space

// Function ported from TDM tdm_shadowmaps.glsl, determining the cube map face for the given direction
vec3 CubeMapDirectionToUv(vec3 v, out int faceIdx)
Expand Down Expand Up @@ -92,77 +94,109 @@ float getDepthValueForVector(in sampler2D shadowMapTexture, vec4 shadowRect, vec

void main()
{
// Ported from TDM interaction.common.fs.glsl

vec4 fresnelParms = vec4(1.0, .23, .5, 1.0);
vec4 fresnelParms2 = vec4(.2, .023, 120.0, 4.0);
vec4 lightParms = vec4(.7, 1.8, 10.0, 30.0);
vec3 totalColor;

// Perform the texture lookups
vec4 diffuse = texture2D(u_Diffusemap, var_TexDiffuse);
vec3 specular = texture2D(u_Specularmap, var_TexSpecular).rgb;

// compute view direction in tangent space
vec3 localV = normalize(var_mat_os2ts * (u_view_origin - var_vertex));

// compute light direction in tangent space
vec3 localL = normalize(var_mat_os2ts * (u_light_origin - var_vertex));

vec4 bumpTexel = texture2D(u_Bumpmap, var_TexBump) * 2. - 1.;
vec3 RawN = normalize( bumpTexel.xyz );
vec3 N = var_mat_os2ts * RawN;

//must be done in tangent space, otherwise smoothing will suffer (see #4958)
float NdotL = clamp(dot(RawN, localL), 0.0, 1.0);
float NdotV = clamp(dot(RawN, localV), 0.0, 1.0);
float NdotH = clamp(dot(RawN, normalize(localV + localL)), 0.0, 1.0);

// fresnel part
float fresnelTerm = pow(1.0 - NdotV, fresnelParms2.w);
float rimLight = fresnelTerm * clamp(NdotL - 0.3, 0.0, fresnelParms.z) * lightParms.y;
float specularPower = mix(lightParms.z, lightParms.w, specular.z);
float specularCoeff = pow(NdotH, specularPower) * fresnelParms2.z;
float fresnelCoeff = fresnelTerm * fresnelParms.y + fresnelParms2.y;

vec3 specularColor = specularCoeff * fresnelCoeff * specular * (diffuse.rgb * 0.25 + vec3(0.75));
float R2f = clamp(localL.z * 4.0, 0.0, 1.0);
// Light texture lookups
vec3 attenuation_xy = vec3(0,0,0);

float NdotL_adjusted = NdotL;
float light = rimLight * R2f + NdotL_adjusted;

// compute attenuation
vec3 attenuation_xy = vec3(0.0, 0.0, 0.0);
if (var_tex_atten_xy_z.w > 0.0)
attenuation_xy = texture2DProj(
u_attenuationmap_xy,
var_tex_atten_xy_z.xyw
).rgb;

vec3 attenuation_z = texture2D(
u_attenuationmap_z, vec2(var_tex_atten_xy_z.z, 0.5)
).rgb;

vec3 totalColor = (specularColor * u_light_color * R2f + diffuse.rgb) * light * (u_light_color * u_light_scale) * attenuation_xy * attenuation_z * var_Colour.rgb;

if (u_UseShadowMap)
{
float shadowMapResolution = (textureSize(u_ShadowMap, 0).x * u_ShadowMapRect.w);

// The light direction is used to sample the shadow map texture
vec3 L = normalize(var_WorldLightDirection);

vec3 absL = abs(var_WorldLightDirection);
float maxAbsL = max(absL.x, max(absL.y, absL.z));
float centerFragZ = maxAbsL;

vec3 normal = mat3(u_ObjectTransform) * N;

float lightFallAngle = -dot(normal, L);
float errorMargin = 5.0 * maxAbsL / ( shadowMapResolution * max(lightFallAngle, 0.1) );
attenuation_xy = texture2DProj(u_attenuationmap_xy, var_tex_atten_xy_z.xyw).rgb;
}

float centerBlockerZ = getDepthValueForVector(u_ShadowMap, u_ShadowMapRect, L);
float lit = float(centerBlockerZ >= centerFragZ - errorMargin);
vec3 attenuation_z = texture2D(u_attenuationmap_z, vec2(var_tex_atten_xy_z.z, 0.5)).rgb;

totalColor *= lit;
if (!u_IsAmbientLight)
{
// Ported from TDM interaction.common.fs.glsl
vec4 fresnelParms = vec4(1.0, .23, .5, 1.0);
vec4 fresnelParms2 = vec4(.2, .023, 120.0, 4.0);
vec4 lightParms = vec4(.7, 1.8, 10.0, 30.0);

// compute view direction in tangent space
vec3 localV = normalize(var_mat_os2ts * (u_LocalViewOrigin - var_vertex));

// compute light direction in tangent space
vec3 localL = normalize(var_mat_os2ts * (u_LocalLightOrigin - var_vertex));

vec3 RawN = normalize(bumpTexel.xyz);
vec3 N = var_mat_os2ts * RawN;

//must be done in tangent space, otherwise smoothing will suffer (see #4958)
float NdotL = clamp(dot(RawN, localL), 0.0, 1.0);
float NdotV = clamp(dot(RawN, localV), 0.0, 1.0);
float NdotH = clamp(dot(RawN, normalize(localV + localL)), 0.0, 1.0);

// fresnel part
float fresnelTerm = pow(1.0 - NdotV, fresnelParms2.w);
float rimLight = fresnelTerm * clamp(NdotL - 0.3, 0.0, fresnelParms.z) * lightParms.y;
float specularPower = mix(lightParms.z, lightParms.w, specular.z);
float specularCoeff = pow(NdotH, specularPower) * fresnelParms2.z;
float fresnelCoeff = fresnelTerm * fresnelParms.y + fresnelParms2.y;

vec3 specularColor = specularCoeff * fresnelCoeff * specular * (diffuse.rgb * 0.25 + vec3(0.75));
float R2f = clamp(localL.z * 4.0, 0.0, 1.0);

float NdotL_adjusted = NdotL;
float light = rimLight * R2f + NdotL_adjusted;

// Combine everything to get the colour (unshadowed)
totalColor = (specularColor * u_LightColour * R2f + diffuse.rgb) * light * (u_LightColour * u_LightScale) * attenuation_xy * attenuation_z * var_Colour.rgb;

if (u_UseShadowMap)
{
float shadowMapResolution = (textureSize(u_ShadowMap, 0).x * u_ShadowMapRect.w);

// The light direction is used to sample the shadow map texture
vec3 L = normalize(var_WorldLightDirection);

vec3 absL = abs(var_WorldLightDirection);
float maxAbsL = max(absL.x, max(absL.y, absL.z));
float centerFragZ = maxAbsL;

vec3 normal = mat3(u_ObjectTransform) * N;

float lightFallAngle = -dot(normal, L);
float errorMargin = 5.0 * maxAbsL / ( shadowMapResolution * max(lightFallAngle, 0.1) );

float centerBlockerZ = getDepthValueForVector(u_ShadowMap, u_ShadowMapRect, L);
float lit = float(centerBlockerZ >= centerFragZ - errorMargin);

totalColor *= lit;
}
}
else
{
// Ported from TDM's interaction.ambient.fs
vec4 light = vec4(attenuation_xy * attenuation_z, 1);

vec3 localNormal = vec3(bumpTexel.x, bumpTexel.y, sqrt(max(1. - bumpTexel.x*bumpTexel.x - bumpTexel.y*bumpTexel.y, 0)));
vec3 N = normalize(var_mat_os2ts * localNormal);

vec3 light1 = vec3(.5); // directionless half
light1 += max(dot(N, u_WorldUpLocal) * (1. - specular) * .5, 0);

// Calculate specularity
vec3 nViewDir = normalize(var_LocalViewerDirection);
vec3 reflect = - (nViewDir - 2 * N * dot(N, nViewDir));

float spec = max(dot(reflect, u_WorldUpLocal), 0);
float specPow = clamp((spec * spec), 0.0, 1.1);
light1 += vec3(spec * specPow * specPow) * specular * 1.0;

// Apply the light's colour (with light scale) and the vertex colour
light1.rgb *= (u_LightColour * u_LightScale) * var_Colour.rgb;

light.rgb *= diffuse.rgb * light1;

light = max(light, vec4(0)); // avoid negative values, which with floating point render buffers can lead to NaN artefacts

totalColor = light.rgb;
}

gl_FragColor.rgb = totalColor;
Expand Down
5 changes: 5 additions & 0 deletions install/gl/interaction_vp.glsl
Expand Up @@ -12,6 +12,7 @@ uniform vec4 u_ColourAddition; // constant additive vertex colour value
uniform mat4 u_ModelViewProjection; // combined modelview and projection matrix
uniform mat4 u_ObjectTransform; // object to world
uniform vec3 u_WorldLightOrigin; // light origin in world space
uniform vec3 u_LocalViewOrigin; // view origin in local space

// Texture Matrices (the two top rows of each)
uniform vec4 u_DiffuseTextureMatrix[2];
Expand All @@ -31,6 +32,7 @@ varying vec4 var_tex_atten_xy_z;
varying mat3 var_mat_os2ts;
varying vec4 var_Colour; // colour to be multiplied on the final fragment
varying vec3 var_WorldLightDirection; // direction the light is coming from in world space
varying vec3 var_LocalViewerDirection; // viewer direction in local space

void main()
{
Expand Down Expand Up @@ -65,6 +67,9 @@ void main()
attr_Tangent.z, attr_Bitangent.z, attr_Normal.z
);

// Calculate the viewer direction in local space (attr_Position is already in local space)
var_LocalViewerDirection = u_LocalViewOrigin - attr_Position.xyz;

// Vertex colour factor
var_Colour = (attr_Colour * u_ColourModulation + u_ColourAddition);
}
Expand Down
41 changes: 41 additions & 0 deletions install/scripts/commands/count_loot.py
@@ -0,0 +1,41 @@
__commandName__ = 'CountLoot'
__commandDisplayName__ = 'Count Loot'

def execute():
import darkradiant as dr

class SceneLootCounter(dr.SceneNodeVisitor):
loot_sum = 0
def pre(self, node):
entity = node.getEntity()
if not entity.isNull():
try:
self.loot_sum += int(entity.getKeyValue("inv_loot_value"))
except:
pass
return 1

class SelectionLootCounter(dr.SelectionVisitor):
loot_sum = 0
def visit(self, node):
entity = node.getEntity()
if not entity.isNull():
try:
self.loot_sum += int(entity.getKeyValue("inv_loot_value"))
except:
pass

scene_counter = SceneLootCounter()
GlobalSceneGraph.root().traverse(scene_counter)

selection_counter = SelectionLootCounter()
GlobalSelectionSystem.foreachSelected(selection_counter)

result = "Total loot: " + str(scene_counter.loot_sum)
if selection_counter.loot_sum > 0:
result += "\nSelection: " + str(selection_counter.loot_sum)

GlobalDialogManager.createMessageBox("Loot Count Results", result, dr.Dialog.CONFIRM).run()

if __executeCommand__:
execute()
2 changes: 0 additions & 2 deletions libs/module/StaticModule.cpp
Expand Up @@ -19,8 +19,6 @@ void StaticModuleList::RegisterModules()
{
module::GlobalModuleRegistry().registerModule(creationFunc());
}

Instance().clear(); // clear the static list after dispatching all modules
}

StaticModuleList& StaticModuleList::Instance()
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/CMakeLists.txt
Expand Up @@ -220,7 +220,7 @@ add_library(radiantcore MODULE
rendersystem/backend/glprogram/ShadowMapProgram.cpp
rendersystem/backend/BuiltInShader.cpp
rendersystem/backend/ColourShader.cpp
rendersystem/backend/LightInteractions.cpp
rendersystem/backend/InteractingLight.cpp
rendersystem/backend/SceneRenderer.cpp
rendersystem/backend/FullBrightRenderer.cpp
rendersystem/backend/LightingModeRenderer.cpp
Expand Down
25 changes: 15 additions & 10 deletions radiantcore/patch/PatchNode.cpp
Expand Up @@ -344,15 +344,10 @@ void PatchNode::onPreRender(const VolumeTest& volume)
m_patch.evaluateTransform();
m_patch.updateTesselation();

if (volume.fill())
{
_renderableSurfaceSolid.update(m_patch._shader.getGLShader());
_renderableSurfaceSolid.attachToEntity(_renderEntity);
}
else
{
_renderableSurfaceWireframe.update(_renderEntity->getWireShader());
}
_renderableSurfaceSolid.update(m_patch._shader.getGLShader());
_renderableSurfaceWireframe.update(_renderEntity->getWireShader());

_renderableSurfaceSolid.attachToEntity(_renderEntity);

if (isSelected() && GlobalSelectionSystem().ComponentMode() == selection::ComponentSelectionMode::Vertex)
{
Expand All @@ -373,7 +368,17 @@ void PatchNode::onPreRender(const VolumeTest& volume)

void PatchNode::renderHighlights(IRenderableCollector& collector, const VolumeTest& volume)
{
// Overlay the selected node with the quadrangulated wireframe
if (GlobalSelectionSystem().Mode() != selection::SelectionSystem::eComponent)
{
// The coloured selection overlay should use the same triangulated surface to avoid z fighting
collector.setHighlightFlag(IRenderableCollector::Highlight::Faces, true);
collector.setHighlightFlag(IRenderableCollector::Highlight::Primitives, false);
collector.addHighlightRenderable(_renderableSurfaceSolid, localToWorld());
}

// The selection outline (wireframe) should use the quadrangulated surface
collector.setHighlightFlag(IRenderableCollector::Highlight::Faces, false);
collector.setHighlightFlag(IRenderableCollector::Highlight::Primitives, true);
collector.addHighlightRenderable(_renderableSurfaceWireframe, localToWorld());
}

Expand Down
12 changes: 11 additions & 1 deletion radiantcore/rendersystem/OpenGLRenderSystem.cpp
Expand Up @@ -11,7 +11,6 @@
#include "backend/GLProgramFactory.h"
#include "backend/BuiltInShader.h"
#include "backend/ColourShader.h"
#include "backend/LightInteractions.h"
#include "backend/LightingModeRenderer.h"
#include "backend/FullBrightRenderer.h"
#include "backend/ObjectRenderer.h"
Expand Down Expand Up @@ -170,6 +169,17 @@ IRenderResult::Ptr OpenGLRenderSystem::renderLitScene(RenderStateFlags globalFla

IRenderResult::Ptr OpenGLRenderSystem::render(SceneRenderer& renderer, RenderStateFlags globalFlagsMask, const IRenderView& view)
{
const auto viewType = renderer.getViewType();

// Make sure all shaders are ready for rendering, submitting their data to the store
for (const auto& [_, shader] : _shaders)
{
if (shader->isApplicableTo(viewType))
{
shader->prepareForRendering();
}
}

auto result = renderer.render(globalFlagsMask, view, _time);

renderText();
Expand Down
6 changes: 5 additions & 1 deletion radiantcore/rendersystem/backend/BufferObjectProvider.h
Expand Up @@ -28,7 +28,11 @@ class BufferObjectProvider final :

~BufferObject()
{
glDeleteBuffers(1, &_buffer);
if (_buffer != 0)
{
glDeleteBuffers(1, &_buffer);
}

_buffer = 0;
}

Expand Down
9 changes: 0 additions & 9 deletions radiantcore/rendersystem/backend/FullBrightRenderer.cpp
Expand Up @@ -30,15 +30,6 @@ class FullBrightRenderResult :

IRenderResult::Ptr FullBrightRenderer::render(RenderStateFlags globalstate, const IRenderView& view, std::size_t time)
{
// Make sure all the geometry is ready for rendering
for (const auto& [_, pass] : _sortedStates)
{
if (pass->isApplicableTo(_renderViewType))
{
pass->getShader().prepareForRendering();
}
}

// Make sure all the data is uploaded
_geometryStore.syncToBufferObjects();

Expand Down
3 changes: 1 addition & 2 deletions radiantcore/rendersystem/backend/FullBrightRenderer.h
Expand Up @@ -10,13 +10,12 @@ class FullBrightRenderer final :
public SceneRenderer
{
private:
RenderViewType _renderViewType;
const OpenGLStates& _sortedStates;
IGeometryStore& _geometryStore;

public:
FullBrightRenderer(RenderViewType renderViewType, const OpenGLStates& sortedStates, IGeometryStore& geometryStore) :
_renderViewType(renderViewType),
SceneRenderer(renderViewType),
_sortedStates(sortedStates),
_geometryStore(geometryStore)
{}
Expand Down

0 comments on commit 7178fb1

Please sign in to comment.