mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 05:17:02 +02:00
overall clean up of th elocal light drawing to avoid the in/out pipeline case, still seeing big cost on gpu from the spot lights
This commit is contained in:
parent
0c0109e427
commit
e72791233d
8 changed files with 107 additions and 120 deletions
|
@ -167,7 +167,7 @@ void Light::setAmbientMapNumMips(uint16_t numMips) {
|
||||||
void Light::updateVolumeGeometry() {
|
void Light::updateVolumeGeometry() {
|
||||||
// enlarge the scales slightly to account for tesselation
|
// enlarge the scales slightly to account for tesselation
|
||||||
const float SCALE_EXPANSION = 0.05f;
|
const float SCALE_EXPANSION = 0.05f;
|
||||||
glm::vec4 volumeGeometry(0.0f, 0.0f, 0.0f, 1.0f); // getMaximumRadius() * (1.0f + SCALE_EXPANSION));
|
glm::vec4 volumeGeometry(0.0f, 0.0f, 0.0f, getMaximumRadius() * (1.0f + SCALE_EXPANSION));
|
||||||
|
|
||||||
if (getType() == SPOT) {
|
if (getType() == SPOT) {
|
||||||
const float TANGENT_LENGTH_SCALE = 0.666f;
|
const float TANGENT_LENGTH_SCALE = 0.666f;
|
||||||
|
|
|
@ -245,11 +245,50 @@ void DeferredLightingEffect::setGlobalLight(const model::LightPointer& light) {
|
||||||
globalLight->setAmbientMap(light->getAmbientMap());
|
globalLight->setAmbientMap(light->getAmbientMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <shared/Shapes.h>
|
||||||
|
|
||||||
|
model::MeshPointer DeferredLightingEffect::getPointLightMesh() {
|
||||||
|
if (!_pointLightMesh) {
|
||||||
|
_pointLightMesh = std::make_shared<model::Mesh>();
|
||||||
|
|
||||||
|
// let's use a icosahedron
|
||||||
|
auto solid = geometry::icosahedron();
|
||||||
|
solid.fitDimension(1.05f); // scaled to 1.05 meters, it will be scaled by the shader accordingly to the light size
|
||||||
|
|
||||||
|
int verticesSize = solid.vertices.size() * 3 * sizeof(float);
|
||||||
|
float* vertexData = (float*) solid.vertices.data();
|
||||||
|
|
||||||
|
_pointLightMesh->setVertexBuffer(gpu::BufferView(new gpu::Buffer(verticesSize, (gpu::Byte*) vertexData), gpu::Element::VEC3F_XYZ));
|
||||||
|
|
||||||
|
auto nbIndices = solid.faces.size() * 3;
|
||||||
|
|
||||||
|
gpu::uint16* indexData = new gpu::uint16[nbIndices];
|
||||||
|
gpu::uint16* index = indexData;
|
||||||
|
for (auto face : solid.faces) {
|
||||||
|
*(index++) = face[0];
|
||||||
|
*(index++) = face[1];
|
||||||
|
*(index++) = face[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
_pointLightMesh->setIndexBuffer(gpu::BufferView(new gpu::Buffer(sizeof(unsigned short) * nbIndices, (gpu::Byte*) indexData), gpu::Element::INDEX_UINT16));
|
||||||
|
delete[] indexData;
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<model::Mesh::Part> parts;
|
||||||
|
parts.push_back(model::Mesh::Part(0, nbIndices, 0, model::Mesh::TRIANGLES));
|
||||||
|
parts.push_back(model::Mesh::Part(0, nbIndices, 0, model::Mesh::LINE_STRIP)); // outline version
|
||||||
|
|
||||||
|
|
||||||
|
_pointLightMesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
|
||||||
|
}
|
||||||
|
return _pointLightMesh;
|
||||||
|
}
|
||||||
|
|
||||||
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
model::MeshPointer DeferredLightingEffect::getSpotLightMesh() {
|
||||||
if (!_spotLightMesh) {
|
if (!_spotLightMesh) {
|
||||||
_spotLightMesh = std::make_shared<model::Mesh>();
|
_spotLightMesh = std::make_shared<model::Mesh>();
|
||||||
|
|
||||||
int slices = 32;
|
int slices = 16;
|
||||||
int rings = 3;
|
int rings = 3;
|
||||||
int vertices = 2 + rings * slices;
|
int vertices = 2 + rings * slices;
|
||||||
int originVertex = vertices - 2;
|
int originVertex = vertices - 2;
|
||||||
|
@ -544,41 +583,30 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
||||||
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
|
||||||
|
|
||||||
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
|
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
|
||||||
auto monoViewport = args->_viewport;
|
auto viewport = args->_viewport;
|
||||||
|
|
||||||
// The view frustum is the mono frustum base
|
// The view frustum is the mono frustum base
|
||||||
auto viewFrustum = args->getViewFrustum();
|
auto viewFrustum = args->getViewFrustum();
|
||||||
|
|
||||||
// Eval the mono projection
|
// Eval the mono projection
|
||||||
mat4 monoProjMat;
|
mat4 projMat;
|
||||||
viewFrustum.evalProjectionMatrix(monoProjMat);
|
viewFrustum.evalProjectionMatrix(projMat);
|
||||||
|
|
||||||
// The mono view transform
|
// The view transform
|
||||||
Transform monoViewTransform;
|
Transform viewTransform;
|
||||||
viewFrustum.evalViewTransform(monoViewTransform);
|
viewFrustum.evalViewTransform(viewTransform);
|
||||||
|
|
||||||
// THe mono view matrix coming from the mono view transform
|
|
||||||
glm::mat4 monoViewMat;
|
|
||||||
monoViewTransform.getMatrix(monoViewMat);
|
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
|
||||||
|
|
||||||
auto eyePoint = viewFrustum.getPosition();
|
|
||||||
float nearRadius = glm::distance(eyePoint, viewFrustum.getNearTopLeft());
|
|
||||||
|
|
||||||
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
auto deferredLightingEffect = DependencyManager::get<DeferredLightingEffect>();
|
||||||
|
|
||||||
// Render in this side's viewport
|
// Render in this viewport
|
||||||
batch.setViewportTransform(monoViewport);
|
batch.setViewportTransform(viewport);
|
||||||
batch.setStateScissorRect(monoViewport);
|
batch.setStateScissorRect(viewport);
|
||||||
|
|
||||||
// enlarge the scales slightly to account for tesselation
|
auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), viewport);
|
||||||
const float SCALE_EXPANSION = 0.05f;
|
|
||||||
|
|
||||||
auto textureFrameTransform = gpu::Framebuffer::evalSubregionTexcoordTransformCoefficients(deferredFramebuffer->getFrameSize(), monoViewport);
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewTransform, true);
|
||||||
batch.setProjectionTransform(monoProjMat);
|
|
||||||
batch.setViewTransform(monoViewTransform, true);
|
|
||||||
|
|
||||||
// Splat Point lights
|
// Splat Point lights
|
||||||
if (points && !deferredLightingEffect->_pointLights.empty()) {
|
if (points && !deferredLightingEffect->_pointLights.empty()) {
|
||||||
|
@ -586,32 +614,26 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
||||||
batch.setPipeline(deferredLightingEffect->_pointLight);
|
batch.setPipeline(deferredLightingEffect->_pointLight);
|
||||||
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
|
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->texcoordFrameTransform, 1, reinterpret_cast< const float* >(&textureFrameTransform));
|
||||||
|
|
||||||
|
// Pojnt mesh
|
||||||
|
auto mesh = deferredLightingEffect->getPointLightMesh();
|
||||||
|
batch.setIndexBuffer(mesh->getIndexBuffer());
|
||||||
|
batch.setInputBuffer(0, mesh->getVertexBuffer());
|
||||||
|
batch.setInputFormat(mesh->getVertexFormat());
|
||||||
|
auto& spherePart = mesh->getPartBuffer().get<model::Mesh::Part>(0);
|
||||||
|
|
||||||
for (auto lightID : deferredLightingEffect->_pointLights) {
|
for (auto lightID : deferredLightingEffect->_pointLights) {
|
||||||
auto light = deferredLightingEffect->getLightStage().getLight(lightID);
|
auto light = deferredLightingEffect->getLightStage().getLight(lightID);
|
||||||
if (!light) {
|
if (!light) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// IN DEBUG: light->setShowContour(true);
|
|
||||||
batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
batch.setUniformBuffer(deferredLightingEffect->_pointLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||||
|
{
|
||||||
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
|
||||||
// glm::vec4 sphereParam(expandedRadius, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
|
||||||
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
|
||||||
/* if (glm::distance(eyePoint, glm::vec3(light->getPosition())) < expandedRadius + nearRadius) {
|
|
||||||
sphereParam.w = 0.0f;
|
|
||||||
batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
|
||||||
} else*/ {
|
|
||||||
// sphereParam.w = 1.0f;
|
|
||||||
// batch._glUniform4fv(deferredLightingEffect->_pointLightLocations->sphereParam, 1, reinterpret_cast< const float* >(&sphereParam));
|
|
||||||
|
|
||||||
Transform model;
|
Transform model;
|
||||||
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
|
model.setTranslation(glm::vec3(light->getPosition().x, light->getPosition().y, light->getPosition().z));
|
||||||
batch.setModelTransform(model.postScale(expandedRadius));
|
batch.setModelTransform(model);
|
||||||
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
|
||||||
geometryCache->renderSphere(batch);
|
batch.drawIndexed(model::Mesh::topologyToPrimitive(spherePart._topology), spherePart._numIndices, spherePart._startIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -634,34 +656,12 @@ void RenderDeferredLocals::run(const render::SceneContextPointer& sceneContext,
|
||||||
if (!light) {
|
if (!light) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// IN DEBUG:
|
|
||||||
// light->setShowContour(true);
|
|
||||||
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
batch.setUniformBuffer(deferredLightingEffect->_spotLightLocations->lightBufferUnit, light->getSchemaBuffer());
|
||||||
|
{
|
||||||
/* auto eyeLightPos = eyePoint - light->getPosition();
|
|
||||||
auto eyeHalfPlaneDistance = glm::dot(eyeLightPos, light->getDirection());
|
|
||||||
|
|
||||||
const float TANGENT_LENGTH_SCALE = 0.666f;
|
|
||||||
glm::vec4 coneParam(light->getSpotAngleCosSin(), TANGENT_LENGTH_SCALE * tanf(0.5f * light->getSpotAngle()), 1.0f);
|
|
||||||
|
|
||||||
float expandedRadius = light->getMaximumRadius() * (1.0f + SCALE_EXPANSION);
|
|
||||||
// TODO: We shouldn;t have to do that test and use a different volume geometry for when inside the vlight volume,
|
|
||||||
// we should be able to draw thre same geometry use DepthClamp but for unknown reason it's s not working...
|
|
||||||
const float OVER_CONSERVATIVE_SCALE = 1.1f;
|
|
||||||
if ((eyeHalfPlaneDistance > -nearRadius) &&
|
|
||||||
(glm::distance(eyePoint, glm::vec3(light->getPosition())) < (expandedRadius * OVER_CONSERVATIVE_SCALE) + nearRadius)) {
|
|
||||||
coneParam.w = 0.0f;
|
|
||||||
batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
|
||||||
} else*/ {
|
|
||||||
// coneParam.w = 1.0f;
|
|
||||||
// batch._glUniform4fv(deferredLightingEffect->_spotLightLocations->coneParam, 1, reinterpret_cast< const float* >(&coneParam));
|
|
||||||
|
|
||||||
Transform model;
|
Transform model;
|
||||||
model.setTranslation(light->getPosition());
|
model.setTranslation(light->getPosition());
|
||||||
model.postRotate(light->getOrientation());
|
model.postRotate(light->getOrientation());
|
||||||
// model.postScale(glm::vec3(expandedRadius, expandedRadius, expandedRadius));
|
|
||||||
|
|
||||||
batch.setModelTransform(model);
|
batch.setModelTransform(model);
|
||||||
|
|
||||||
batch.drawIndexed(model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);
|
batch.drawIndexed(model::Mesh::topologyToPrimitive(conePart._topology), conePart._numIndices, conePart._startIndex);
|
||||||
|
|
|
@ -73,6 +73,8 @@ private:
|
||||||
bool _shadowMapEnabled{ false };
|
bool _shadowMapEnabled{ false };
|
||||||
bool _ambientOcclusionEnabled{ false };
|
bool _ambientOcclusionEnabled{ false };
|
||||||
|
|
||||||
|
model::MeshPointer _pointLightMesh;
|
||||||
|
model::MeshPointer getPointLightMesh();
|
||||||
model::MeshPointer _spotLightMesh;
|
model::MeshPointer _spotLightMesh;
|
||||||
model::MeshPointer getSpotLightMesh();
|
model::MeshPointer getSpotLightMesh();
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,10 @@ void evalLightingPoint(out vec3 diffuse, out vec3 specular, Light light,
|
||||||
|
|
||||||
if (isShowLightContour() > 0.0) {
|
if (isShowLightContour() > 0.0) {
|
||||||
// Show edge
|
// Show edge
|
||||||
float edge = abs(2.0 * ((getLightRadius(light) - fragLightDistance) / (0.1)) - 1.0);
|
float edge = abs(2.0 * ((getLightCutoffRadius(light) - fragLightDistance) / (0.1)) - 1.0);
|
||||||
if (edge < 1) {
|
if (edge < 1) {
|
||||||
float edgeCoord = exp2(-8.0*edge*edge);
|
float edgeCoord = exp2(-8.0*edge*edge);
|
||||||
diffuse = vec3(edgeCoord * edgeCoord * getLightShowContour(light) * getLightColor(light));
|
diffuse = vec3(edgeCoord * edgeCoord * getLightColor(light));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ void evalLightingSpot(out vec3 diffuse, out vec3 specular, Light light,
|
||||||
|
|
||||||
if (isShowLightContour() > 0.0) {
|
if (isShowLightContour() > 0.0) {
|
||||||
// Show edges
|
// Show edges
|
||||||
float edgeDistR = (getLightRadius(light) - fragLightDistance);
|
float edgeDistR = (getLightCutoffRadius(light) - fragLightDistance);
|
||||||
float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light));
|
float edgeDistS = dot(fragLightDistance * vec2(cosSpotAngle, sqrt(1.0 - cosSpotAngle * cosSpotAngle)), -getLightSpotOutsideNormal2(light));
|
||||||
float edgeDist = min(edgeDistR, edgeDistS);
|
float edgeDist = min(edgeDistR, edgeDistS);
|
||||||
float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0);
|
float edge = abs(2.0 * (edgeDist / (0.1)) - 1.0);
|
||||||
|
|
|
@ -18,27 +18,27 @@
|
||||||
|
|
||||||
<$declareStandardTransform()$>
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
<!<@include model/Light.slh@>!>
|
<@include model/Light.slh@>
|
||||||
|
|
||||||
|
|
||||||
out vec4 _texCoord0;
|
out vec4 _texCoord0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 sphereVertex = inPosition;
|
vec4 sphereVertex = inPosition;
|
||||||
// vec4 sphereParam = getLightVolumeGeometry(getLight());
|
vec4 sphereParam = getLightVolumeGeometry(getLight());
|
||||||
|
|
||||||
// sphereVertex.xyz *= sphereParam.w;
|
sphereVertex.xyz *= sphereParam.w;
|
||||||
|
|
||||||
// standard transform
|
// standard transform
|
||||||
TransformCamera cam = getTransformCamera();
|
TransformCamera cam = getTransformCamera();
|
||||||
TransformObject obj = getTransformObject();
|
TransformObject obj = getTransformObject();
|
||||||
<$transformModelToClipPos(cam, obj, sphereVertex, gl_Position)$>;
|
<$transformModelToClipPos(cam, obj, sphereVertex, gl_Position)$>;
|
||||||
|
|
||||||
vec4 projected = gl_Position / gl_Position.w;
|
vec4 projected = gl_Position / gl_Position.w;
|
||||||
projected.xy = (projected.xy + 1.0) * 0.5;
|
projected.xy = (projected.xy + 1.0) * 0.5;
|
||||||
|
|
||||||
if (cam_isStereo()) {
|
if (cam_isStereo()) {
|
||||||
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
||||||
}
|
}
|
||||||
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,53 +20,36 @@
|
||||||
|
|
||||||
<@include model/Light.slh@>
|
<@include model/Light.slh@>
|
||||||
|
|
||||||
|
|
||||||
out vec4 _texCoord0;
|
out vec4 _texCoord0;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 coneVertex = inPosition;
|
vec4 coneVertex = inPosition;
|
||||||
// if (coneParam.w != 0.0) {
|
|
||||||
vec4 coneParam = getLightVolumeGeometry(getLight());
|
vec4 coneParam = getLightVolumeGeometry(getLight());
|
||||||
if(coneVertex.z >= 0.0) {
|
|
||||||
// Evaluate the true position of the spot volume
|
|
||||||
vec2 dir = float(coneVertex.z < 0.5f) * (coneParam.xy
|
|
||||||
+ vec2(coneParam.y, -coneParam.x) * coneParam.z * float(coneVertex.z > 0.0f))
|
|
||||||
+ float(coneVertex.z > 0.5f) * (vec2(1.0, 0.0)
|
|
||||||
+ vec2(0.0, coneParam.z) * float(coneVertex.z < 1.0f));
|
|
||||||
|
|
||||||
coneVertex.xy *= dir.y;
|
if(coneVertex.z >= 0.0) {
|
||||||
coneVertex.z = -dir.x;
|
// Evaluate the true position of the spot volume
|
||||||
} else {
|
vec2 dir = float(coneVertex.z < 0.5f) * (coneParam.xy
|
||||||
coneVertex.z = 0.0;
|
+ vec2(coneParam.y, -coneParam.x) * coneParam.z * float(coneVertex.z > 0.0f))
|
||||||
}
|
+ float(coneVertex.z > 0.5f) * (vec2(1.0, 0.0)
|
||||||
|
+ vec2(0.0, coneParam.z) * float(coneVertex.z < 1.0f));
|
||||||
|
|
||||||
coneVertex.xyz *= coneParam.w;
|
coneVertex.xy *= dir.y;
|
||||||
|
coneVertex.z = -dir.x;
|
||||||
|
} else {
|
||||||
|
coneVertex.z = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
// standard transform
|
coneVertex.xyz *= coneParam.w;
|
||||||
TransformCamera cam = getTransformCamera();
|
|
||||||
TransformObject obj = getTransformObject();
|
|
||||||
<$transformModelToClipPos(cam, obj, coneVertex, gl_Position)$>;
|
|
||||||
vec4 projected = gl_Position / gl_Position.w;
|
|
||||||
projected.xy = (projected.xy + 1.0) * 0.5;
|
|
||||||
|
|
||||||
if (cam_isStereo()) {
|
// standard transform
|
||||||
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
TransformCamera cam = getTransformCamera();
|
||||||
}
|
TransformObject obj = getTransformObject();
|
||||||
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
<$transformModelToClipPos(cam, obj, coneVertex, gl_Position)$>;
|
||||||
/* } else {
|
vec4 projected = gl_Position / gl_Position.w;
|
||||||
const float depth = -1.0; //Draw at near plane
|
projected.xy = (projected.xy + 1.0) * 0.5;
|
||||||
const vec4 UNIT_QUAD[4] = vec4[4](
|
|
||||||
vec4(-1.0, -1.0, depth, 1.0),
|
|
||||||
vec4(1.0, -1.0, depth, 1.0),
|
|
||||||
vec4(-1.0, 1.0, depth, 1.0),
|
|
||||||
vec4(1.0, 1.0, depth, 1.0)
|
|
||||||
);
|
|
||||||
vec4 pos = UNIT_QUAD[gl_VertexID];
|
|
||||||
|
|
||||||
_texCoord0 = vec4((pos.xy + 1) * 0.5, 0.0, 1.0);
|
if (cam_isStereo()) {
|
||||||
if (cam_isStereo()) {
|
projected.x = 0.5 * (projected.x + cam_getStereoSide());
|
||||||
_texCoord0.x = 0.5 * (_texCoord0.x + cam_getStereoSide());
|
}
|
||||||
}
|
_texCoord0 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w;
|
||||||
gl_Position = pos;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,5 +77,7 @@ void main(void) {
|
||||||
|
|
||||||
_fragColor.rgb += diffuse;
|
_fragColor.rgb += diffuse;
|
||||||
_fragColor.rgb += specular;
|
_fragColor.rgb += specular;
|
||||||
|
|
||||||
|
// _fragColor.rgb = vec3(0.0, 1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue