osg+pbr-直射光

这篇具有很好参考价值的文章主要介绍了osg+pbr-直射光。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

算法是来自于learn opengl pbr相关部分,
只考虑如何移植到osg。

1,法线如何从局部坐标系到世界坐标系(逆转置矩阵)
2,视点通过漫游器获取,
3,视点uniform指针传递给漫游器,在漫游器中改变

为了说明正确性,先把视点设置为原点,按右方向键时正常。

osg+pbr-直射光
可见,面向原点的一半是正确的。

矫正后,
osg+pbr-直射光

代码如下:
travel.h
#pragma once
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgGA/GUIEventAdapter>
#include <osgViewer/ViewerEventHandlers>
#include <osg/AnimationPath>
#include
#include <osg/PositionAttitudeTransform>
#include <osg/MatrixTransform>
#include <osgGA/CameraManipulator>
#include <osg/matrixd>
class TravelManipulator : public osgGA::CameraManipulator
{
public:
TravelManipulator();

public:
//设置当前视口
virtual void setByMatrix(const osg::Matrixd& matrix);
virtual void setByInverseMatrix(const osg::Matrixd& matrix);
//得到当前矩阵和逆矩阵
virtual osg::Matrixd getMatrix() const;
virtual osg::Matrixd getInverseMatrix() const;

virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us);
void ChangePosition(osg::Vec3d& delta);

private:
//视点
osg::Vec3 m_vPosition;
//朝向
osg::Vec3 m_vRotation;
//移动步长
int m_vStep;
//旋转步长
float m_vRotateSpeed;

//暂停
bool _bPause;

public:
//设置视点位置到shader
void setEyePosUniform(osg::ref_ptrosg::Uniform camearaPosUniform);
//
osg::ref_ptrosg::Uniform _eyePosUniform;
};
travel.cpp
#include “Travel.h”

TravelManipulator::TravelManipulator()
{
m_vPosition = osg::Vec3(0, 0, 50);
m_vRotation = osg::Vec3(osg::PI_2, 0, 0);
m_vStep = 1.0;
m_vRotateSpeed = 1.0;
_bPause = false;
_eyePosUniform = NULL;
}

void TravelManipulator::setByMatrix(const osg::Matrixd & matrix)
{
}

void TravelManipulator::setByInverseMatrix(const osg::Matrixd & matrix)
{
}

osg::Matrixd TravelManipulator::getMatrix() const
{
osg::Matrixd matTrans;
matTrans.makeTranslate(m_vPosition);
osg::Matrixd matRotate;
matRotate.makeRotate(m_vRotation[0], osg::X_AXIS, m_vRotation[1], osg::Y_AXIS, m_vRotation[2], osg::Z_AXIS);
return matRotate * matTrans;
}

osg::Matrixd TravelManipulator::getInverseMatrix() const
{
osg::Matrixd mat = getMatrix();
return osg::Matrixd::inverse(mat);
}

bool TravelManipulator::handle(const osgGA::GUIEventAdapter & ea, osgGA::GUIActionAdapter & us)
{
switch (ea.getEventType())
{
case osgGA::GUIEventAdapter::KEYDOWN:
{
//if (ea.getKey() ==‘p’)
//{
// _bPause = !_bPause;
//}
//if (_bPause)
{
if ((ea.getKey() == ‘w’) || (ea.getKey() == ‘W’) )
{
ChangePosition(osg::Vec3d(m_vStep * cosf(osg::PI_2 + m_vRotation._v[2]), m_vStep * sinf(osg::PI_2 + m_vRotation._v[2]), 0));
return true;
}
else if ((ea.getKey() == ‘s’) || (ea.getKey() == ‘S’))
{
ChangePosition(osg::Vec3d(-m_vStep * cosf(osg::PI_2 + m_vRotation._v[2]), -m_vStep * sinf(osg::PI_2 + m_vRotation._v[2]), 0));
return true;
}
else if ((ea.getKey() == ‘a’) || (ea.getKey() == ‘A’) )
{
ChangePosition(osg::Vec3d(m_vStep * sinf(osg::PI_2 + m_vRotation._v[2]), -m_vStep * cosf(osg::PI_2 + m_vRotation._v[2]), 0));
return true;
}
else if ((ea.getKey() == ‘d’) || (ea.getKey() == ‘D’) )
{
ChangePosition(osg::Vec3d(-m_vStep * sinf(osg::PI_2 + m_vRotation._v[2]), m_vStep * cosf(osg::PI_2 + m_vRotation._v[2]), 0));
return true;
}
else if ((ea.getKey() == ‘Q’) || (ea.getKey() == ‘q’))
{
ChangePosition(osg::Vec3d(0, 0, 0.2));
return true;
}
else if ((ea.getKey() == ‘E’) || (ea.getKey() == ‘e’))
{

			ChangePosition(osg::Vec3d(0, 0, -0.2));
			return true;
		}
		else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)
		{
			m_vRotation[0] += 0.2;
			if (_eyePosUniform)
			{
				//_eyePosUniform->set(m_vPosition);
			}
			return true;
		}
		else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Down)
		{

			m_vRotation[0] -= 0.2;
			if (_eyePosUniform)
			{
				//_eyePosUniform->set(m_vPosition);
			}
			return true;
		}
		else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)
		{
			m_vRotation[2] += 0.2;
			if (_eyePosUniform)
			{
				//_eyePosUniform->set(m_vPosition);
			}
			return true;
		}
		else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)
		{

			m_vRotation[2] -= 0.2;
			if (_eyePosUniform)
			{
				_eyePosUniform->set(m_vPosition);
			}
			return true;
		}
	}
}
break;
case osgGA::GUIEventAdapter::FRAME:
{
	//if (!_bPause)
	//{
	//	//m_vPosition[2] += 1;
	//}
}
	break;
default:
	break;
}
return false;

}

void TravelManipulator::ChangePosition(osg::Vec3d & delta)
{
m_vPosition += delta;
}
void TravelManipulator::setEyePosUniform(osg::ref_ptrosg::Uniform camearaPosUniform)
{
_eyePosUniform = camearaPosUniform;
}
main.cpp
//通过Liblas读取.las文件,并在osg中显示出来,用shader,先在片元着色器指定使用绿色
#include <liblas/liblas.hpp>
#include
#include

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>

#include <osg/Switch>
#include <osg/Types>
#include <osgText/Text>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>

#include <osgGA/Device>

#include
#include <osg/Shader>
#include <osg/BlendFunc>
#include <osg/blendColor>
#include <osg/Point>
#include <osg/Shapedrawable>
#include <osgUtil/SmoothingVisitor>
#include “Travel.h”

static const char * vertexShader_PBR =
{
“in vec3 aPos; \n”
“in vec3 aNormal; \n”
“varying vec3 WorldPos; \n”
“varying vec3 Normal; \n”
“uniform mat4 normalMatrix; \n”
“void main() \n”
“{ \n”
" WorldPos = aPos; \n"
" Normal = vec3(normalMatrix * vec4(aNormal,1.0)); \n"
" gl_Position = ftransform(); \n"
“}\n”
};

static const char psShader_PBR =
{
“#version 330 core \n”
“out vec4 FragColor; \n”
“varying vec3 WorldPos; \n”
“varying vec3 Normal; \n”
“uniform vec3 albedo; \n”
“uniform float metallic; \n”
“uniform float roughness; \n”
“uniform float ao; \n”
“uniform vec3 lightPositions[4]; \n”
“uniform vec3 lightColors[4]; \n”
“uniform vec3 camPos; \n”
“const float PI = 3.14159265359; \n”
“float DistributionGGX(vec3 N, vec3 H, float roughness) \n”
“{ \n”
" float a = roughness
roughness; \n"
" float a2 = aa; \n"
" float NdotH = max(dot(N, H), 0.0); \n"
" float NdotH2 = NdotH
NdotH; \n"
" float nom = a2; \n"
" float denom = (NdotH2 * (a2 - 1.0) + 1.0); \n"
" denom = PI * denom * denom; \n"
" return nom / denom; \n"
“} \n”
“float GeometrySchlickGGX(float NdotV, float roughness) \n”
“{ \n”
" float r = (roughness + 1.0); \n"
" float k = (r*r) / 8.0; \n"
" float nom = NdotV; \n"
" float denom = NdotV * (1.0 - k) + k; \n"
" return nom / denom; \n"
“} \n”
“float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) \n”
“{ \n”
" float NdotV = max(dot(N, V), 0.0); \n"
" float NdotL = max(dot(N, L), 0.0); \n"
" float ggx2 = GeometrySchlickGGX(NdotV, roughness); \n"
" float ggx1 = GeometrySchlickGGX(NdotL, roughness); \n"
" return ggx1 * ggx2; \n"
“} \n”
“vec3 fresnelSchlick(float cosTheta, vec3 F0) \n”
“{ \n”
" return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); \n"
“} \n”
“void main() \n”
“{ \n”
" vec3 N = normalize(Normal); \n"
" vec3 V = normalize(camPos - WorldPos); \n"
" vec3 F0 = vec3(0.04); \n"
" F0 = mix(F0, albedo, metallic); \n"
" vec3 Lo = vec3(0.0); \n"
" for (int i = 0; i < 4; ++i) \n"
" { \n"
" vec3 L = normalize(lightPositions[i] - WorldPos); \n"
" vec3 H = normalize(V + L); \n"
" float distance = length(lightPositions[i] - WorldPos); \n"
" float attenuation = 1.0 / (distance * distance); \n"
" vec3 radiance = lightColors[i] * attenuation; \n"
" float NDF = DistributionGGX(N, H, roughness); \n"
" float G = GeometrySmith(N, V, L, roughness); \n"
" vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0); \n"
" vec3 numerator = NDF * G * F; \n"
" float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001; \n"
" vec3 specular = numerator / denominator; \n"
" vec3 kS = F; \n"
" vec3 kD = vec3(1.0) - kS; \n"
" kD *= 1.0 - metallic; \n"
" float NdotL = max(dot(N, L), 0.0); \n"
" Lo += (kD * albedo / PI + specular) * radiance * NdotL; \n"
" } \n"
" vec3 ambient = vec3(0.03) * albedo * ao; \n"
" vec3 color = ambient + Lo; \n"
" color = color / (color + vec3(1.0)); \n"
" color = pow(color, vec3(1.0 / 2.2)); \n"
" FragColor = vec4(color, 1.0); \n"
//" FragColor = vec4(1.0,0.0,0.0, 1.0); \n"
“} \n”
};

osg::ref_ptrosg::Geode CreateSphereGeode()
{
osg::ref_ptrosg::Geode geode = new osg::Geode;
osg::ref_ptrosg::Vec3Array vertices = new osg::Vec3Array(6);
(*vertices)[0].set(0.0f, 0.0f, 1.0f);
(*vertices)[1].set(-0.5f, -0.5f, 0.0f);
(*vertices)[2].set(0.5f, -0.5f, 0.0f);
(*vertices)[3].set(0.5f, 0.5f, 0.0f);
(*vertices)[4].set(-0.5f, 0.5f, 0.0f);
(*vertices)[5].set(0.0f, 0.0f, -1.0f);
osg::ref_ptrosg::DrawElementsUInt indices = new osg::DrawElementsUInt(GL_TRIANGLES, 24);
(*indices)[0] = 0; (*indices)[1] = 1; (*indices)[2] = 2;
(*indices)[3] = 0; (*indices)[4] = 2; (*indices)[5] = 3;
(*indices)[6] = 0; (*indices)[7] = 3; (*indices)[8] = 4;
(*indices)[9] = 0; (*indices)[10] = 4; (*indices)[11] = 1;
(*indices)[12] = 5; (*indices)[13] = 2; (*indices)[14] = 1;
(*indices)[15] = 5; (*indices)[16] = 3; (*indices)[17] = 2;
(*indices)[18] = 5; (*indices)[19] = 4; (*indices)[20] = 3;
(*indices)[21] = 5; (*indices)[22] = 1; (*indices)[23] = 4;
osg::ref_ptrosg::Geometry geom = new osg::Geometry;
geom->setVertexArray(vertices.get());
geom->addPrimitiveSet(indices.get());
osgUtil::SmoothingVisitor::smooth(*geom);
geode->addDrawable(geom);
return geode;

}

osg::ref_ptrosg::Geode renderSphere(osg::Vec3f pos)
{
osg::ref_ptrosg::Geode geode = new osg::Geode;
const unsigned int X_SEGMENTS = 64;
const unsigned int Y_SEGMENTS = 64;
const float PI = 3.14159265359f;
osg::ref_ptrosg::Vec3Array vertices = new osg::Vec3Array;
osg::ref_ptrosg::Vec3Array normalArray = new osg::Vec3Array;
for (unsigned int x = 0; x <= X_SEGMENTS; ++x)
{
for (unsigned int y = 0; y <= Y_SEGMENTS; ++y)
{
float xSegment = (float)x / (float)X_SEGMENTS;
float ySegment = (float)y / (float)Y_SEGMENTS;
float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
float yPos = std::cos(ySegment * PI);
float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);

		vertices->push_back(osg::Vec3(xPos, yPos, zPos) + pos);
		normalArray->push_back(osg::Vec3(xPos, yPos, zPos));
	}
}
osg::ref_ptr<osg::DrawElementsUInt> indices = new osg::DrawElementsUInt();
bool oddRow = false;
for (unsigned int y = 0; y < Y_SEGMENTS; ++y)
{
	if (!oddRow) // even rows: y == 0, y == 2; and so on
	{
		for (unsigned int x = 0; x <= X_SEGMENTS; ++x)
		{
			indices->push_back(y       * (X_SEGMENTS + 1) + x);
			indices->push_back((y + 1) * (X_SEGMENTS + 1) + x);
		}
	}
	else
	{
		for (int x = X_SEGMENTS; x >= 0; --x)
		{
			indices->push_back((y + 1) * (X_SEGMENTS + 1) + x);
			indices->push_back(y       * (X_SEGMENTS + 1) + x);
		}
	}
	oddRow = !oddRow;
}
int indexCount = static_cast<unsigned int>(indices->size());
indices->setMode(GL_TRIANGLE_STRIP);

osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(vertices.get());
geom->addPrimitiveSet(indices.get());
geom->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX);

geom->setVertexAttribArray(1, vertices, osg::Array::BIND_PER_VERTEX);
geom->setVertexAttribArray(2, normalArray, osg::Array::BIND_PER_VERTEX);

//osgUtil::SmoothingVisitor::smooth(*geom);
geode->addDrawable(geom);
return geode;

}

int main()
{

osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<TravelManipulator> manipulator = new TravelManipulator;
viewer->setCameraManipulator(manipulator);

osg::ref_ptr<osg::Uniform> camPosUniform = new osg::Uniform("camPos", osg::Vec3f(0,0,0));
manipulator->setEyePosUniform(camPosUniform);

osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
osg::Matrix viewMatrix = camera->getViewMatrix();
osg::Matrix projMatrix = camera->getProjectionMatrix();
osg::Vec3f eye, center, up;
camera->getViewMatrixAsLookAt(eye, center, up);

//osg::ref_ptr<osg::Uniform> camPosUniform = new osg::Uniform("camPos", eye);
osg::ref_ptr<osg::Uniform> viewMatrixUniform = new osg::Uniform("view", viewMatrix);
osg::ref_ptr<osg::Uniform> projMatrixUniform = new osg::Uniform("projection", projMatrix);
osg::ref_ptr<osg::Group> grp = new osg::Group;
osg::Vec3f albedo(0.5f, 0.0f, 0.0f);
osg::ref_ptr<osg::Uniform> albedoUniform = new osg::Uniform("albedo", albedo);
float ao = 1.0f;
osg::ref_ptr<osg::Uniform> aoUniform = new osg::Uniform("ao", ao);

int nrRows = 7;
int nrColumns = 7;
float spacing = 2.5;
float ballRadius = 1.0f;

osg::ref_ptr<osg::Vec3Array> lightColors = new osg::Vec3Array;
lightColors->push_back(osg::Vec3(300.0f, 300.0f, 300.0f));
lightColors->push_back(osg::Vec3(300.0f, 300.0f, 300.0f));
lightColors->push_back(osg::Vec3(300.0f, 300.0f, 300.0f));
lightColors->push_back(osg::Vec3(300.0f, 300.0f, 300.0f));

osg::ref_ptr<osg::Uniform> lightColorsUniform = new osg::Uniform(osg::Uniform::FLOAT_VEC3, "lightColors", lightColors->size());
for (int i = 0; i < lightColors->size(); i++)
{
	lightColorsUniform->setElement(i, lightColors->at(i));
}
osg::ref_ptr<osg::Vec3Array> lightPositions = new osg::Vec3Array;
lightPositions->push_back(osg::Vec3(-10.0f, 10.0f, 10.0f));
lightPositions->push_back(osg::Vec3(10.0f, 10.0f, 10.0f));
lightPositions->push_back(osg::Vec3(-10.0f, -10.0f, 10.0f));
lightPositions->push_back(osg::Vec3(10.0f, -10.0f, 10.0f));

osg::ref_ptr<osg::Uniform> lightPositionsUniform = new osg::Uniform(osg::Uniform::FLOAT_VEC3, "lightPositions", lightPositions->size());
for (int i = 0; i < lightPositions->size(); i++)
{
	lightPositionsUniform->setElement(i, lightPositions->at(i));
}
for (int row = 0; row < nrRows; row++)
{
	float metallic = row * 1.0 / nrRows;
	for (int col = 0; col < nrColumns; col++)
	{
		float roughness = col * 1.0 / nrColumns;
		if (roughness <0.05)
		{
			roughness = 0.05;
		}
		if (roughness > 1.0)
		{
			roughness = 1.0;
		}
		osg::Vec3 ballCenter(
			(col - (nrColumns / 2)) * spacing,
			(row - (nrRows / 2)) * spacing,
			0.0f);
		osg::Matrix worldMatrix = osg::Matrix::translate(ballCenter);

		osg::Matrix inverse;
		inverse.invert(worldMatrix);
		osg::Matrix transPose;
		transPose.transpose(inverse);
		osg::ref_ptr<osg::Geode> geode = renderSphere(ballCenter);
		{
			osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();
			osg::ref_ptr<osg::Shader> vs = new osg::Shader(osg::Shader::VERTEX, vertexShader_PBR);
			osg::ref_ptr<osg::Shader> ps = new osg::Shader(osg::Shader::FRAGMENT, psShader_PBR);
			osg::ref_ptr<osg::Program> program = new osg::Program;
			program->addBindAttribLocation("aPos", 1);
			program->addBindAttribLocation("aNormal", 2);
			program->addShader(vs);
			program->addShader(ps);

			osg::ref_ptr<osg::Uniform> metallicUniform = new osg::Uniform("metallic", metallic);
			osg::ref_ptr<osg::Uniform> roughnessUniform = new osg::Uniform("roughness", roughness);
			//osg::ref_ptr<osg::Uniform> transposeInverseMatrixUniform = new osg::Uniform("normalMatrix", transPose);

			osg::Uniform* transposeInverseMatrixUniform = stateset->getOrCreateUniform("normalMatrix", osg::Uniform::FLOAT_MAT4);
			transposeInverseMatrixUniform->set(transPose);
			stateset->addUniform(albedoUniform);
			stateset->addUniform(metallicUniform);
			stateset->addUniform(roughnessUniform);
			stateset->addUniform(aoUniform);
			stateset->addUniform(lightPositionsUniform);
			stateset->addUniform(lightColorsUniform);
			stateset->addUniform(transposeInverseMatrixUniform);
			stateset->addUniform(viewMatrixUniform);
			stateset->addUniform(projMatrixUniform);
			stateset->addUniform(camPosUniform);
			stateset->setAttribute(program, osg::StateAttribute::ON);
		}
		grp->addChild(geode);
	}

}
grp->addChild(renderSphere(osg::Vec3(-10.0f, 10.0f, 10.0f)));
grp->addChild(renderSphere(osg::Vec3(10.0f, 10.0f, 10.0f)));
grp->addChild(renderSphere(osg::Vec3(-10.0f, -10.0f, 10.0f)));
grp->addChild(renderSphere(osg::Vec3(10.0f, -10.0f, 10.0f)));

viewer->getCamera()->setClearColor(osg::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
viewer->setSceneData(grp);
viewer->run();

return 0;

}文章来源地址https://www.toymoban.com/news/detail-504424.html

到了这里,关于osg+pbr-直射光的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenGL ES相关库加载3D 车辆模型

    需求类似奇瑞的这个效果,就是能全方位旋转拖拽看车,以及点击开关车门车窗后备箱等 瑞虎9全景看车 (chery.cn) 最开始收到这个需求的时候还有点无所适从,因为以前没有做过类似的效果,后面一经搜索后发现实现的方式五花八门,但始终绕不过opengl,于是通过opengl 逐步展

    2024年02月06日
    浏览(33)
  • 可信深度学习Trustworthy Deep Learning相关论文

    Survey An Overview of Catastrophic AI Risks. [paper] Connecting the Dots in Trustworthy Artificial Intelligence: From AI Principles, Ethics, and Key Requirements to Responsible AI Systems and Regulation. [paper] A Survey of Trustworthy Federated Learning with Perspectives on Security, Robustness, and Privacy. [paper] Adversarial Machine Learning: A Systemati

    2024年02月13日
    浏览(37)
  • Scikit-learn强化学习代码批注及相关练习

    一、游戏介绍 木棒每保持平衡1个时间步,就得到1分。每一场游戏的最高得分为200分每一场游戏的结束条件为木棒倾斜角度大于41.8°或者已经达到200分。最终获胜条件为最近100场游戏的平均得分高于195。代码中env.step(),的返回值就分别代表了。观测Observation:当前step执行

    2024年02月11日
    浏览(36)
  • Scikit-learn聚类方法代码批注及相关练习

    一、代码批注 代码来自:https://scikit-learn.org/stable/auto_examples/cluster/plot_dbscan.html#sphx-glr-auto-examples-cluster-plot-dbscan-py 在实验中一直有个困惑,不知道这个小圆圈是怎么画上去的。它的原因是在“db.core_sample_indices_”和“db.labels”,起初我以为“db.core_sample_indices_”会生成除噪音

    2024年02月13日
    浏览(37)
  • redis中的string相关的部分命令

    redis命令手册 redis中文官网查看文档 挨个进行输出调试 Redis Setnx 命令 Redis Getrange 命令 Redis Mset 命令 Redis Setex 命令 Redis SET 命令 Redis Get 命令 Redis Getbit 命令 Redis Setbit 命令 Redis Decr 命令 Redis Decrby 命令 Redis Strlen 命令 Redis Msetnx 命令 Redis Incrby 命令 Redis Incrbyfloat 命令 Redis Setran

    2024年02月02日
    浏览(26)
  • 使用 Elastic Learned Sparse Encoder 和混合评分的卓越相关性

    作者:The Elastic Platform team 2023 年 5 月 25 今天,我们很高兴地宣布 Elasticsearch 8.8 正式发布。 此版本为向量搜索带来了多项关键增强功能,让开发人员无需付出通常的努力和专业知识即可在搜索应用程序中利用一流的 AI 驱动技术。 使用 Elastic 专有的语义搜索转换器实现卓越的

    2024年02月06日
    浏览(41)
  • OpenGL 桶形畸变算法-常用VR

    图像放大率随着距光轴的距离而减小。在这样的畸变中,直线在中心向外凸出,像桶一样。 桶形畸变中,从图像的中心点到图像的边缘点图像的相对大小逐渐变小,看起来就像把一张正常大小的图片包裹在一个球上一样。鱼眼相机,就是利用这种类型的畸变将一个无限宽的物

    2024年04月16日
    浏览(45)
  • 深信服 网络相关面试题及部分答案

    直接开始 A: 在具备自协商能力的端口没有Link的情况下,端口一直发送FLP,在FLP中包含着自己的连接能力信息,包括支持的速率能力、双工能力、流控能力等。这个连接能力是从自协商能力寄存器中得到的(Auto-Negotiation Advertisement Register ,PHY标准寄存器地址4 )。依靠脉冲位

    2024年02月16日
    浏览(34)
  • Java中的各种引用类型以及部分引用的相关例子

    在Java中,引用类型主要有四种,分别是:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)和虚引用(Phantom Reference)。这些类型通常与垃圾回收机制有关,用来描述对象的生命周期和可达性。下面详细介绍每一种引用类型: 强引用 (Strong Reference) 强

    2024年04月13日
    浏览(41)
  • 【计算机图形学 】扫描线多边形填充算法 | OpenGL+鼠标交互

    传送门 实现多边形扫描线填充算法,并和鼠标进行交互。 具体原理略过,会贴上完整代码,可直接运行。 环境: vs2019,OpenGL的库(可以搜索如何用vs使用OpenGL的库,可以使用vs自带的插件或者其他方法,很方便) 要点: 1.NET和AET的创建,改动 2.改变鼠标点击和鼠标拖拽的响应

    2023年04月08日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包