Расчет глубины пикселя

В процессе оптимизации демки для PS3 выяснилось, что было бы неплохо оптимизировать шейдер для частиц. В вершинном шейдере происходит расчет позиций 4 вершин (частицы – билборд), а-ля point sprite, но размер указывается в world space, и частицы можно крутить. В пиксельном шейдере считается глубина, читается глубина из depth texture, и разница с коэффициентом используется как множитель к альфе.

Выглядит шейдер так:

float depth = uvDepth.z / uvDepth.w;

float4 screenDepthARGB = tex2Dproj(depthMap, uvDepth);
// B is stencil, ARG are depth bits, A is MSB, G is LSB
float screenDepth = dot(screenDepthARGB, float4(1/255.0, 1/255.0/255.0, 0, 1));

color_out = tex2D(diffuseMap, uv) * color_in;
color_out.a *= saturate((screenDepth - depth) * depthCoeff);

Одна оптимизация очевидна – в последней строчке можно либо заменить sub + mul на mad, либо просто оставить sub (умножать в VS uvDepth.z на depthCoeff, и в качестве второго аргумента dot использовать float4(1/255.0, 1/255.0/255.0, 0, 1) * depthCoeff (посчитанное на CPU, конечно же).

Хочется сказать о другой. Вычисление глубины пикселя можно вынести в VS. После того, как в первый раз натыкаешься на то, что частное интерполированных величин от интерполирования частного отличается, как-то дальше уже не приходит в голову то, что иногда – операция законна. И не дает артефактов даже теоретически.

Действительно, т.к. частицы – билборды, то во всех точках одной частицы глубина – одинаковая. Можно смело делить в VS.

Не умею правильно считать глубину, умею правильно считать глубину, умею не считать глубину правильно.

crossposted to zeux.livejournal.com

  • CEMEH

    Я нипонял, где тут SPU????

  • Sergei_am

    Ну, для смотрящих на камеру частиц ето как-то очевидно, да.
    А у вас других нет? Интересно бъло бъ там попробовать, но все равно думается что с делением в vs тоже бъло бъ ок, в массе случаев.

  • http://zeux.livejournal.com/ Zeux

    Тоже думается, что с делением в другом случае было бы ок. У нас других нет.