From dc8756e4659eed24d593522bb7176fc2f4e9bc9c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 15 Sep 2015 14:40:23 -0700 Subject: [PATCH] Need to pull master, just updated all the deferred shaders to use scribe func declare blocks to avoid long shaders... didn;t validate the current clip to eye position evaluation --- libraries/render-utils/src/DeferredBuffer.slh | 11 +++ .../render-utils/src/DeferredGlobalLight.slh | 24 +++++- .../src/DeferredLightingEffect.cpp | 85 +++++++++++++------ .../render-utils/src/DeferredLightingEffect.h | 1 + libraries/render-utils/src/Shadow.slh | 3 +- .../src/directional_ambient_light.slf | 3 + ...onal_ambient_light_cascaded_shadow_map.slf | 3 + .../directional_ambient_light_shadow_map.slf | 2 + .../render-utils/src/directional_light.slf | 3 + .../directional_light_cascaded_shadow_map.slf | 3 + .../src/directional_light_shadow_map.slf | 3 + .../src/directional_skybox_light.slf | 16 +++- ...ional_skybox_light_cascaded_shadow_map.slf | 3 + .../directional_skybox_light_shadow_map.slf | 3 + libraries/render-utils/src/point_light.slf | 12 ++- libraries/render-utils/src/spot_light.slf | 6 +- 16 files changed, 149 insertions(+), 32 deletions(-) diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index 32cf064e6e..ff6cfc175e 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -27,6 +27,7 @@ uniform sampler2D depthMap; struct DeferredTransform { + mat4 projection; mat4 viewInverse; // the distance to the near clip plane @@ -54,12 +55,22 @@ float getStereoSide(DeferredTransform deferredTransform) { } vec4 evalEyePositionFromZ(DeferredTransform deferredTransform, float depthVal, vec2 texcoord) { + vec3 nPos = vec3(texcoord.xy * 2.0f - 1.0f, depthVal * 2.0f - 1.0f); + + float Ze = -deferredTransform.projection[3][2] / (nPos.z + deferredTransform.projection[2][2]); + float Xe = (nPos.x - Ze * deferredTransform.projection[2][0] - deferredTransform.projection[3][0]) / deferredTransform.projection[0][0]; + float Ye = (nPos.y - Ze * deferredTransform.projection[2][1] - deferredTransform.projection[3][1]) / deferredTransform.projection[1][1]; + vec2 nearVal_depthScale = deferredTransform.nearVal_depthScale_stereoMode_spare0.xy; vec2 depthTexCoordOffset = deferredTransform.depthTexCoordOffset_scale.xy; vec2 depthTexCoordScale = deferredTransform.depthTexCoordOffset_scale.zw; // compute the view space position using the depth float z = nearVal_depthScale.x / (depthVal * nearVal_depthScale.y - 1.0); + if (texcoord.x > 0.0f) { + z = Ze; + return vec4(Xe, Ye, Ze, 1.0f); + } return vec4((depthTexCoordOffset + texcoord * depthTexCoordScale) * z, z, 1.0); } diff --git a/libraries/render-utils/src/DeferredGlobalLight.slh b/libraries/render-utils/src/DeferredGlobalLight.slh index a04d76541c..e3ea1287d9 100755 --- a/libraries/render-utils/src/DeferredGlobalLight.slh +++ b/libraries/render-utils/src/DeferredGlobalLight.slh @@ -13,6 +13,8 @@ <@include DeferredLighting.slh@> +<@func declareSkyboxMap()@> + uniform samplerCube skyboxMap; vec4 evalSkyboxLight(vec3 direction, float lod) { @@ -22,6 +24,9 @@ vec4 evalSkyboxLight(vec3 direction, float lod) { return skytexel; } +<@endfunc@> + +<@func declareSphericalHarmonics()@> struct SphericalHarmonics { vec4 L00; vec4 L1m1; @@ -59,10 +64,12 @@ vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { // Need one SH uniform SphericalHarmonics ambientSphere; +<@endfunc@> + // Everything about light <@include model/Light.slh@> - +<@func declareEvalAmbientGlobalColor()@> vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now @@ -80,6 +87,12 @@ vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi return color; } +<@endfunc@> + +<@func declareEvalAmbientSphereGlobalColor()@> + +<$declareSphericalHarmonics()$> + vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now Light light = getLight(); @@ -97,6 +110,12 @@ vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 return color; } +<@endfunc@> + +<@func declareEvalSkyboxGlobalColor()@> + +<$declareSkyboxMap()$> +<$declareSphericalHarmonics()$> vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Need the light now @@ -114,7 +133,9 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi return color; } +<@endfunc@> +<@func declareEvalLightmappedColor()@> vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { Light light = getLight(); @@ -139,5 +160,6 @@ vec3 evalLightmappedColor(mat4 invViewMat, float shadowAttenuation, vec3 normal, return diffuse * (ambientLight + diffuseLight); } +<@endfunc@> <@endif@> diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 10da54fc75..05649d883f 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -308,8 +308,10 @@ void DeferredLightingEffect::render(RenderArgs* args) { float tMin = args->_viewport.y / (float)framebufferSize.height(); float tHeight = args->_viewport.w / (float)framebufferSize.height(); - bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); + auto monoViewport = args->_viewport; + + // The view furstum is the mono frustum base auto viewFrustum = args->_viewFrustum; float left, right, bottom, top, nearVal, farVal; @@ -322,19 +324,27 @@ void DeferredLightingEffect::render(RenderArgs* args) { float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; + // Eval the mono projection mat4 monoProjMat; viewFrustum->evalProjectionMatrix(monoProjMat); + + // The mono view transform Transform monoViewTransform; viewFrustum->evalViewTransform(monoViewTransform); + // THe mono view matrix coming from the mono view transform + glm::mat4 monoViewMat; + monoViewTransform.getMatrix(monoViewMat); + bool isStereo = args->_context->isStereo(); int numPasses = 1; mat4 projMats[2]; - Transform viewTransforms[2]; - vec4 viewports[2]; + ivec4 viewports[2]; + vec4 clipQuad[2]; vec2 screenBottomLeftCorners[2]; vec2 screenTopRightCorners[2]; + vec4 fetchTexcoordRects[2]; DeferredTransform deferredTransforms[2]; @@ -345,18 +355,25 @@ void DeferredLightingEffect::render(RenderArgs* args) { args->_context->getStereoProjections(projMats); args->_context->getStereoViews(eyeViews); - glm::mat4 monoViewMat; - monoViewTransform.getMatrix(monoViewMat); + float halfWidth = 0.5 * sWidth; for (int i = 0; i < numPasses; i++) { + // In stereo, the 2 sides are layout side by side in the mono viewport and their width is half + int sideWidth = monoViewport.z * 0.5; + viewports[i] = ivec4(monoViewport.x + (i * sideWidth), monoViewport.y, sideWidth, monoViewport.w); auto sideViewMat = eyeViews[i] * monoViewMat; - viewTransforms[i].evalFromRawMatrix(sideViewMat); - deferredTransforms[i]._viewInverse = sideViewMat; + + projMats[i] = projMats[i] * eyeViews[i]; + + deferredTransforms[i]._projection = projMats[i]; + + deferredTransforms[i]._viewInverse = monoViewMat; + deferredTransforms[i].nearVal = nearVal; deferredTransforms[i].depthScale = depthScale; deferredTransforms[i].isStereo = (i == 0 ? -1.0f : 1.0f); @@ -364,16 +381,22 @@ void DeferredLightingEffect::render(RenderArgs* args) { deferredTransforms[i].depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); - viewports[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); + clipQuad[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); screenBottomLeftCorners[i] = glm::vec2(-1.0f + i * 1.0f, -1.0f); screenTopRightCorners[i] = glm::vec2(i * 1.0f, 1.0f); + + fetchTexcoordRects[i] = glm::vec4(sMin + i * halfWidth, tMin, halfWidth, tHeight); + } } else { + + viewports[0] = monoViewport; + projMats[0] = monoProjMat; - viewTransforms[0] = monoViewTransform; + deferredTransforms[0]._projection = monoProjMat; - viewTransforms[0].getMatrix(deferredTransforms[0]._viewInverse); + deferredTransforms[0]._viewInverse = monoViewMat; deferredTransforms[0].nearVal = nearVal; deferredTransforms[0].depthScale = depthScale; @@ -382,9 +405,11 @@ void DeferredLightingEffect::render(RenderArgs* args) { deferredTransforms[0].depthTexCoordScale = glm::vec2(depthTexCoordScaleS, depthTexCoordScaleT); - viewports[0] = glm::vec4(sMin, tMin, sWidth, tHeight); + clipQuad[0] = glm::vec4(sMin, tMin, sWidth, tHeight); screenBottomLeftCorners[0] = glm::vec2(-1.0f, -1.0f); screenTopRightCorners[0] = glm::vec2(1.0f, 1.0f); + + fetchTexcoordRects[0] = glm::vec4(sMin, tMin, sWidth, tHeight); } auto eyePoint = viewFrustum->getPosition(); @@ -392,22 +417,30 @@ void DeferredLightingEffect::render(RenderArgs* args) { for (int side = 0; side < numPasses; side++) { + // Render in this side's viewport + batch.setViewportTransform(viewports[side]); + batch.setStateScissorRect(viewports[side]); + // Sync and Bind the correct DeferredTransform ubo _deferredTransformBuffer[side]._buffer->setSubData(0, sizeof(DeferredTransform), (const gpu::Byte*) &deferredTransforms[side]); - batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, _deferredTransformBuffer[side]); - /* glm::vec2 topLeft(-1.0f, -1.0f); + + glm::vec2 topLeft(-1.0f, -1.0f); glm::vec2 bottomRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(sMin, tMin); + /* glm::vec2 texCoordTopLeft(sMin, tMin); glm::vec2 texCoordBottomRight(sMin + sWidth, tMin + tHeight);*/ - glm::vec2 topLeft = screenBottomLeftCorners[side]; - glm::vec2 bottomRight = screenTopRightCorners[side]; - glm::vec2 texCoordTopLeft(viewports[side].x, viewports[side].y); - glm::vec2 texCoordBottomRight(viewports[side].x + viewports[side].z, viewports[side].y + viewports[side].w); + /* glm::vec2 topLeft = screenBottomLeftCorners[side]; + glm::vec2 bottomRight = screenTopRightCorners[side];*/ + glm::vec2 texCoordTopLeft(clipQuad[side].x, clipQuad[side].y); + glm::vec2 texCoordBottomRight(clipQuad[side].x + clipQuad[side].z, clipQuad[side].y + clipQuad[side].w); + + // First Global directional light and ambient pass + bool useSkyboxCubemap = (_skybox) && (_skybox->getCubemap()); + auto& program = _directionalLight; LightLocationsPtr locations = _directionalLightLocations; @@ -485,11 +518,13 @@ void DeferredLightingEffect::render(RenderArgs* args) { } { - Transform model; + /* Transform model; model.setTranslation(glm::vec3(sMin, tMin, 0.0)); model.setScale(glm::vec3(sWidth, tHeight, 1.0)); batch.setModelTransform(model); + */ + batch.setModelTransform(Transform()); batch.setProjectionTransform(glm::mat4()); batch.setViewTransform(Transform()); @@ -510,11 +545,11 @@ void DeferredLightingEffect::render(RenderArgs* args) { batch.setResourceTexture(4, nullptr); }*/ - glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); - glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); auto texcoordMat = glm::mat4(); - texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); + /* texcoordMat[0] = glm::vec4(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); texcoordMat[1] = glm::vec4(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); + */ texcoordMat[0] = glm::vec4(fetchTexcoordRects[side].z / 2.0f, 0.0f, 0.0f, fetchTexcoordRects[side].x + fetchTexcoordRects[side].z / 2.0f); + texcoordMat[1] = glm::vec4(0.0f, fetchTexcoordRects[side].w / 2.0f, 0.0f, fetchTexcoordRects[side].y + fetchTexcoordRects[side].w / 2.0f); texcoordMat[2] = glm::vec4(0.0f, 0.0f, 1.0f, 0.0f); texcoordMat[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); @@ -524,7 +559,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { auto geometryCache = DependencyManager::get(); batch.setProjectionTransform(projMats[side]); - batch.setViewTransform(viewTransforms[side]); + batch.setViewTransform(monoViewTransform); if (!_pointLights.empty()) { batch.setPipeline(_pointLight); @@ -557,7 +592,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); batch.setProjectionTransform(projMats[side]); - batch.setViewTransform(viewTransforms[side]); + batch.setViewTransform(monoViewTransform); } else { Transform model; model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z)); @@ -608,7 +643,7 @@ void DeferredLightingEffect::render(RenderArgs* args) { DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, color); batch.setProjectionTransform( projMats[side]); - batch.setViewTransform(viewTransforms[side]); + batch.setViewTransform(monoViewTransform); } else { coneParam.w = 1.0f; batch._glUniform4fv(_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam)); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index de0448a51d..db02a4e771 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -157,6 +157,7 @@ private: class DeferredTransform { public: + glm::mat4 _projection; glm::mat4 _viewInverse; float nearVal{ 1.0f }; diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index decb434177..525abf60b7 100755 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -111,7 +111,7 @@ float evalShadowAttenuation(vec4 shadowTexcoord) { return evalShadowAttenuationBasic(shadowTexcoord); } - + <@endif@> diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf index bb485c77d8..8dfd0488ac 100755 --- a/libraries/render-utils/src/directional_ambient_light.slf +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientSphereGlobalColor()$> + in vec2 _texCoord0; out vec4 _fragColor; diff --git a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf index ab8361e2dc..8ca272a9c3 100755 --- a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientSphereGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf index 1d6db7f30f..ef92e1d493 100755 --- a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf @@ -16,6 +16,8 @@ <@include DeferredBuffer.slh@> <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientSphereGlobalColor()$> // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf index 5a350f77da..07ee126bd6 100644 --- a/libraries/render-utils/src/directional_light.slf +++ b/libraries/render-utils/src/directional_light.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientGlobalColor()$> + in vec2 _texCoord0; out vec4 _fragColor; diff --git a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf index d34cb08956..a580653cb0 100644 --- a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf index ab1fb4cd69..4e0f9db360 100644 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalAmbientGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_skybox_light.slf b/libraries/render-utils/src/directional_skybox_light.slf index 5819e13e50..21ea28a681 100755 --- a/libraries/render-utils/src/directional_skybox_light.slf +++ b/libraries/render-utils/src/directional_skybox_light.slf @@ -3,20 +3,23 @@ // Generated on <$_SCRIBE_DATE$> // // directional_light.frag -// fragment shader + // Everything about deferred buffer <@include DeferredBuffer.slh@> <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalSkyboxGlobalColor()$> + in vec2 _texCoord0; out vec4 _fragColor; @@ -47,4 +50,13 @@ void main(void) { _fragColor = vec4(color, frag.normalVal.a); } + + // Debug Stereo + if (getStereoMode(deferredTransform)) { + float side = getStereoSide(deferredTransform); + // _fragColor = vec4(-side, 0.0, side, 1.0); + //_fragColor = vec4(_texCoord0, 0.0, 1.0); + // _fragColor = vec4(frag.position.xyz, 1.0); + + } } diff --git a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf index 81fb37ea10..c1fe501434 100755 --- a/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_skybox_light_cascaded_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalSkyboxGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf index 70d0f75025..df3dbc64c4 100755 --- a/libraries/render-utils/src/directional_skybox_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_skybox_light_shadow_map.slf @@ -17,6 +17,9 @@ <@include DeferredGlobalLight.slh@> +<$declareEvalLightmappedColor()$> +<$declareEvalSkyboxGlobalColor()$> + // Everything about shadow <@include Shadow.slh@> diff --git a/libraries/render-utils/src/point_light.slf b/libraries/render-utils/src/point_light.slf index 0731c36ea0..e2818754bb 100644 --- a/libraries/render-utils/src/point_light.slf +++ b/libraries/render-utils/src/point_light.slf @@ -26,11 +26,13 @@ in vec4 _texCoord0; out vec4 _fragColor; void main(void) { + DeferredTransform deferredTransform = getDeferredTransform(); + // Grab the fragment data from the uv vec2 texCoord = _texCoord0.st / _texCoord0.q; DeferredFragment frag = unpackDeferredFragment(texCoord); - mat4 invViewMat = getDeferredTransform().viewInverse; + mat4 invViewMat = deferredTransform.viewInverse; // Kill if in front of the light volume float depth = frag.depthVal; @@ -75,4 +77,12 @@ void main(void) { _fragColor = vec4(edgeCoord * edgeCoord * getLightShowContour(light) * getLightColor(light), 0.0); } } + + // Debug Stereo + if (getStereoMode(deferredTransform)) { + float side = getStereoSide(deferredTransform); + // _fragColor = vec4(-side, 0.0, side, 1.0); + // _fragColor = vec4(texCoord, 0.0, 1.0); + _fragColor = vec4(frag.position.xyz, 1.0); + } } diff --git a/libraries/render-utils/src/spot_light.slf b/libraries/render-utils/src/spot_light.slf index d8949183d6..23cde97eef 100644 --- a/libraries/render-utils/src/spot_light.slf +++ b/libraries/render-utils/src/spot_light.slf @@ -87,10 +87,12 @@ void main(void) { } } - + // Debug Stereo if (getStereoMode(deferredTransform)) { float side = getStereoSide(deferredTransform); - _fragColor = vec4(-side, 0.0, side, 1.0); + // _fragColor = vec4(-side, 0.0, side, 1.0); + // _fragColor = vec4(texCoord, 0.0, 1.0); + _fragColor = vec4(frag.position.xyz, 1.0); } }