info@arnoldrender.ru
  • Facebook
  • Google
  • Linked-in
  • Twitter
  • Vimeo
  • Youtube
Arnoldrender
  • Главная
  • Новости
  • Эксклюзивы
  • Галерея
  • Вики
  • Скачать
  • Software
  • Форум
  • Контакты

Форум

Добро пожаловать, гость 

Показать / спрятать

Добро пожаловать, гость! Для участия в форуме требуется регистрация.

Форум » Общие вопросы » Development » user data in shaders

Страниц: 1
Автор Тема: user data in shaders


гость
Новичок
Сообщения: 9
user data in shaders
 28/06/2013 23:49

Здравствуйте.
Пытаюсь написать шейдер, но натолкнулся на проблему - не могу найти инфы, как крепить юзер дату в Init колбеке и затем доставать её в shader_evaluate для просчета. И не совсем улавливаю суть разницы между shader_evaluate и node_update, точнее для чего нужен второй колбек.
В ментал рее у каждого шейдера есть апдейт колбек, и опционально - init\destroy. Обычно я просчитываю некие данные в init, затем использую их в апдейте, и потом удаляю в destroy. Как подобное реализовать в арни ?
спасибо



admin
Администратор
Сообщения: 583
Ответ на: user data in shaders
 29/06/2013 15:29

что имеется в виду вставить юзер дата в шейдер? юзер дата по умолчанию касаются кастомных данных геометрии. То есть если ты хочешь чтобы твой шейдер ЧИТАЛ/писал юзерские дата, то как вариант ниже (исходник стандартных шейдеров USERDataColor и WriteColor). Читать их можно например как здесь.

WriteColor------------------------------------------------------------------

#include <ai.h>

#define ARNOLD_NODEID_WRITECOLOR 0x00115D10

namespace
{

enum WriteColorParams
{
p_beauty,
p_input,
p_name,
p_blend
};

};

AI_SHADER_NODE_EXPORT_METHODS(WriteColorMtd);

node_parameters
{
// Node metadata
AiMetaDataSetStr(mds, NULL, "maya.name", "aiWriteColor");
AiMetaDataSetInt(mds, NULL, "maya.id", ARNOLD_NODEID_WRITECOLOR);
AiMetaDataSetStr(mds, NULL, "maya.classification", "shader/utility");
AiMetaDataSetBool(mds, NULL, "maya.swatch", false);

AiParameterRGBA("beauty", 0.0f, 0.0f, 0.0f, 1.0f);
AiParameterRGBA("input", 0.0f, 0.0f, 0.0f, 1.0f);
AiParameterSTR("aov_name", "");
AiParameterBOOL("blend", false);
}

shader_evaluate
{
sg->out.RGBA = AiShaderEvalParamRGBA(p_beauty);

if (sg->Rt & AI_RAY_CAMERA)
{
const AtRGBA input = AiShaderEvalParamRGBA(p_input);
AiAOVSetRGBA(sg, AiShaderEvalParamStr(p_name), input);
}
}

node_initialize
{
}

node_update
{
if (AiNodeGetBool(node, "blend"))
AiAOVRegister(AiNodeGetStr(node, "aov_name"), AI_TYPE_RGB, AI_AOV_BLEND_OPACITY);
}

node_finish
{
}

USERDataColor--------------------------------------------------------------------

#include <ai.h>
#include <string.h>

#define ARNOLD_NODEID_USERDATACOLOR 0x00115D14

AI_SHADER_NODE_EXPORT_METHODS(UserDataColorMtd);

namespace
{

enum UserDataColorParams
{
p_colorAttrName,
p_defaultValue
};
}

node_parameters
{
AiMetaDataSetStr(mds, NULL, "maya.name", "aiUserDataColor");
AiMetaDataSetInt(mds, NULL, "maya.id", ARNOLD_NODEID_USERDATACOLOR);
AiMetaDataSetStr(mds, NULL, "maya.classification", "shader/utility");
AiMetaDataSetBool(mds, NULL, "maya.swatch", false);

AiParameterSTR("colorAttrName", "");
AiParameterRGB("defaultValue", 0.f, 0.f, 0.f);
}

node_initialize
{
}

node_update
{
}

node_finish
{
}

shader_evaluate
{

const AtChar *name = 0;
AtChar transp[] = "opacityPP";

AtRGB c;
AtRGBA ca;
AtVector v;
AtFloat f;

name = AiShaderEvalParamStr(p_colorAttrName);

if (strcmp (name, transp) == 0)
{
if (AiUDataGetFlt(name, &f))
{
sg->out.RGB.r = f;
sg->out.RGB.g = f;
sg->out.RGB.b = f;
}
else
{
sg->out.RGB = AiShaderEvalParamRGB(p_defaultValue);
}
}
else
{
if (AiUDataGetRGB(name, &c))
{
sg->out.RGB.r = c.r;
sg->out.RGB.g = c.g;
sg->out.RGB.b = c.b;
}
else if (AiUDataGetRGBA(name, &ca))
{
sg->out.RGB.r = ca.r;
sg->out.RGB.g = ca.g;
sg->out.RGB.b = ca.b;
}
else if (AiUDataGetVec(name, &v))
{
sg->out.RGB.r = v.x;
sg->out.RGB.g = v.y;
sg->out.RGB.b = v.z;
}
else if (AiUDataGetFlt(name, &f))
{
sg->out.RGB.r = f;
sg->out.RGB.g = f;
sg->out.RGB.b = f;
}
else
{
sg->out.RGB = AiShaderEvalParamRGB(p_defaultValue);
}
}
}



admin
Администратор
Сообщения: 583
Ответ на: user data in shaders
 29/06/2013 15:39

либо завести свой набор данных и писать/читать его - пример ниже:

Свой класс.
// OPTIONS
class COptions
{
public:
int GI_reflection_depth, GI_refraction_depth;
// int threads;

COptions() {}
COptions(AtNode *in_node)
{
GI_reflection_depth = AiNodeGetInt(in_node, "GI_reflection_depth");
GI_refraction_depth = AiNodeGetInt(in_node, "GI_refraction_depth");
// threads = AiNodeGetInt(in_node, "threads");
}
};

блок инициализации в шейдере:

node_initialize
{
COptions *currOption = (COptions*)AiMalloc(sizeof(currOption));
currOption->GI_reflection_depth = 0;
currOption->GI_refraction_depth = 0;
AiNodeSetLocalData(node, currOption);
}

далее блок апдейт нода в шейдере:
node_update
{
COptions *currOption = (COptions*)AiNodeGetLocalData(node);
AtNode* options = AiUniverseGetOptions();
currOption->GI_reflection_depth = AiNodeGetInt(options, "GI_reflection_depth");
currOption->GI_refraction_depth = AiNodeGetInt(options, "GI_refraction_depth");
}

наконец evaluate в шейдере:

shader_evaluate
{
COptions *currOption = (COptions*)AiNodeGetLocalData(node);
.....
AtColor reflection;
if (sg->Rr_refl < currOption->GI_reflection_depth)
{
AtScrSample sample;
AiTrace(&ray, &sample);
reflection = sample.color;
}
else
{
reflection = refl_exit_color;
if (refl_exit_use_env)
{
AtScrSample sample;
AiTraceBackground(&ray, &sample);
reflection *= sample.color;
}
}
.......

if (sg->Rr_refr < currOption->GI_refraction_depth)
{
AiTrace(&ray, &sample);
refraction = sample.color;
}
else
{
refraction = refr_exit_color;
if (refr_exit_use_env)
{
AiTraceBackground(&ray, &sample);
refraction *= sample.color;
}
}



гость
Новичок
Сообщения: 9
Ответ на: user data in shaders
 29/06/2013 20:07

Спасибо большое, второй вариант - то что нужно, то есть сделать некоторые вычисления на этапе инициализации, и потом обращаться к ним из shader_evaluate. Ещё вопрос, node_update - что именно этот колбек делает и при каких условиях вызывается и сколько раз ?



admin
Администратор
Сообщения: 583
Ответ на: user data in shaders
 29/06/2013 21:54

node_initialize is called only once for each instance of the shader, at the beginning of the first render.

node_update is called once per render call (so, multiple times for progressive) for each instance of the shader. And this includes the first render.

Это имелось в виду?



гость
Новичок
Сообщения: 9
Ответ на: user data in shaders
 01/07/2013 03:31

Да, похоже это, спасибо. Сбивало с толку наличие shader_eval и node_upd одновременно( и вообще сосуществование node и shader ) после ментал рея, где только shader колбеки по-факту.



admin
Администратор
Сообщения: 583
Ответ на: user data in shaders
 01/07/2013 17:48

Ну я в ментале вообще ничего не писал. Я рендерманщик. В нем я писал много и довольно сложные вещи. Могу сказать что в арнольде все довольно внятно и последовательно. Многие вещи могут казаться избыточными, но как говорится путей много. Поэтому и возможностей для реализации того или иного функционала много. Поэтому в Солиде попытались, так сказать, удовлетворить всем требованиям. Кроме того, соавтор Арнольда - Sony ImageWorks, а их сложно упрекнуть в непоследовательности и непрактичности. Если что-то есть, значит они уже напарывались и это необходимо. Если что - спрашивай, короче.

Страниц: 1

Все права защищены 2013, логотип и торговая марка Arnold Renderer принадлежит компании SolidAngle. Логотип и торговая марка Maya принадлежит компании Autodesk. Логотип и торговая марка Houdini принадлежит компании Side Effects Software. Копирование любых печатных и визуальных материалов, размещенных на сайте без ссылки на сайт arnoldrender.ru запрещены. Дизайн и разработка: BrainyLab