Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
TPixelTexture2D.ipp
Go to the documentation of this file.
1#pragma once
2
5
6#include <Common/assertion.h>
7
8#include <stdexcept>
9#include <cmath>
10
11namespace ph
12{
13
14template<typename OutputType>
15inline TPixelTexture2D<OutputType>::TPixelTexture2D(const std::shared_ptr<PixelBuffer2D>& pixelBuffer) :
17 pixelBuffer,
18 pixel_texture::ESampleMode::Bilinear,
19 pixel_texture::EWrapMode::ClampToEdge)
20{}
21
22template<typename OutputType>
24 const std::shared_ptr<PixelBuffer2D>& pixelBuffer,
25 const pixel_texture::ESampleMode sampleMode,
26 const pixel_texture::EWrapMode wrapModeS,
27 const pixel_texture::EWrapMode wrapModeT) :
28
29 TTexture<OutputType>(),
31 m_pixelBuffer(pixelBuffer),
32 m_sampleMode (sampleMode),
33 m_wrapModeS (wrapModeS),
34 m_wrapModeT (wrapModeT),
35 m_texelSize (0)
37 if(!m_pixelBuffer)
38 {
39 throw std::invalid_argument(
40 "Input pixel buffer is empty.");
41 }
42
43 m_texelSize = math::Vector2D(1.0) / math::Vector2D(m_pixelBuffer->getSize());
44}
45
46template<typename OutputType>
48{
49 PH_ASSERT(m_pixelBuffer);
50 return m_pixelBuffer->getSize();
51}
52
53template<typename OutputType>
55{
56 return m_texelSize;
57}
58
59template<typename OutputType>
61{
62 return m_sampleMode;
63}
64
65template<typename OutputType>
67{
68 return m_wrapModeS;
69}
70
71template<typename OutputType>
73{
74 return m_wrapModeT;
75}
76
77template<typename OutputType>
79{
80 PH_ASSERT(m_pixelBuffer);
81 return m_pixelBuffer.get();
82}
83
84template<typename OutputType>
86{
87 return pixel_texture::uv_to_st(sampleUV, getWrapModeS(), getWrapModeT());
88}
89
90template<typename OutputType>
92{
93 switch(getSampleMode())
94 {
96 return samplePixelBufferNearest(sampleUV);
97
99 return samplePixelBufferBilinear(sampleUV);
100 }
101
102 PH_ASSERT_UNREACHABLE_SECTION();
103 return {};
104}
105
106template<typename OutputType>
108{
109 const math::TVector2<uint32> bufferSize = getSizePx();
110 PH_ASSERT_GT(bufferSize.product(), 0);
111
112 const math::Vector2D st = sampleUVToST(sampleUV);
113
114 // Calculate pixel buffer index and handle potential overflow
115 uint32 x = static_cast<uint32>(st[0] * bufferSize.x());
116 uint32 y = static_cast<uint32>(st[1] * bufferSize.y());
117 x = x < bufferSize.x() ? x : bufferSize.x() - 1;
118 y = y < bufferSize.y() ? y : bufferSize.y() - 1;
119
120 return getPixelBuffer()->fetchPixel({x, y}, 0);
121}
122
123template<typename OutputType>
125{
126 const math::TVector2<uint32> bufferSize = getSizePx();
127 PH_ASSERT_GT(bufferSize.product(), 0);
128
129 const math::Vector2D st = sampleUVToST(sampleUV);
130
131 const float64 x = st[0] * bufferSize.x();
132 const float64 y = st[1] * bufferSize.y();
133 const float64 x0 = std::floor(x - 0.5) + 0.5;
134 const float64 y0 = std::floor(y - 0.5) + 0.5;
135 const float64 x1 = x0 + 1.0;
136 const float64 y1 = y0 + 1.0;
137
138 const float64 weights[4]
139 {
140 (x1 - x) * (y1 - y),// weight 00
141 (x1 - x) * (y - y0),// weight 01
142 (x - x0) * (y1 - y),// weight 10
143 (x - x0) * (y - y0) // weight 11
144 };
145 const math::Vector2D xys[4]
146 {
147 {x0, y0}, {x0, y1}, {x1, y0}, {x1, y1}
148 };
149
151
152 // Calculate bilinearly interpolated pixel by accumulating weighted samples
153 ComputePixel accuPixel(0);
154 for(std::size_t i = 0; i < 4; ++i)
155 {
156 // ST coordinates for the i-th vertex of the bilinear quad
157 const math::Vector2D st_i = sampleUVToST(xys[i] * getTexelSize());
158
159 uint32 xi = static_cast<uint32>(st_i[0] * bufferSize.x());
160 uint32 yi = static_cast<uint32>(st_i[1] * bufferSize.y());
161 xi = xi < bufferSize.x() ? xi : bufferSize.x() - 1;
162 yi = yi < bufferSize.y() ? yi : bufferSize.y() - 1;
163
164 const ComputePixel pixel_i(getPixelBuffer()->fetchPixel({xi, yi}, 0).getAllValues());
165
166 accuPixel.addLocal(pixel_i * weights[i]);
167 }
168
169 return pixel_buffer::TPixel<float64>(accuPixel.toArray(), getPixelBuffer()->numPixelElements());
170}
171
172}// end namespace ph
Definition PixelBuffer2D.h:153
Definition TPixelTexture2D.h:16
pixel_buffer::TPixel< float64 > samplePixelBufferNearest(const math::Vector2D &sampleUV) const
Definition TPixelTexture2D.ipp:107
pixel_texture::EWrapMode getWrapModeT() const
Definition TPixelTexture2D.ipp:72
pixel_buffer::TPixel< float64 > samplePixelBuffer(const math::Vector2D &sampleUV) const
Definition TPixelTexture2D.ipp:91
const PixelBuffer2D * getPixelBuffer() const
Definition TPixelTexture2D.ipp:78
pixel_texture::ESampleMode getSampleMode() const
Definition TPixelTexture2D.ipp:60
TPixelTexture2D(const std::shared_ptr< PixelBuffer2D > &pixelBuffer)
Definition TPixelTexture2D.ipp:15
math::Vector2D sampleUVToST(const math::Vector2D &sampleUV) const
Definition TPixelTexture2D.ipp:85
pixel_texture::EWrapMode getWrapModeS() const
Definition TPixelTexture2D.ipp:66
pixel_buffer::TPixel< float64 > samplePixelBufferBilinear(const math::Vector2D &sampleUV) const
Definition TPixelTexture2D.ipp:124
math::TVector2< uint32 > getSizePx() const
Definition TPixelTexture2D.ipp:47
math::Vector2D getTexelSize() const
Definition TPixelTexture2D.ipp:54
Definition TTexture.h:12
Definition TArithmeticArray.h:13
Represents a 2-D vector.
Definition TVector2.h:19
T & x()
Definition TVector2.ipp:38
T & y()
Definition TVector2.ipp:44
T product() const
Definition TArithmeticArrayBase.ipp:358
Represent a pixel from pixel buffer.
Definition PixelBuffer2D.h:27
TVector2< float64 > Vector2D
Definition math_fwd.h:47
math::Vector2D uv_to_st(const math::Vector2D &inputUV, const EWrapMode wrapModeS, const EWrapMode wrapModeT)
Transform (u, v) coordinates to (s, t) in [0, 1] according to wrap mode. The transformation will pres...
Definition pixel_texture_basics.h:95
EWrapMode
Definition pixel_texture_basics.h:21
ESampleMode
Definition pixel_texture_basics.h:28
The root for all renderer implementations.
Definition EEngineProject.h:6