Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   [Stage3D] Генерация ShadowMap. (http://www.flasher.ru/forum/showthread.php?t=212338)

Bletraut 20.01.2016 17:09

Генерация ShadowMap.
 
Значит решил я сделать шейдер динамических теней ShadowMapping, и столкнулся с такой проблемой. Суть алгоритма такова: вначале вся сцена отрисовывается в текстуру используя только оттенок серого (такая текстура называется shadowmap), т.е. цвет пикселя в текстуре равен глубине пикселя. Затем отрисовываются все объекты, но координата Z текущего пикселя сравнивается с соответствующим значением пикселя на shadowmap. Но проблема состоит в том, что у текстуры не хватает точности для записи глубины, т.е. координаты 30 и 60 отображаются одним цветом. Подскажите, может как-то можно повторно использовать depth-buffer или какие-то алгоритмы для теней, более точные.

Zebestov 20.01.2016 20:35

Так может не ограничивать себя оттенком серого (0-255), а "писать" глубину, используя три канала для хранения куда большего диапазона (0-16M)?

Bletraut 21.01.2016 18:10

Как мне это сделать? Допустим, как мне записать получившееся значение глубины 0.29398240345 в 3 цвета?

Zebestov 21.01.2016 18:51

Ты должен выяснить пределы. Когда тебе будут известны минимальное и максимальное значения глубины, записывай глубину как-то так:
Код AS3:

var valueRGB:uint = uint((depth - minDepthValue) / (maxDepthValue - minDepthValue) * 0xffffff);
var valueR:uint = (valueRGB >>> 16) & 0xff;
var valueG:uint = (valueRGB >>> 8) & 0xff;
var valueB:uint = (valueRGB) & 0xff;

а читай так:
Код AS3:

var valueRGB:uint = (valueR << 16) | (valueG << 8) | valueB;
var depth:Number = valueRGB / 0xffffff * (maxDepthValue - minDepthValue) + minDepthValue;

P.S.
Разумеется вот это вот (maxDepthValue - minDepthValue) лучше вычислить один раз и хранить в какой-то depthValueRange.

Bletraut 21.01.2016 19:23

Это как бы понятно. Но проблема в том, что в агал нет побитовых операций.

Zebestov 21.01.2016 19:31

Битовым операциям есть альтернатива — целочисленное деление, поиск остатка от деления, вот это вот все. Погугли, как это делается в AGAL, бо я его совершенно забыл.

Alex Lexcuk 21.01.2016 21:19

Не об этом ли речь идет?
Код AS3:

depthPassFragmentShader.assemble(Context3DProgramType.FRAGMENT,                                                                         
                                "div ft0 v0.z fc0.x \n" +        //FT0 Ranges From 0 to 1 and its the depth of the pixel from the light                                   
                                "mul ft0 ft0 fc1 \n" +        //FT0 = [FT0,255*FT0,(255^2)*FT0,(255^3)*FT0] for encoding 32 bit floating point into RGBA
                                "frc ft0 ft0 \n" +            //FT0 = [f(FT0),f(255*FT0), f((255^2)*FT0), f((255^3)*FT0)] where f(number) = number - floor(number)
                                "mul ft1 ft0.yzww fc2 \n" +    //FT1 = [(f(255*FT0))/255.0, (f((255^2)*FT0))/255.0, (f((255^3)*FT0))/255.0, 0.0]
                                "sub ft0 ft0 ft1 \n" +        //FT0 = [f(FT0) - ((f(255*FT0))/255.0), f(255*FT0) - ((f((255^2)*FT0))/255.0), f((255^2)*FT0) -  ((f((255^3)*FT0))/255.0), f((255^3)*FT0)]
                                "mov oc ft0 \n"
                                )


Bletraut 21.01.2016 21:29

Да, об этом.

Alex Lexcuk А можешь объяснить очень подробно, что тут. Просто хочу, не просто скопировать, но и понимать всё происходящее. Комментарии к коду я конечно прочитал, но хотелось бы понимать.

Добавлено через 15 минут
И это как я понял генерация шадовмапа, а где шейдер считывания глубины, вот именно само преобразование. И еще,
Код AS3:

ft0.yzww

почему именно эти компоненты, короче если можно, то все в подробностях.

Alex Lexcuk 21.01.2016 21:51

Тут разжевано
http://www.kirupa.com/forum/showthre...l-thread/page9
Код AS3:

/*
*    v0 = Pixel Position in Lights Clip Space
*  fc0 = [zFar,1.0,1.0,1.0]
*    fc1 = [1.0,255.0,65025.0,16581375.0]
*  fc2 = [(1.0/255.0),(1.0/255.0),(1.0/255.0),0.0]
*/

 
depthPassFragmentShader = new AGALMiniAssembler()
depthPassFragmentShader.assemble(Context3DProgramType.FRAGMENT,                                                                       
                                "div ft0 v0.z fc0.x \n" +        //FT0 Ranges From 0 to 1 and its the depth of the pixel from the light                                   
                                "mul ft0 ft0 fc1 \n" +        //FT0 = [FT0,255*FT0,(255^2)*FT0,(255^3)*FT0] for encoding 32 bit floating point into RGBA
                                "frc ft0 ft0 \n" +            //FT0 = [f(FT0),f(255*FT0), f((255^2)*FT0), f((255^3)*FT0)] where f(number) = number - floor(number)
                                "mul ft1 ft0.yzww fc2 \n" +    //FT1 = [(f(255*FT0))/255.0, (f((255^2)*FT0))/255.0, (f((255^3)*FT0))/255.0, 0.0]
                                "sub ft0 ft0 ft1 \n" +        //FT0 = [f(FT0) - ((f(255*FT0))/255.0), f(255*FT0) - ((f((255^2)*FT0))/255.0), f((255^2)*FT0) -  ((f((255^3)*FT0))/255.0), f((255^3)*FT0)]
                                "mov oc ft0 \n"
                                )

Так понятней будет, что там в регистрах находится.
div деление
mul умножение
frc похоже на как-бы остаток деления (не может быть больше 1 естественно)
sub вычитание
итого глубина кодируется в серо-синий с преобладанием все-же серого цвет, а потом достается снова как-то так
Код AS3:

/*
* v0 = Pixel Position In Lights Screen Space
* v1 = Pixel Position In World Space
* v2 = Vertex Normals
* v3 = Vertex UV's
* FC0 = [zFar,1.0,0.5,(-(blurSamples/2.0))]
* FC1 = [1.0,1.0,1.0,(1.0/2048.0)]
* FC2 = [1.0,(1.0/255.0),(1.0/65025.0),(1.0/16581375.0)]
* FC3 = [depthComparisonThreshold,blurSamples,shadowAlpha,0.0]
* FC4 = [lightPosition.x,lightPosition.y,lightPosition.z,0.0]
*/

 
var loopAssembly:String = ""
for ( var i:int = -(blurSamples/2.0); i < (blurSamples/2.0); i++){
    loopAssembly += "tex ft3 ft2.xy fs0<2d,wrap,linear> \n" +
                    "dp4 ft3 ft3 fc2 \n" +
                    "sub ft3 ft3 ft0 \n" +
                    "sge ft4 ft3 fc3.x \n" +
                    "add ft5 ft5 ft4 \n" +                                                           
                    "add ft2.x ft2.x fc1.w \n"
}


Bletraut 21.01.2016 22:05

А нормали ваще нужны?


Часовой пояс GMT +4, время: 15:36.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.