Added support for zones defining a texture (either cube or 3D), that will be available in pixel shaders when rendering objects inside the zone.

This commit is contained in:
Lasse Öörni 2014-07-16 16:27:15 +03:00
Родитель 3c77988d37
Коммит e82b3d53a1
14 изменённых файлов: 75 добавлений и 9 удалений

Просмотреть файл

@ -18,6 +18,8 @@ uniform samplerCube sLightCubeMap;
uniform sampler2DShadow sShadowMap;
uniform samplerCube sFaceSelectCubeMap;
uniform samplerCube sIndirectionCubeMap;
uniform samplerCube sZoneCubeMap;
uniform sampler3D sZoneVolumeMap;
#else
uniform sampler2D sShadowMap;
#endif

Просмотреть файл

@ -17,6 +17,8 @@ samplerCUBE sIndirectionCubeMap : register(S9);
sampler2D sDepthBuffer : register(S10);
sampler2D sLightBuffer : register(S11);
sampler3D sVolumeMap : register(S12);
samplerCUBE sZoneCubeMap : register(S13);
sampler3D sZoneVolumeMap : register(S13);
float4 Sample(sampler2D map, float2 texCoord)
{

Просмотреть файл

@ -898,6 +898,7 @@ void InitResourcePicker()
resourcePickers.Push(ResourcePicker("Technique", "*.xml"));
resourcePickers.Push(ResourcePicker("Texture2D", textureFilters));
resourcePickers.Push(ResourcePicker("TextureCube", "*.xml"));
resourcePickers.Push(ResourcePicker("Texture3D", "*.xml"));
resourcePickers.Push(ResourcePicker("XMLFile", "*.xml"));
resourcePickers.Push(ResourcePicker("Sprite2D", textureFilters, ACTION_PICK | ACTION_OPEN));
resourcePickers.Push(ResourcePicker("AnimationSet2D", anmSetFilters, ACTION_PICK | ACTION_OPEN));
@ -1034,10 +1035,25 @@ void StoreResourcePickerPath()
Resource@ GetPickedResource(String resourceName)
{
resourceName = GetResourceNameFromFullName(resourceName);
Resource@ res = cache.GetResource(resourcePicker.typeName, resourceName);
String type = resourcePicker.typeName;
// Cube and 3D textures both use .xml extension. In that case interrogate the proper resource type
// from the file itself
if (type == "Texture3D" || type == "TextureCube")
{
XMLFile@ xmlRes = cache.GetResource("XMLFile", resourceName);
if (xmlRes !is null)
{
if (xmlRes.root.name.Compare("cubemap", false) == 0 || xmlRes.root.name.Compare("texturecube", false) == 0)
type = "TextureCube";
else if (xmlRes.root.name.Compare("texture3d", false) == 0)
type = "Texture3D";
}
}
Resource@ res = cache.GetResource(type, resourceName);
if (res is null)
log.Warning("Cannot find resource type: " + resourcePicker.typeName + " Name:" + resourceName);
log.Warning("Cannot find resource type: " + type + " Name:" + resourceName);
return res;
}

Просмотреть файл

@ -1341,8 +1341,9 @@ Zones have three special flags: height fog mode, override mode and ambient gradi
- If the camera is inside a zone with override mode enabled, all rendered objects will use that zone's ambient and fog settings, instead of the zone they belong to. This can be used for example to implement an underwater effect.
- When ambient gradient mode is enabled, the zone's own ambient color value is not used, but instead it will look for two highest-priority neighbor zones that touch it at the minimum and maximum Z face of its oriented bounding box: any objects inside will then get a per-vertex ambient color fade between the neighbor zones' ambient colors. To ensure objects use the gradient zone when inside it, the gradient zone should have higher priority than the neighbor zones. The gradient is always oriented along the gradient zone's local Z axis.
Zones also define a lightmask and a shadowmask (with all bits set by default.) An object's final lightmask for light culling is determined by ANDing the object lightmask and the zone lightmask. The final shadowmask is also calculated in the same way.
Like lights, zones also define a lightmask and a shadowmask (with all bits set by default.) An object's final lightmask for light culling is determined by ANDing the object lightmask and the zone lightmask. The final shadowmask is also calculated in the same way.
Finally, zones can optionally define a texture, see \ref Zone::SetZoneTexture "SetZoneTexture()". This should be either a cube or 3D texture that will be bound to the zone texture unit (TU_ZONE) when rendering objects within the zone. This could be used to achieve for example precomputed environment reflections, ambient lighting or ambient occlusion in custom shaders; the default shaders do not use this texture. Due to texture unit limitations it is not available on OpenGL ES 2.0.
\page AuxiliaryViews Auxiliary views

Просмотреть файл

@ -588,6 +588,10 @@ void Batch::Prepare(View* view, bool setModelTransform) const
graphics->SetTexture(TU_LIGHTSHAPE, shapeTexture);
}
}
// Set zone texture if necessary
if (zone_ && graphics->HasTextureUnit(TU_ZONE))
graphics->SetTexture(TU_ZONE, zone_->GetZoneTexture());
}
void Batch::Draw(View* view) const

Просмотреть файл

@ -2766,6 +2766,8 @@ void Graphics::SetTextureUnitMappings()
textureUnits_["FaceSelectCubeMap"] = TU_FACESELECT;
textureUnits_["IndirectionCubeMap"] = TU_INDIRECTION;
textureUnits_["VolumeMap"] = TU_VOLUMEMAP;
textureUnits_["ZoneCubeMap"] = TU_ZONE;
textureUnits_["ZoneVolumeMap"] = TU_ZONE;
}
void RegisterGraphicsLibrary(Context* context)

Просмотреть файл

@ -230,7 +230,8 @@ enum TextureUnit
TU_DEPTHBUFFER = 10,
TU_LIGHTBUFFER = 11,
TU_VOLUMEMAP = 12,
MAX_TEXTURE_UNITS = 13
TU_ZONE = 13,
MAX_TEXTURE_UNITS = 14
};
/// Billboard camera facing modes.

Просмотреть файл

@ -25,14 +25,12 @@
#include "Color.h"
#include "Drawable.h"
#include "Frustum.h"
#include "Texture.h"
namespace Urho3D
{
class Camera;
class Texture;
class Texture2D;
class TextureCube;
struct LightBatchQueue;
/// %Light types.

Просмотреть файл

@ -2954,6 +2954,8 @@ void Graphics::SetTextureUnitMappings()
textureUnits_["DepthBuffer"] = TU_DEPTHBUFFER;
textureUnits_["LightBuffer"] = TU_LIGHTBUFFER;
textureUnits_["VolumeMap"] = TU_VOLUMEMAP;
textureUnits_["ZoneCubeMap"] = TU_ZONE;
textureUnits_["ZoneVolumeMap"] = TU_ZONE;
}
void RegisterGraphicsLibrary(Context* context)

Просмотреть файл

@ -25,7 +25,9 @@
#include "DebugRenderer.h"
#include "Node.h"
#include "Octree.h"
#include "ResourceCache.h"
#include "Scene.h"
#include "TextureCube.h"
#include "Zone.h"
#include "DebugNew.h"
@ -82,6 +84,7 @@ void Zone::RegisterObject(Context* context)
ATTRIBUTE(Zone, VAR_BOOL, "Override Mode", override_, false, AM_DEFAULT);
ATTRIBUTE(Zone, VAR_BOOL, "Ambient Gradient", ambientGradient_, false, AM_DEFAULT);
ATTRIBUTE(Zone, VAR_INT, "Priority", priority_, 0, AM_DEFAULT);
ACCESSOR_ATTRIBUTE(Zone, VAR_RESOURCEREF, "Zone Texture", GetZoneTextureAttr, SetZoneTextureAttr, ResourceRef, ResourceRef(TextureCube::GetTypeStatic()), AM_DEFAULT);
ATTRIBUTE(Zone, VAR_INT, "Light Mask", lightMask_, DEFAULT_LIGHTMASK, AM_DEFAULT);
ATTRIBUTE(Zone, VAR_INT, "Shadow Mask", shadowMask_, DEFAULT_SHADOWMASK, AM_DEFAULT);
ACCESSOR_ATTRIBUTE(Zone, VAR_INT, "Zone Mask", GetZoneMask, SetZoneMask, unsigned, DEFAULT_ZONEMASK, AM_DEFAULT);
@ -158,6 +161,12 @@ void Zone::SetPriority(int priority)
MarkNetworkUpdate();
}
void Zone::SetZoneTexture(Texture* texture)
{
zoneTexture_ = texture;
MarkNetworkUpdate();
}
void Zone::SetHeightFog(bool enable)
{
heightFog_ = enable;
@ -216,6 +225,17 @@ bool Zone::IsInside(const Vector3& point) const
return boundingBox_.IsInside(localPoint) != OUTSIDE;
}
void Zone::SetZoneTextureAttr(ResourceRef value)
{
ResourceCache* cache = GetSubsystem<ResourceCache>();
zoneTexture_ = static_cast<Texture*>(cache->GetResource(value.type_, value.name_));
}
ResourceRef Zone::GetZoneTextureAttr() const
{
return GetResourceRef(zoneTexture_, TextureCube::GetTypeStatic());
}
void Zone::OnMarkedDirty(Node* node)
{
// Due to the octree query and weak pointer manipulation, is not safe from worker threads

Просмотреть файл

@ -24,6 +24,7 @@
#include "Color.h"
#include "Drawable.h"
#include "Texture.h"
namespace Urho3D
{
@ -64,10 +65,12 @@ public:
void SetPriority(int priority);
/// Set height fog mode.
void SetHeightFog(bool enable);
/// Set override mode. If camera is inside an override zone, it will also be used for all drawables.
/// Set override mode. If camera is inside an override zone, that zone will be used for all rendered objects instead of their own zone.
void SetOverride(bool enable);
/// Set ambient gradient mode. In gradient mode ambient color is interpolated from neighbor zones.
void SetAmbientGradient(bool enable);
/// Set zone texture. This will be bound to the zone texture unit when rendering objects inside the zone. Note that the default shaders do not use it.
void SetZoneTexture(Texture* texture);
/// Return inverse world transform.
const Matrix3x4& GetInverseWorldTransform() const;
@ -95,9 +98,15 @@ public:
bool GetOverride() const { return override_; }
/// Return whether ambient gradient mode is enabled.
bool GetAmbientGradient() const { return ambientGradient_; }
/// Return zone texture.
Texture* GetZoneTexture() const { return zoneTexture_; }
/// Check whether a point is inside.
bool IsInside(const Vector3& point) const;
/// Set zone texture attribute.
void SetZoneTextureAttr(ResourceRef value);
/// Return zone texture attribute.
ResourceRef GetZoneTextureAttr() const;
protected:
/// Handle node transform being dirtied.
@ -141,6 +150,8 @@ protected:
float fogHeightScale_;
/// Zone priority.
int priority_;
/// Zone texture.
SharedPtr<Texture> zoneTexture_;
/// Last zone used for ambient gradient start color.
WeakPtr<Zone> lastAmbientStartZone_;
/// Last zone used for ambient gradient end color.

Просмотреть файл

@ -182,7 +182,8 @@ enum TextureUnit
TU_DEPTHBUFFER = 10,
TU_LIGHTBUFFER = 11,
TU_VOLUMEMAP = 12,
MAX_TEXTURE_UNITS = 13
TU_ZONE = 13,
MAX_TEXTURE_UNITS = 14
};
enum FaceCameraMode

Просмотреть файл

@ -13,6 +13,7 @@ class Zone : public Drawable
void SetHeightFog(bool enable);
void SetOverride(bool enable);
void SetAmbientGradient(bool enable);
void SetZoneTexture(Texture* texture);
const Matrix3x4& GetInverseWorldTransform() const;
const Color& GetAmbientColor() const;
@ -27,6 +28,7 @@ class Zone : public Drawable
bool GetHeightFog() const;
bool GetOverride() const;
bool GetAmbientGradient() const;
Texture* GetZoneTexture() const;
bool IsInside(const Vector3& point) const;
@ -44,4 +46,5 @@ class Zone : public Drawable
tolua_property__get_set bool heightFog;
tolua_property__get_set bool override;
tolua_property__get_set bool ambientGradient;
tolua_property__get_set Texture* zoneTexture;
};

Просмотреть файл

@ -292,6 +292,7 @@ static void RegisterRenderPath(asIScriptEngine* engine)
engine->RegisterEnumValue("TextureUnit", "TU_DEPTHBUFFER", TU_DEPTHBUFFER);
engine->RegisterEnumValue("TextureUnit", "TU_LIGHTBUFFER", TU_LIGHTBUFFER);
engine->RegisterEnumValue("TextureUnit", "TU_VOLUMEMAP", TU_VOLUMEMAP);
engine->RegisterEnumValue("TextureUnit", "TU_ZONE", TU_ZONE);
engine->RegisterEnumValue("TextureUnit", "MAX_MATERIAL_TEXTURE_UNITS", MAX_MATERIAL_TEXTURE_UNITS);
engine->RegisterEnumValue("TextureUnit", "MAX_TEXTURE_UNITS", MAX_TEXTURE_UNITS);
@ -851,6 +852,8 @@ static void RegisterZone(asIScriptEngine* engine)
engine->RegisterObjectMethod("Zone", "bool get_override() const", asMETHOD(Zone, GetOverride), asCALL_THISCALL);
engine->RegisterObjectMethod("Zone", "void set_ambientGradient(bool)", asMETHOD(Zone, SetAmbientGradient), asCALL_THISCALL);
engine->RegisterObjectMethod("Zone", "bool get_ambientGradient() const", asMETHOD(Zone, GetAmbientGradient), asCALL_THISCALL);
engine->RegisterObjectMethod("Zone", "void set_zoneTexture(Texture@+)", asMETHOD(Zone, SetZoneTexture), asCALL_THISCALL);
engine->RegisterObjectMethod("Zone", "Texture@+ get_zoneTexture() const", asMETHOD(Zone, GetZoneTexture), asCALL_THISCALL);
}
static void RegisterStaticModel(asIScriptEngine* engine)