mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 14:53:01 +02:00
First pass at new particle shader
This commit is contained in:
parent
7d0a5677fa
commit
230a413ec1
10 changed files with 104 additions and 86 deletions
|
@ -25,21 +25,23 @@
|
||||||
#include "textured_particle_frag.h"
|
#include "textured_particle_frag.h"
|
||||||
#include "textured_particle_alpha_discard_frag.h"
|
#include "textured_particle_alpha_discard_frag.h"
|
||||||
|
|
||||||
|
static const uint32_t VERTEX_PER_QUAD = 6;
|
||||||
|
|
||||||
class ParticlePayload {
|
class ParticlePayload {
|
||||||
public:
|
public:
|
||||||
typedef render::Payload<ParticlePayload> Payload;
|
using Payload = render::Payload<ParticlePayload>;
|
||||||
typedef Payload::DataPointer Pointer;
|
using Pointer = Payload::DataPointer;
|
||||||
typedef RenderableParticleEffectEntityItem::Vertex Vertex;
|
using Vertex = RenderableParticleEffectEntityItem::Vertex;
|
||||||
|
|
||||||
ParticlePayload(EntityItemPointer entity) :
|
ParticlePayload(EntityItemPointer entity) :
|
||||||
_entity(entity),
|
_entity(entity),
|
||||||
_vertexFormat(std::make_shared<gpu::Stream::Format>()),
|
_vertexFormat(std::make_shared<gpu::Stream::Format>()),
|
||||||
_vertexBuffer(std::make_shared<gpu::Buffer>()),
|
_vertexBuffer(std::make_shared<gpu::Buffer>()) {
|
||||||
_indexBuffer(std::make_shared<gpu::Buffer>()) {
|
|
||||||
|
|
||||||
_vertexFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element::VEC3F_XYZ, offsetof(Vertex, xyz));
|
_vertexFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element::VEC4F_XYZW,
|
||||||
_vertexFormat->setAttribute(gpu::Stream::TEXCOORD, 0, gpu::Element::VEC2F_UV, offsetof(Vertex, uv));
|
offsetof(Vertex, xyzw), VERTEX_PER_QUAD);
|
||||||
_vertexFormat->setAttribute(gpu::Stream::COLOR, 0, gpu::Element::COLOR_RGBA_32, offsetof(Vertex, rgba));
|
_vertexFormat->setAttribute(gpu::Stream::COLOR, 0, gpu::Element::COLOR_RGBA_32,
|
||||||
|
offsetof(Vertex, rgba), VERTEX_PER_QUAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPipeline(gpu::PipelinePointer pipeline) { _pipeline = pipeline; }
|
void setPipeline(gpu::PipelinePointer pipeline) { _pipeline = pipeline; }
|
||||||
|
@ -54,9 +56,6 @@ public:
|
||||||
gpu::BufferPointer getVertexBuffer() { return _vertexBuffer; }
|
gpu::BufferPointer getVertexBuffer() { return _vertexBuffer; }
|
||||||
const gpu::BufferPointer& getVertexBuffer() const { return _vertexBuffer; }
|
const gpu::BufferPointer& getVertexBuffer() const { return _vertexBuffer; }
|
||||||
|
|
||||||
gpu::BufferPointer getIndexBuffer() { return _indexBuffer; }
|
|
||||||
const gpu::BufferPointer& getIndexBuffer() const { return _indexBuffer; }
|
|
||||||
|
|
||||||
void setTexture(gpu::TexturePointer texture) { _texture = texture; }
|
void setTexture(gpu::TexturePointer texture) { _texture = texture; }
|
||||||
const gpu::TexturePointer& getTexture() const { return _texture; }
|
const gpu::TexturePointer& getTexture() const { return _texture; }
|
||||||
|
|
||||||
|
@ -76,10 +75,9 @@ public:
|
||||||
batch.setModelTransform(_modelTransform);
|
batch.setModelTransform(_modelTransform);
|
||||||
batch.setInputFormat(_vertexFormat);
|
batch.setInputFormat(_vertexFormat);
|
||||||
batch.setInputBuffer(0, _vertexBuffer, 0, sizeof(Vertex));
|
batch.setInputBuffer(0, _vertexBuffer, 0, sizeof(Vertex));
|
||||||
batch.setIndexBuffer(gpu::UINT16, _indexBuffer, 0);
|
|
||||||
|
|
||||||
auto numIndices = _indexBuffer->getSize() / sizeof(uint16_t);
|
auto numVertices = _vertexBuffer->getSize() / sizeof(Vertex);
|
||||||
batch.drawIndexed(gpu::TRIANGLES, numIndices);
|
batch.draw(gpu::TRIANGLES, numVertices * VERTEX_PER_QUAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -89,7 +87,6 @@ protected:
|
||||||
gpu::PipelinePointer _pipeline;
|
gpu::PipelinePointer _pipeline;
|
||||||
gpu::Stream::FormatPointer _vertexFormat;
|
gpu::Stream::FormatPointer _vertexFormat;
|
||||||
gpu::BufferPointer _vertexBuffer;
|
gpu::BufferPointer _vertexBuffer;
|
||||||
gpu::BufferPointer _indexBuffer;
|
|
||||||
gpu::TexturePointer _texture;
|
gpu::TexturePointer _texture;
|
||||||
bool _visibleFlag = true;
|
bool _visibleFlag = true;
|
||||||
};
|
};
|
||||||
|
@ -197,70 +194,38 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
|
||||||
particleDetails.emplace_back(particle.position, particle.radius, rgba);
|
particleDetails.emplace_back(particle.position, particle.radius, rgba);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort particles back to front
|
|
||||||
// NOTE: this is view frustum might be one frame out of date.
|
|
||||||
auto direction = AbstractViewStateInterface::instance()->getCurrentViewFrustum()->getDirection();
|
|
||||||
|
|
||||||
// No need to sort if we're doing additive blending
|
// No need to sort if we're doing additive blending
|
||||||
if (!_additiveBlending) {
|
if (!_additiveBlending) {
|
||||||
|
// sort particles back to front
|
||||||
|
// NOTE: this is view frustum might be one frame out of date.
|
||||||
|
auto direction = AbstractViewStateInterface::instance()->getCurrentViewFrustum()->getDirection();
|
||||||
|
// Get direction in the entity space
|
||||||
|
direction = glm::inverse(getRotation()) * direction;
|
||||||
|
|
||||||
std::sort(particleDetails.begin(), particleDetails.end(),
|
std::sort(particleDetails.begin(), particleDetails.end(),
|
||||||
[&](const ParticleDetails& lhs, const ParticleDetails& rhs) {
|
[&](const ParticleDetails& lhs, const ParticleDetails& rhs) {
|
||||||
return glm::dot(lhs.position, direction) > glm::dot(rhs.position, direction);
|
return glm::dot(lhs.position, direction) > glm::dot(rhs.position, direction);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// allocate vertices
|
|
||||||
_vertices.clear();
|
|
||||||
|
|
||||||
// build vertices from particle positions and radiuses
|
// build vertices from particle positions and radiuses
|
||||||
glm::vec3 right = glm::normalize(glm::cross(direction, Vectors::UNIT_Y));
|
_vertices.clear(); // clear vertices
|
||||||
glm::vec3 up = glm::normalize(glm::cross(right, direction));
|
_vertices.reserve(particleDetails.size()); // Reserve space
|
||||||
for (const auto& particle : particleDetails) {
|
for (const auto& particle : particleDetails) {
|
||||||
glm::vec3 upOffset = up * particle.radius;
|
_vertices.emplace_back(glm::vec4(particle.position, particle.radius), particle.rgba);
|
||||||
glm::vec3 rightOffset = right * particle.radius;
|
|
||||||
// generate corners of quad aligned to face the camera.
|
|
||||||
_vertices.emplace_back(particle.position + rightOffset + upOffset, glm::vec2(1.0f, 1.0f), particle.rgba);
|
|
||||||
_vertices.emplace_back(particle.position - rightOffset + upOffset, glm::vec2(0.0f, 1.0f), particle.rgba);
|
|
||||||
_vertices.emplace_back(particle.position - rightOffset - upOffset, glm::vec2(0.0f, 0.0f), particle.rgba);
|
|
||||||
_vertices.emplace_back(particle.position + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), particle.rgba);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render::PendingChanges pendingChanges;
|
render::PendingChanges pendingChanges;
|
||||||
pendingChanges.updateItem<ParticlePayload>(_renderItemId, [this](ParticlePayload& payload) {
|
pendingChanges.updateItem<ParticlePayload>(_renderItemId, [this](ParticlePayload& payload) {
|
||||||
// update vertex buffer
|
// update vertex buffer
|
||||||
auto vertexBuffer = payload.getVertexBuffer();
|
auto vertexBuffer = payload.getVertexBuffer();
|
||||||
auto indexBuffer = payload.getIndexBuffer();
|
|
||||||
size_t numBytes = sizeof(Vertex) * _vertices.size();
|
size_t numBytes = sizeof(Vertex) * _vertices.size();
|
||||||
|
vertexBuffer->resize(numBytes);
|
||||||
if (numBytes == 0) {
|
if (numBytes == 0) {
|
||||||
vertexBuffer->resize(0);
|
|
||||||
indexBuffer->resize(0);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexBuffer->resize(numBytes);
|
|
||||||
memcpy(vertexBuffer->editData(), _vertices.data(), numBytes);
|
memcpy(vertexBuffer->editData(), _vertices.data(), numBytes);
|
||||||
|
|
||||||
// FIXME, don't update index buffer if num particles has not changed.
|
|
||||||
// update index buffer
|
|
||||||
const size_t NUM_VERTS_PER_PARTICLE = 4;
|
|
||||||
const size_t NUM_INDICES_PER_PARTICLE = 6;
|
|
||||||
auto numQuads = (_vertices.size() / NUM_VERTS_PER_PARTICLE);
|
|
||||||
numBytes = sizeof(uint16_t) * numQuads * NUM_INDICES_PER_PARTICLE;
|
|
||||||
indexBuffer->resize(numBytes);
|
|
||||||
gpu::Byte* data = indexBuffer->editData();
|
|
||||||
auto indexPtr = reinterpret_cast<uint16_t*>(data);
|
|
||||||
for (size_t i = 0; i < numQuads; ++i) {
|
|
||||||
indexPtr[i * NUM_INDICES_PER_PARTICLE + 0] = i * NUM_VERTS_PER_PARTICLE + 0;
|
|
||||||
indexPtr[i * NUM_INDICES_PER_PARTICLE + 1] = i * NUM_VERTS_PER_PARTICLE + 1;
|
|
||||||
indexPtr[i * NUM_INDICES_PER_PARTICLE + 2] = i * NUM_VERTS_PER_PARTICLE + 3;
|
|
||||||
indexPtr[i * NUM_INDICES_PER_PARTICLE + 3] = i * NUM_VERTS_PER_PARTICLE + 1;
|
|
||||||
indexPtr[i * NUM_INDICES_PER_PARTICLE + 4] = i * NUM_VERTS_PER_PARTICLE + 2;
|
|
||||||
indexPtr[i * NUM_INDICES_PER_PARTICLE + 5] = i * NUM_VERTS_PER_PARTICLE + 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update transform
|
// update transform
|
||||||
glm::vec3 position = getPosition();
|
glm::vec3 position = getPosition();
|
||||||
glm::quat rotation = getRotation();
|
glm::quat rotation = getRotation();
|
||||||
|
@ -323,8 +288,7 @@ void RenderableParticleEffectEntityItem::createPipelines() {
|
||||||
gpu::ShaderPointer fragShader;
|
gpu::ShaderPointer fragShader;
|
||||||
if (_additiveBlending) {
|
if (_additiveBlending) {
|
||||||
fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(textured_particle_frag)));
|
fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(textured_particle_frag)));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//If we are sorting and have no additive blending, we want to discard pixels with low alpha to avoid inter-particle entity artifacts
|
//If we are sorting and have no additive blending, we want to discard pixels with low alpha to avoid inter-particle entity artifacts
|
||||||
fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(textured_particle_alpha_discard_frag)));
|
fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(textured_particle_alpha_discard_frag)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,9 @@ protected:
|
||||||
render::ItemID _renderItemId;
|
render::ItemID _renderItemId;
|
||||||
|
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
Vertex(glm::vec3 xyzIn, glm::vec2 uvIn, uint32_t rgbaIn) : xyz(xyzIn), uv(uvIn), rgba(rgbaIn) {}
|
Vertex(glm::vec4 xyzwIn, uint32_t rgbaIn) : xyzw(xyzwIn), rgba(rgbaIn) {}
|
||||||
glm::vec3 xyz;
|
glm::vec4 xyzw; // Position + radius
|
||||||
glm::vec2 uv;
|
uint32_t rgba; // Color
|
||||||
uint32_t rgba;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void createPipelines();
|
void createPipelines();
|
||||||
|
|
|
@ -9,14 +9,17 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
uniform sampler2D colorMap;
|
in vec4 varColor;
|
||||||
|
in vec2 varTexcoord;
|
||||||
in vec4 _color;
|
|
||||||
in vec2 _texCoord0;
|
|
||||||
|
|
||||||
out vec4 outFragColor;
|
out vec4 outFragColor;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 color = texture(colorMap, _texCoord0);
|
outFragColor = varColor;//texture(tex, varTexcoord.xy) * varColor;
|
||||||
outFragColor = color * _color;
|
|
||||||
|
if (varColor == vec4(0,0,0,1)) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,21 +10,58 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
<@include gpu/Inputs.slh@>
|
|
||||||
|
|
||||||
<@include gpu/Transform.slh@>
|
<@include gpu/Transform.slh@>
|
||||||
|
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
out vec4 _color;
|
in vec4 inPosition;
|
||||||
out vec2 _texCoord0;
|
in vec4 inColor;
|
||||||
|
|
||||||
|
out vec4 varColor;
|
||||||
|
out vec2 varTexcoord;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
// pass along the color & uvs to fragment shader
|
const int NUM_VERTICES_PER_PARTICLE = 6;
|
||||||
_color = inColor;
|
const vec4 UNIT_QUAD[NUM_VERTICES_PER_PARTICLE] = vec4[NUM_VERTICES_PER_PARTICLE](
|
||||||
_texCoord0 = inTexCoord0.xy;
|
vec4(-1.0, -1.0, 0.0, 1.0),
|
||||||
|
vec4(1.0, -1.0, 0.0, 1.0),
|
||||||
|
vec4(-1.0, 1.0, 0.0, 1.0),
|
||||||
|
vec4(-1.0, 1.0, 0.0, 1.0),
|
||||||
|
vec4(1.0, -1.0, 0.0, 1.0),
|
||||||
|
vec4(1.0, 1.0, 0.0, 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// anchor point in eye space
|
||||||
|
vec4 anchorPoint = vec4(inPosition.xyz, 1.0);
|
||||||
|
float radius = inPosition.w;
|
||||||
|
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, inPosition, gl_Position)$>
|
<$transformModelToEyePos(cam, obj, anchorPoint, anchorPoint)$>
|
||||||
|
|
||||||
|
// Which icon are we dealing with ?
|
||||||
|
int particleID = gl_VertexID / NUM_VERTICES_PER_PARTICLE;
|
||||||
|
|
||||||
|
// Which quad vertex pos?
|
||||||
|
int twoTriID = gl_VertexID - particleID * NUM_VERTICES_PER_PARTICLE;
|
||||||
|
vec4 quadPos = radius * UNIT_QUAD[twoTriID];
|
||||||
|
|
||||||
|
// Pass the texcoord and the z texcoord is representing the texture icon
|
||||||
|
varTexcoord = vec2((quadPos.xy + 1.0) * 0.5);
|
||||||
|
varColor = inColor;
|
||||||
|
|
||||||
|
if (particleID == 0) {
|
||||||
|
varColor = vec4(1,0,0,1);
|
||||||
|
} else if (particleID == 5) {
|
||||||
|
varColor = vec4(0,1,0,1);
|
||||||
|
} else if (particleID == 10) {
|
||||||
|
varColor = vec4(0,0,1,1);
|
||||||
|
} else {
|
||||||
|
varColor = vec4(0,0,0,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 clipPos;
|
||||||
|
vec4 eyePos = vec4(anchorPoint.xyz + quadPos.xyz, 1.0);
|
||||||
|
<$transformEyeToClip(cam, eyePos, clipPos)$>
|
||||||
|
gl_Position = clipPos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ const float ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD = 0.0f;
|
||||||
const float ParticleEffectEntityItem::DEFAULT_RADIUS_START = DEFAULT_PARTICLE_RADIUS;
|
const float ParticleEffectEntityItem::DEFAULT_RADIUS_START = DEFAULT_PARTICLE_RADIUS;
|
||||||
const float ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH = DEFAULT_PARTICLE_RADIUS;
|
const float ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH = DEFAULT_PARTICLE_RADIUS;
|
||||||
const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = "";
|
const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = "";
|
||||||
const bool ParticleEffectEntityItem::DEFAULT_ADDITIVE_BLENDING = false;
|
const bool ParticleEffectEntityItem::DEFAULT_ADDITIVE_BLENDING = true;
|
||||||
|
|
||||||
|
|
||||||
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
|
|
|
@ -211,7 +211,7 @@ public:
|
||||||
static const bool DEFAULT_ADDITIVE_BLENDING;
|
static const bool DEFAULT_ADDITIVE_BLENDING;
|
||||||
bool getAdditiveBlending() const { return _additiveBlending; }
|
bool getAdditiveBlending() const { return _additiveBlending; }
|
||||||
void setAdditiveBlending(bool additiveBlending) {
|
void setAdditiveBlending(bool additiveBlending) {
|
||||||
_additiveBlending = additiveBlending;
|
_additiveBlending = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const { return false; }
|
virtual bool supportsDetailedRayIntersection() const { return false; }
|
||||||
|
|
|
@ -154,7 +154,7 @@ GLBackend::GLShader* compileShader(const Shader& shader) {
|
||||||
|
|
||||||
qCWarning(gpulogging) << "GLShader::compileShader - failed to compile the gl shader object:";
|
qCWarning(gpulogging) << "GLShader::compileShader - failed to compile the gl shader object:";
|
||||||
qCWarning(gpulogging) << temp;
|
qCWarning(gpulogging) << temp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
filestream.open("debugshader.glsl.info.txt");
|
filestream.open("debugshader.glsl.info.txt");
|
||||||
if (filestream.is_open()) {
|
if (filestream.is_open()) {
|
||||||
|
|
|
@ -59,7 +59,7 @@ void Stream::Format::evaluateCache() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Stream::Format::setAttribute(Slot slot, Slot channel, Element element, Offset offset, Frequency frequency) {
|
bool Stream::Format::setAttribute(Slot slot, Slot channel, Element element, Offset offset, uint32 frequency) {
|
||||||
_attributes[slot] = Attribute((InputSlot) slot, channel, element, offset, frequency);
|
_attributes[slot] = Attribute((InputSlot) slot, channel, element, offset, frequency);
|
||||||
evaluateCache();
|
evaluateCache();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -49,8 +49,8 @@ public:
|
||||||
|
|
||||||
// Frequency describer
|
// Frequency describer
|
||||||
enum Frequency {
|
enum Frequency {
|
||||||
|
PER_INSTANCE = -1,
|
||||||
PER_VERTEX = 0,
|
PER_VERTEX = 0,
|
||||||
PER_INSTANCE,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The attribute description
|
// The attribute description
|
||||||
|
@ -59,7 +59,7 @@ public:
|
||||||
public:
|
public:
|
||||||
Attribute() {}
|
Attribute() {}
|
||||||
|
|
||||||
Attribute(Slot slot, Slot channel, Element element, Offset offset = 0, Frequency frequency = PER_VERTEX) :
|
Attribute(Slot slot, Slot channel, Element element, Offset offset = 0, uint32 frequency = PER_VERTEX) :
|
||||||
_slot(slot),
|
_slot(slot),
|
||||||
_channel(channel),
|
_channel(channel),
|
||||||
_element(element),
|
_element(element),
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
|
|
||||||
uint32 getElementTotalSize() const { return _elementTotalSize; }
|
uint32 getElementTotalSize() const { return _elementTotalSize; }
|
||||||
|
|
||||||
bool setAttribute(Slot slot, Slot channel, Element element, Offset offset = 0, Frequency frequency = PER_VERTEX);
|
bool setAttribute(Slot slot, Slot channel, Element element, Offset offset = 0, uint32 frequency = PER_VERTEX);
|
||||||
bool setAttribute(Slot slot, Frequency frequency = PER_VERTEX);
|
bool setAttribute(Slot slot, Frequency frequency = PER_VERTEX);
|
||||||
bool setAttribute(Slot slot, Slot channel, Frequency frequency = PER_VERTEX);
|
bool setAttribute(Slot slot, Slot channel, Frequency frequency = PER_VERTEX);
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,16 @@ TransformCamera getTransformCamera() {
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
<@func $transformModelToEyePos(cameraTransform, objectTransform, modelPos, eyePos)@>
|
||||||
|
<!// Equivalent to the following but hoppefully a tad more accurate
|
||||||
|
//return camera._projection * camera._view * object._model * pos; !>
|
||||||
|
{ // transformModelToEyePos
|
||||||
|
vec4 _worldpos = (<$objectTransform$>._model * <$modelPos$>);
|
||||||
|
<$eyePos$> = (<$cameraTransform$>._view * _worldpos);
|
||||||
|
// <$eyePos$> = (<$cameraTransform$>._projectionInverse * <$clipPos$>);
|
||||||
|
}
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
<@func $transformInstancedModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
<@func $transformInstancedModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@>
|
||||||
<!// Equivalent to the following but hoppefully a tad more accurate
|
<!// Equivalent to the following but hoppefully a tad more accurate
|
||||||
//return camera._projection * camera._view * object._model * pos; !>
|
//return camera._projection * camera._view * object._model * pos; !>
|
||||||
|
@ -86,7 +96,6 @@ TransformCamera getTransformCamera() {
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
|
||||||
<@func transformModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
<@func transformModelToWorldPos(objectTransform, modelPos, worldPos)@>
|
||||||
{ // transformModelToWorldPos
|
{ // transformModelToWorldPos
|
||||||
<$worldPos$> = (<$objectTransform$>._model * <$modelPos$>);
|
<$worldPos$> = (<$objectTransform$>._model * <$modelPos$>);
|
||||||
|
@ -140,4 +149,10 @@ TransformCamera getTransformCamera() {
|
||||||
}
|
}
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
<@func transformEyeToClip(cameraTransform, eyePos, clipPos)@>
|
||||||
|
{ // transformEyeToClip
|
||||||
|
<$clipPos$> = <$cameraTransform$>._projection * <$eyePos$>;
|
||||||
|
}
|
||||||
|
<@endfunc@>
|
||||||
|
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
Loading…
Reference in a new issue