HLSL一个如何可以通过数据之间的着色器/读现有颜色的价值?
-
25-09-2019 - |
题
我有2HLSL ps2。0着色器。简化,它们是:
着色1
- 读纹理
- 输出色的价值基于这样的纹理
2色器
- 问题:需要阅读的颜色从1色器
- 输出最终的颜色,这是一个输入功能的颜色
(他们需要的不同的着色,因为我已经达到的最高的顶点色器输出为1色器)
我的问题是我无法工作,如何着色2可以访问现有的片段/素的颜色。
知道如何做这些事情的任何与HLSL会解决我的问题;
- 阅读现有素的色彩(我不认为这是可能的)
- 通过的结果的着色1至2色器作为一个float4
- 呈现的结果的着色1作为一个纹理在存储器,并有着色2读,
解决方案 3
合成脚本似乎是唯一用于全屏(或更准确地、全视)的影响。
呈现纹理的路要走。这不一定是完成了与合成的脚本。
这个线程 我在魔鬼的论坛进入更多的细节;
Ogre::Root r(...);
Ogre::RenderWindow* window = r.createRenderWindow(...);
//...
Ogre::SceneManager* sm = r.createSceneManager(Ogre::ST_GENERIC, "sm");
//...
//Main scene camera
Ogre::Camera* c = sm->createCamera("camera");
{
c->setNearClipDistance(5);
Ogre::Viewport* v = window->addViewport(c);
v->setBackgroundColour (Ogre::ColourValue(0, 0, 0));
c->setAspectRatio (static_cast<double> (v->getActualWidth ()) / v->getActualHeight ());
}
//RTT
Ogre::TexturePtr ptrTexture = Ogre::TextureManager::getSingleton().createManual(
"RttTex",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D,
512,//window->getWidth(),
512,//window->getHeight(),
0, //MIP_DEFAULT?
Ogre::PF_R8G8B8,
Ogre::TU_RENDERTARGET,
0
);
Ogre::RenderTexture* renderTexture = ptrTexture->getBuffer()->getRenderTarget();
renderTexture->setAutoUpdated(true);
//Create material to use with rect
{
//You should replace this with the material you wish to render to texture
//It can be defined in c++ (as this is) or in a material script
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("material", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::Technique* tech = material->createTechnique();
tech->createPass();
material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
material->getTechnique(0)->getPass(0)->createTextureUnitState("my_square_texture.dds");
}
//Create rect2D in yz plane to which we will draw our textures
//Most likely you'll wish to reposition the node so it's offscreen
const static float r_dimension = 1000.0;
Ogre::SceneNode* rect_node = sm->getRootSceneNode()->createChildSceneNode("rect_node");
{
Ogre::ManualObject *rect = sm->createManualObject("rect");
rect->begin("material", Ogre::RenderOperation::OT_TRIANGLE_FAN);
rect->position(0, r_dimension, r_dimension);
rect->textureCoord(0,0);
rect->normal(0, 1, 0);
rect->position(0, -r_dimension, r_dimension);
rect->textureCoord(0,1);
rect->normal(0, 1, 0);
rect->position(0, -r_dimension, -r_dimension);
rect->textureCoord(1,1);
rect->normal(0, 1, 0);
rect->position(0, r_dimension, -r_dimension);
rect->textureCoord(1,0);
rect->normal(0, 1, 0);
rect->end();
rect_node->attachObject(rect);
}
//Create camera, make it look at this rect2D
Ogre::Camera* rtt_cam = sm->createCamera("rtt_cam");
//Use same FOV as main camera
Ogre::Radian fov_y = c->getFOVy();
rtt_cam->setFOVy(fov_y);
//Position the camera such that the texture fills the viewpoint
{
//Angle from normal (ie, "vector origin->camera") to to top of tecture is FOV/2
//Distance origin to top of texture is r_dimension
double cam_to_rect_distance = r_dimension/tan((fov_y.valueRadians())/2);
rtt_cam->setPosition(cam_to_rect_distance, 0, 0);
rtt_cam->lookAt(rect_node->getPosition());
}
//Debug using main window
//window->addViewport(rtt_cam);
//Write to RTT
Ogre::Viewport* v = renderTexture->addViewport(rtt_cam);
v->setClearEveryFrame(true); //You may wish to set this to false and render only when your material updates/changes
v->setBackgroundColour(Ogre::ColourValue::Blue); //Debug colour. If we see blue border in RTT our cam position is wrong.
v->setOverlaysEnabled(false); //We don't want overlays to show up on the RTT
//TEMP Create debug screen (lifted from Ogre Tutorial 7)
//Draws the result of RTT onscreen picture-in-picture
{
Ogre::Rectangle2D *miniScreen = new Ogre::Rectangle2D(true);
miniScreen->setCorners(0.5f, -0.5f, 1.0f, -1.0f);
//miniScreen->setBoundingBox(Ogre::AxisAlignedBox(-100000.0f * Ogre::Vector3::UNIT_SCALE, 100000.0f * Ogre::Vector3::UNIT_SCALE));
Ogre::SceneNode* miniScreenNode = sm->getRootSceneNode()->createChildSceneNode("MiniScreenNode");
miniScreenNode->attachObject(miniScreen);
//Create material to read result of Rtt, purely for debug purposes
Ogre::MaterialPtr screenMaterial = Ogre::MaterialManager::getSingleton().create("ScreenMatt", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
Ogre::Technique* screenTechnique = screenMaterial->createTechnique();
screenTechnique->createPass();
screenMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
screenMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("RttTex");
miniScreen->setMaterial("ScreenMatt");
//TODO ideally we'd have render target listeners call setVisible(false) on pre update and setVisible(true) post update,
//so we don't get the infinite line picture-in-picture-in-picture in the preview window.
}
//Now you can bind your shader's material script to the rtt
{
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName("your_material_name");
Ogre::Technique *technique = material->getTechnique(0);
Ogre::Pass *pass = technique->getPass(0);
Ogre::TextureUnitState *tunit = pass->getTextureUnitState("your_materials_tunit_name");
tunit->setTextureName("Rtt");
}
//...
while (! window->isClosed ()) {
//...
r.renderOneFrame();
}
其他提示
备选案文3:
你HLSL码将简单,第二色器将只是试样从一个texture2d,它和und,为它的计算。
你会需要绘制一个 呈现目标 与您第一次色器,然后你可以结合渲染的目标到一个纹理,并获得它从第二色器,如果它是任何其他texture2d,它.注意,你可以不读,从一个呈现的目标,是当前设定的,所以设置回来的帧缓冲区之前,你的第二通过。
此外,解释如何你已经成功地达到极限于顶点色器输出?我很好奇:P.
做你想要什么,你可以开关呈现目标的执行之间的shader1和shader2.你输出你的第一个着色到一个纹然后你通过这个纹理你的第二色器。
这样做是怪物与 合成的脚本 和目标。
不隶属于 StackOverflow