|
|
|||||
Генерация ShadowMap.
Значит решил я сделать шейдер динамических теней ShadowMapping, и столкнулся с такой проблемой. Суть алгоритма такова: вначале вся сцена отрисовывается в текстуру используя только оттенок серого (такая текстура называется shadowmap), т.е. цвет пикселя в текстуре равен глубине пикселя. Затем отрисовываются все объекты, но координата Z текущего пикселя сравнивается с соответствующим значением пикселя на shadowmap. Но проблема состоит в том, что у текстуры не хватает точности для записи глубины, т.е. координаты 30 и 60 отображаются одним цветом. Подскажите, может как-то можно повторно использовать depth-buffer или какие-то алгоритмы для теней, более точные.
__________________
Я заклинаю вас действовать иначе. |
|
|||||
Lorem ipsum
|
Так может не ограничивать себя оттенком серого (0-255), а "писать" глубину, используя три канала для хранения куда большего диапазона (0-16M)?
__________________
Поймай яблоко 2! |
|
|||||
Как мне это сделать? Допустим, как мне записать получившееся значение глубины 0.29398240345 в 3 цвета?
__________________
Я заклинаю вас действовать иначе. |
|
|||||
Lorem ipsum
|
Ты должен выяснить пределы. Когда тебе будут известны минимальное и максимальное значения глубины, записывай глубину как-то так:
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; var valueRGB:uint = (valueR << 16) | (valueG << 8) | valueB; var depth:Number = valueRGB / 0xffffff * (maxDepthValue - minDepthValue) + minDepthValue; Разумеется вот это вот (maxDepthValue - minDepthValue) лучше вычислить один раз и хранить в какой-то depthValueRange.
__________________
Поймай яблоко 2! |
|
|||||
Это как бы понятно. Но проблема в том, что в агал нет побитовых операций.
__________________
Я заклинаю вас действовать иначе. |
|
|||||
Lorem ipsum
|
Битовым операциям есть альтернатива — целочисленное деление, поиск остатка от деления, вот это вот все. Погугли, как это делается в AGAL, бо я его совершенно забыл.
__________________
Поймай яблоко 2! |
|
|||||
Не об этом ли речь идет?
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" )
__________________
Гоночка |
|
|||||
Да, об этом.
Alex Lexcuk А можешь объяснить очень подробно, что тут. Просто хочу, не просто скопировать, но и понимать всё происходящее. Комментарии к коду я конечно прочитал, но хотелось бы понимать. Добавлено через 15 минут И это как я понял генерация шадовмапа, а где шейдер считывания глубины, вот именно само преобразование. И еще, почему именно эти компоненты, короче если можно, то все в подробностях.
__________________
Я заклинаю вас действовать иначе. |
|
|||||
Тут разжевано
http://www.kirupa.com/forum/showthre...l-thread/page9 /* * 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 вычитание итого глубина кодируется в серо-синий с преобладанием все-же серого цвет, а потом достается снова как-то так /* * 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" }
__________________
Гоночка |
|
|||||
А нормали ваще нужны?
__________________
Я заклинаю вас действовать иначе. |
Часовой пояс GMT +4, время: 20:46. |
|
« Предыдущая тема | Следующая тема » |
|
|