59 if (!_sceneDataBoundThisPass ||
60 std::memcmp(&sceneData.projViewMatrix, &_cachedSceneVP,
sizeof(simd::float4x4)) != 0) {
61 encoder->setVertexBytes(&sceneData,
sizeof(SceneData), 1);
62 _cachedSceneVP = sceneData.projViewMatrix;
63 _sceneDataBoundThisPass =
true;
82 const float c00 = m11 * m22 - m12 * m21;
83 const float c01 = m12 * m20 - m10 * m22;
84 const float c02 = m10 * m21 - m11 * m20;
85 const float c10 = m02 * m21 - m01 * m22;
86 const float c11 = m00 * m22 - m02 * m20;
87 const float c12 = m01 * m20 - m00 * m21;
88 const float c20 = m01 * m12 - m02 * m11;
89 const float c21 = m02 * m10 - m00 * m12;
90 const float c22 = m00 * m11 - m01 * m10;
92 const float det3 = m00 * c00 + m01 * c01 + m02 * c02;
93 const float normalSign = det3 < 0.0f ? -1.0f : 1.0f;
94 const float invDet = (std::abs(det3) > 1e-8f) ? (1.0f / det3) : 0.0f;
97 const simd::float4x4 normalMatrix = simd::float4x4(
98 simd::float4{c00 * invDet, c01 * invDet, c02 * invDet, 0.0f},
99 simd::float4{c10 * invDet, c11 * invDet, c12 * invDet, 0.0f},
100 simd::float4{c20 * invDet, c21 * invDet, c22 * invDet, 0.0f},
101 simd::float4{0.0f, 0.0f, 0.0f, 1.0f}
104 const ModelData modelData{
112 const size_t transformOffset = transformRing->
allocate(&modelData,
sizeof(ModelData));
113 encoder->setVertexBufferOffset(transformOffset, 2);
121 const std::vector<GpuLightData>& lights,
const Vector3& cameraPosition,
122 const bool enableNormalMaps,
const float exposure,
124 const int toneMapping)
128 ambientLinear.
linear(&ambientColor);
135 const size_t lightCount = std::min(lights.size(), maxLights);
141 for (
size_t i = 0; i < maxLights; ++i) {
143 if (i < lightCount) {
144 const auto& src = lights[i];
146 lightLinear.
linear(&src.color);
147 dst.positionRange[0] = src.position.getX();
148 dst.positionRange[1] = src.position.getY();
149 dst.positionRange[2] = src.position.getZ();
150 dst.positionRange[3] = src.range;
151 dst.directionCone[0] = src.direction.getX();
152 dst.directionCone[1] = src.direction.getY();
153 dst.directionCone[2] = src.direction.getZ();
154 dst.colorIntensity[0] = lightLinear.
r;
155 dst.colorIntensity[1] = lightLinear.
g;
156 dst.colorIntensity[2] = lightLinear.
b;
157 dst.colorIntensity[3] = src.intensity;
163 dst.directionCone[3] = src.areaHalfWidth;
164 dst.coneAngles[0] = src.areaHalfHeight;
165 dst.coneAngles[1] = src.areaRight.getX();
166 dst.coneAngles[2] = src.areaRight.getY();
167 dst.coneAngles[3] = src.areaRight.getZ();
169 dst.directionCone[3] = src.outerConeCos;
170 dst.coneAngles[0] = src.innerConeCos;
171 dst.coneAngles[1] = src.outerConeCos;
172 dst.coneAngles[2] = 0.0f;
173 dst.coneAngles[3] = 0.0f;
175 dst.typeCastShadows[0] =
static_cast<uint32_t
>(src.type);
176 dst.typeCastShadows[1] = src.castShadows ? 1u : 0u;
177 dst.typeCastShadows[2] = src.falloffModeLinear ? 1u : 0u;
179 dst.typeCastShadows[3] = (src.shadowMapIndex >= 0)
180 ?
static_cast<uint32_t
>(src.shadowMapIndex) : 0u;
186 if (enableNormalMaps) {
232 _localShadowTexture0 =
nullptr;
233 _localShadowTexture1 =
nullptr;
234 _omniShadowCube0 =
nullptr;
235 _omniShadowCube1 =
nullptr;
251 constexpr float omniShaderBias = 0.001f;
252 const float farClip = ls.viewProjection.getElement(0, 0);
254 _omniShadowCube0 = ls.shadowMap;
261 _omniShadowCube1 = ls.shadowMap;
269 std::memset(matDst, 0, 16 *
sizeof(
float));
273 _localShadowTexture0 = ls.shadowMap;
275 _localShadowTexture1 = ls.shadowMap;
277 const auto& m = ls.viewProjection;
278 for (
int col = 0; col < 4; ++col) {
279 for (
int row = 0; row < 4; ++row) {
280 matDst[col * 4 + row] = m.getElement(row, col);
284 paramsDst[0] = ls.bias;
285 paramsDst[1] = ls.normalBias;
286 paramsDst[2] = ls.intensity;
287 paramsDst[3] = ls.isOmni ? 1.0f : 0.0f;
297 std::memset(matDst, 0, 16 *
sizeof(
float));
298 paramsDst[0] = 0.0001f;
311 const float skyboxMip,
const Vector3& skyDomeCenter,
const bool isDome,
314 _envAtlasTexture = envAtlas;
315 _skyboxCubeMapTexture = skyboxCubeMap;
324 if (_envAtlasTexture) {
361 const void* uniformData,
362 const size_t uniformSize,
368 size_t materialOffset;
369 if (_materialBoundThisPass && currentMaterial == _lastBoundMaterial) {
370 materialOffset = _lastMaterialOffset;
372 materialOffset = uniformRing->
allocate(uniformData, uniformSize);
373 _lastBoundMaterial = currentMaterial;
374 _lastMaterialOffset = materialOffset;
375 _materialBoundThisPass =
true;
377 encoder->setFragmentBufferOffset(materialOffset, 3);
378 encoder->setVertexBufferOffset(materialOffset, 3);
395 size_t lightingOffset;
396 if (_lightingBoundThisPass && lightingHash == _lastLightingHash) {
397 lightingOffset = _lastLightingOffset;
400 _lastLightingHash = lightingHash;
401 _lastLightingOffset = lightingOffset;
402 _lightingBoundThisPass =
true;
404 encoder->setFragmentBufferOffset(lightingOffset, 4);
GPU texture resource supporting 2D, cubemap, volume, and array formats with mipmap management.