|
3D-программирование Вопросы, касающиеся программирования 3D мира |
06.07.2011, 01:45
|
#151
|
Дэвелопер
Регистрация: 06.04.2009
Адрес: Запорожье
Сообщений: 1,500
Написано 1,011 полезных сообщений (для 4,642 пользователей)
|
Ответ: Имитация водной поверхности.
Для тех, кто знает, что такое projection matrix, описание вообще не надо. Остальным лучше вообще не трогать.
Вы вообще что пытаетесь сделать, уважаемый?
__________________
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо .Squid за это полезное сообщение:
|
|
06.07.2011, 02:20
|
#152
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
Освоить хорс тридэ.
А в данный момент, пытался нащупать четыре точки пересечения четырех комплектов трех плоскостей.(получилось почему то, что точки получаются сзади камеры, видимо с плоскостями формирующими пирамиду обзора накосячил, т.к. точки пересечения имеют y=0)
Xz из координат мира(тформенная в координаты камеры), левая боковая и нижняя клиплайны камеры, если не путаю терминологию, чтобы получить соответствующую точку на мировой xz. И так для каждого угла экрана.
Зачем мне это понадобилось? Вот таким действием я хочу получить зону видимости камеры по плоскости xz, затем заполнить её треугольниками. Потом деформировать полученный меш получая данные из массива 1024х1024 или больше.
|
(Offline)
|
|
06.07.2011, 15:21
|
#153
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
Работать с прямыми и маркерами, оказалось куда легче и прозрачней
Include "xors3d.bb"
Global pivot,camera,mxs#,mys#,Light,ball
Global lefttop,leftdown,righttop,rightdown
Dim ScreenData#(4,3)
xGraphics3D(1024,600, 32,0, 0)
pivot=xCreatePivot()
camera = xCreateCamera(pivot)
light = xCreateLight()
For i=0 To 50
gg=xCreateCube()
xPositionEntity gg,Rnd(0,50),0,Rnd(0,50)
Next
SetMarkers(150,34,19)
bh0=xCreateCube()
xScaleEntity bh0,0.5,0.5,0.5
xEntityColor bh0,255,255,0
bh1=xCopyEntity(bh0)
bh2=xCopyEntity(bh0)
bh3=xCopyEntity(bh0)
While(Not (xKeyHit(KEY_ESCAPE) Or xWinMessage("WM_CLOSE")))
xPositionEntity bh0,ScreenData#(0,0),ScreenData#(0,1),ScreenData#(0,2)
xPositionEntity bh1,ScreenData#(1,0),ScreenData#(1,1),ScreenData#(1,2)
xPositionEntity bh2,ScreenData#(2,0),ScreenData#(2,1),ScreenData#(2,2)
xPositionEntity bh3,ScreenData#(3,0),ScreenData#(3,1),ScreenData#(3,2)
xUpdateWorld
xRenderWorld()
DrawLine()
Control(1.1,1)
xFlip()
Wend
End
Function DrawLine()
;входные значения
;камера это точка с индексом 1
x000#=xEntityX(camera,1)
y000#=xEntityY(camera,1)
z000#=xEntityZ(camera,1)
;нижний левый
x00#=xEntityX(leftdown,1)
y00#=xEntityY(leftdown,1)
z00#=xEntityZ(leftdown,1)
;верхний левый
x01#=xEntityX(lefttop,1)
y01#=xEntityY(lefttop,1)
z01#=xEntityZ(lefttop,1)
;верхний правый
x11#=xEntityX(righttop,1)
y11#=xEntityY(righttop,1)
z11#=xEntityZ(righttop,1)
;нижний правый
x10#=xEntityX(rightdown,1)
y10#=xEntityY(rightdown,1)
z10#=xEntityZ(rightdown,1)
; теперь построю четыре прямых по уравнению (x-x1)/(x2-x1)=(y-y1)/(y2-y1)=(z-z1)/(z2-z1)
; точка левого нижнего угла. Так как проецирую на xz то у=0
Mdly#=-y000/(y00-y000)
Mdlx#=mdly*(x00-x000)+x000
Mdlz#=mdly*(z00-z000)+z000
; точка левого верхнего угла. Так как проецирую на xz то у=0
Mtly#=-y000/(y01-y000)
Mtlx#=mtly*(x01-x000)+x000
Mtlz#=mtly*(z01-z000)+z000
; точка правого верхнего угла. Так как проецирую на xz то у=0
MtRy#=-y000/(y11-y000)
MtRx#=mtRy*(x11-x000)+x000
MtRz#=mtRy*(z11-z000)+z000
; точка правого нижнего угла. Так как проецирую на xz то у=0
MDRy#=-y000/(y10-y000)
MDRx#=mDRy*(x10-x000)+x000
MDRz#=mDRy*(z10-z000)+z000
;левый нижний
ScreenData#(0,0)=Mdlx#
ScreenData#(0,1)=0
ScreenData#(0,2)=Mdlz#
;левый верхний
ScreenData#(1,0)=Mtlx#
ScreenData#(1,1)=0
ScreenData#(1,2)=Mtlz#
;праввый верхний
ScreenData#(2,0)=MtRx#
ScreenData#(2,1)=0
ScreenData#(2,2)=MtRz#
;правый нижний
ScreenData#(3,0)=MDRx#
ScreenData#(3,1)=0
ScreenData#(3,2)=MDRz#
;теперь проверка на расстояние, что бы спроецированные точки не были дальше от камеры, чем маркеры
;в данных камеры это выполняется легко
;проверка левого нижнего угла
xTFormPoint ScreenData#(0,0),ScreenData#(0,1),ScreenData#(0,2),0,camera
If xTFormedZ()>xEntityZ(leftdown) Then
ScreenData#(0,0)=xEntityX(leftdown,1)
ScreenData#(0,2)=xEntityZ(leftdown,1)
EndIf
;проверка левого верхнего угла
xTFormPoint ScreenData#(1,0),ScreenData#(1,1),ScreenData#(1,2),0,camera
If xTFormedZ()>xEntityZ(lefttop) Then
ScreenData#(1,0)=xEntityX(lefttop,1)
ScreenData#(1,2)=xEntityZ(lefttop,1)
EndIf
;проверка правого верхнего угла
xTFormPoint ScreenData#(2,0),ScreenData#(2,1),ScreenData#(2,2),0,camera
If xTFormedZ()>xEntityZ(righttop) Then
ScreenData#(2,0)=xEntityX(righttop,1)
ScreenData#(2,2)=xEntityZ(righttop,1)
EndIf
;проверка левого верхнего угла
xTFormPoint ScreenData#(3,0),ScreenData#(3,1),ScreenData#(3,2),0,camera
If xTFormedZ()>xEntityZ(rightdown) Then
ScreenData#(3,0)=xEntityX(rightdown,1)
ScreenData#(3,2)=xEntityZ(rightdown,1)
EndIf
; теперь проверка ставящая точку в правильное место если она оказалась за позади камеры
;проверка левого нижнего угла
xTFormPoint ScreenData#(0,0),ScreenData#(0,1),ScreenData#(0,2),0,camera
If xTFormedZ()<0 Then
ScreenData#(0,0)=xEntityX(leftdown,1)
ScreenData#(0,2)=xEntityZ(leftdown,1)
EndIf
;проверка левого верхнего угла
xTFormPoint ScreenData#(1,0),ScreenData#(1,1),ScreenData#(1,2),0,camera
If xTFormedZ()<0 Then
ScreenData#(1,0)=xEntityX(lefttop,1)
ScreenData#(1,2)=xEntityZ(lefttop,1)
EndIf
;проверка правого верхнего угла
xTFormPoint ScreenData#(2,0),ScreenData#(2,1),ScreenData#(2,2),0,camera
If xTFormedZ()<0 Then
ScreenData#(2,0)=xEntityX(righttop,1)
ScreenData#(2,2)=xEntityZ(righttop,1)
EndIf
;проверка левого верхнего угла
xTFormPoint ScreenData#(3,0),ScreenData#(3,1),ScreenData#(3,2),0,camera
If xTFormedZ()<0 Then
ScreenData#(3,0)=xEntityX(rightdown,1)
ScreenData#(3,2)=xEntityZ(rightdown,1)
EndIf
End Function
Function SetMarkers(distance#,yaw#,pitch#)
;yaw#=34 ;36
;pitch#=19 ;19.5
lefttop=xCreateCube(camera)
xEntityColor lefttop,255,0,0
leftdown=xCopyEntity(lefttop,camera)
righttop=xCopyEntity(lefttop,camera)
rightdown=xCopyEntity(lefttop,camera)
xr#=-Sin(yaw)*distance
yr#=Cos(yaw)*distance
zbh#=Sin(pitch)*distance
zbd#=Sin(-pitch)*distance
xPositionEntity lefttop,xr,zbh,yr
xPositionEntity leftdown,xr,zbd,yr
xPositionEntity righttop,-xr,zbh,yr
xPositionEntity rightdown,-xr,zbd,yr
End Function
Function control(speed#,mousesensitivity#)
If xKeyDown(key_1) Then xWireframe(True) Else xWireframe(False)
xText(10, 10, "FPS: " + xGetFPS())
xText(10,30,"Trisinview: "+xTrisRendered ())
mxs#=mxs#+(xMouseXSpeed()/5.0)
mys#=mys#+(xMouseYSpeed()/5.0)
xRotateEntity (camera,mousesensitivity#*mys#,-mousesensitivity#*mxs#,0)
xMoveMouse xGraphicsWidth()/2,xGraphicsHeight()/2
If xKeyDown(17) Or xKeyDown(200) xMoveEntity camera,0,0,speed#
If xKeyDown(31) Or xKeyDown(208) xMoveEntity camera,0,0,-speed#
If xKeyDown(30) Or xKeyDown(203) xMoveEntity camera,-speed#,0,0
If xKeyDown(32) Or xKeyDown(205) xMoveEntity camera,speed#,0,0
xPositionEntity pivot,xEntityX#(camera,1),xEntityY#(camera,1),xEntityZ#(camera,1)
xPositionEntity camera,0,0,0
End Function
|
(Offline)
|
|
07.07.2011, 01:01
|
#154
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
Вот этот пример террэйна в атаче сильно страшный или пойдет?
Последний раз редактировалось dsd, 10.08.2011 в 03:06.
|
(Offline)
|
|
07.07.2011, 02:26
|
#155
|
злобный флудер
Регистрация: 10.07.2007
Сообщений: 2,585
Написано 789 полезных сообщений (для 1,476 пользователей)
|
Ответ: Имитация водной поверхности.
А чо, мне нравится. Тока воду надо как-то подстрайвать под положение камеры и часть террейна иногда пропадает, опять-же при определенном положений камеры.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
08.07.2011, 23:07
|
#156
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
Внезапно осознал как ускорить свой генератор высот во много раз. Теперь изображение генерируется раз в 10 дольше массива. Плюс добавил отрисовку уровня моря и еще кое что.
Кстати, а почему шаг в цикле for ... next нельзя менять даже вне цикла?
Global xelements=1024,maxd,img,h#
Global sealevel#=0.15
Global MountainDiff=4
Graphics3D 536,536,0,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()
z=Rand(20,4500)
While Not z=0 Or KeyHit(1)
maxd=maxd+1
z=xelements Shr maxd
Wend
maxd=maxd-1
Print "number of repetitions: "+maxd
Dim heightmap#(xelements,xelements,2)
heightmap#(0,0,0)=Rnd(-5,5) heightmap#(0,0,1)=1
heightmap#(xelements-1,0,0)=Rnd(-5,5) heightmap#(xelements-1,0,1)=1
heightmap#(0,xelements-1,0)=Rnd(-5,5) heightmap#(0,xelements-1,0)=1
heightmap#(xelements-1,xelements-1,0)=Rnd(-5,5) heightmap#(xelements-1,xelements-1,0)=1
h00#=heightmap#(0,0,0)
h10#=heightmap#(xelements-1,0,0)
h01#=heightmap#(0,xelements-1,0)
h11#=heightmap#(xelements-1,xelements-1,0)
For d=maxd To 1 Step -1
bz=2^(d-1)
x0=0
While Not x0>( xelements-1)
y0=0
While Not y0>( xelements-1)
x000=Abs((x0-bz) Mod xelements)
y000=Abs((y0-bz) Mod xelements)
x001=Abs((x0+bz)Mod xelements)
y001=Abs((y0+bz)Mod xelements)
x002=Abs((x0+bz-1)Mod xelements)
y002=Abs((y0+bz-1)Mod xelements)
x00#=heightmap#(x000,y000,0)
x01#=heightmap#(x001,y000,0)
x10#=heightmap#(x000,y001,0)
x11#=heightmap#(x001,y001,0)
If heightmap#(x001,y001,1)=1 And heightmap#(x000,y001,1)=1 And heightmap#(x001,y000,1)=1 And heightmap#(x000,y000,1)=1 Then
heightmap#(x0,y0,0)=(x00+x01+x10+x11)/4+1.44*bz*Rnd(-0.2,0.2)
heightmap#(x000,y0,0)=(x00+x10)/2+bz*Rnd(-0.1,0.1)
heightmap#(x001,y0,0)=(x01+x11)/2+bz*Rnd(-0.1,0.1)
heightmap#(x0,y000,0)=(x00+x01)/2+bz*Rnd(-0.1,0.1)
heightmap#(x0,y001,0)=(x11+x10)/2+bz*Rnd(-0.1,0.1)
heightmap#(x0,y0,1)=1
heightmap#(x000,y0,1)=1
heightmap#(x001,y0,1)=1
heightmap#(x0,y000,1)=1
heightmap#(x0,y001,1)=1
EndIf
y0=y0+bz
Wend
x0=x0+bz
Wend
Print Abs((d-maxd)*100/maxd)+"% "+(xelements-1)Mod (1 Shl d) + " " + bz
Next
Print "Array is ready"
Print "resize of array elements just started"
hmax#=0
hmin#=0
For x=1 To xelements
For y=1 To xelements
x0=x-1
y0=y-1
If heightmap#(x0,y0,0)>hmax Then hmax=heightmap#(x0,y0,0)
If heightmap#(x0,y0,0)<hmin Then hmin=heightmap#(x0,y0,0)
Next
Next
h#=hmax-hmin
For x=1 To xelements
For y=1 To xelements
x0=x-1
y0=y-1
heightmap#(x0,y0,0)=((heightmap#(x0,y0,0)-hmin)/h)^MountainDiff
Next
Next
MakeImage()
ResizeImage img,512,512
While Not ((KeyDown(56) And KeyHit(62)) Or (KeyHit(56) And KeyDown(62)) Or KeyHit(1))
UpdateWorld
RenderWorld
ClsColor 0,75,151
Cls
DrawImage img,12,12
;Text 200,400,17 Mod (1 Shl 8)
;Text 200,420,hmin+" "+hmax
Text 0,0,1 Shl 8
Flip
Wend
End
Function MakeImage()
Print "Making image"
img=CreateImage(xelements,xelements)
SetBuffer ImageBuffer(img)
ClsColor 255,0,0
Cls
For x=1 To xelements
For y=1 To xelements
x0=x-1
y0=y-1
d=255*(1-heightmap#(x0,y0,0))
;If x0>xelements/2 Then d=Rand(0,255) ; for viewing regular noise, just to find is there any difference or not
Color d,d,d
If heightmap#(x0,y0,0)<sealevel Then Color 57,67,255 ;for showing sea level
Plot x0,y0
Next
Next
SetBuffer BackBuffer()
End Function
|
(Offline)
|
|
09.07.2011, 04:51
|
#157
|
.
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений (для 6,863 пользователей)
|
Ответ: Имитация водной поверхности.
Скринами кормить не забывай - это очень эффективно
|
(Offline)
|
|
Эти 4 пользователя(ей) сказали Спасибо moka за это полезное сообщение:
|
|
09.07.2011, 05:05
|
#158
|
быдло
Регистрация: 05.08.2007
Сообщений: 1,435
Написано 614 полезных сообщений (для 1,489 пользователей)
|
Ответ: Имитация водной поверхности.
Сообщение от dsd
Кстати, а почему шаг в цикле for ... next нельзя менять даже вне цикла?
|
юзай вместо "for" while - и всё будет хорошо
|
(Offline)
|
|
10.07.2011, 23:34
|
#159
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
По моему во время просмотра складывается впечатление, что алгоритм гораздо сложней, чем он есть на самом деле .
Сложный алгоритм работающий в 20 раз медленней, но честно, при полном отсутствии разницы заметной на глаз походу глупость.
Последний раз редактировалось dsd, 10.08.2011 в 03:06.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
10.07.2011, 23:38
|
#160
|
Мастер
Регистрация: 24.06.2009
Адрес: Набережные Челны
Сообщений: 930
Написано 292 полезных сообщений (для 504 пользователей)
|
Ответ: Имитация водной поверхности.
"Живая земля" припоминает игру IGI
Ностальгия.. Сыграю в неё ещё раз.
Исходник tt002.bb пока сложно даётся. Суть сразу не разберёшь. Это через шейдер? (похоже нет)
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
11.07.2011, 01:57
|
#161
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
Перевел в хорс свою самобытную систему частиц. Кажется я замучу на этой неделе какое-никакое дерево.
Люди, дайте шейдер, который будет делать объект похожим на ежа. Просто рисующий нормали, что ли. Пожалста Только попроще.
Последний раз редактировалось dsd, 10.08.2011 в 03:06.
|
(Offline)
|
|
11.07.2011, 10:08
|
#162
|
☭
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений (для 2,707 пользователей)
|
Ответ: Имитация водной поверхности.
Просто рисующий нормали, что ли.
|
dx10 only. геометрические шейдеры нужны. для генерации новых приммитивов
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
13.07.2011, 02:53
|
#163
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
float4x4 matrixWorldViewProj : MATRIX_WORLDVIEWPROJ; // матрица итоговая
float4x4 matrixWorld : MATRIX_WORLD; // матрица мировая
float time;
float3 lightDirection : LIGHT0_DIRECTION; // направление
float4 lightColor : LIGHT0_COLOR; // цвет
float4 entityColor : COLOR_DIFFUSE; // цвет объекта
texture diffuseTexture : TEXTURE_0; // текстура
// описываем sampler
sampler diffuseSampler = sampler_state
{
Texture = <diffuseTexture>; // привязываем текстуру
// устанавливаем адресацию координат
AddressU = WRAP;
AddressV = WRAP;
AddressW = WRAP;
// устанавливаем фильтрацию
MinFilter = ANISOTROPIC;
MagFilter = ANISOTROPIC;
MipFilter = ANISOTROPIC;
// устанавливаем уровень фильтрации
MaxAnisotropy = 4;
};
// входная структура для вершинного шейдера
struct VSInput
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 texCoords : TEXCOORD0;
};
// структура для результата вершинного шейдера
struct VSOutput
{float4 position : POSITION;
float3 normal : TEXCOORD1;
float2 texCoords : TEXCOORD0;
};
// вершинный шейдер
VSOutput VSMain(VSInput input)
{
// объект для выходных данных
VSOutput output;
// трансформируем позицию вершины
float xoops = input.position.x-8*cos(radians(time/10+3*input.position.x));
float yoops = input.position.z-6*sin(radians(time/35+1.5*input.position.z));
float zoops = 8*cos(radians(time/10+3*input.position.x))+6*sin(radians(time/35+1.5*input.position.z));
output.position = mul(float4(input.position.xyz+float3(xoops,zoops,yoops),input.position.w), matrixWorldViewProj);
// трансформируем и нормализуем нормаль
output.normal = normalize(mul(input.normal, matrixWorld));
// переписываем текстурные координаты
output.texCoords = input.texCoords;
// возвращаем результат
return output;
}
// пиксельный шейдер
float4 PSMain(VSOutput input) : COLOR0
{
// делаем выборку из текстуры
float4 diffuse = tex2D(diffuseSampler, input.texCoords);
// расчитываем освещенность точки
float lit = dot(input.normal, -lightDirection*1.5f);
// возвращаем результирующий цвет пиксела
return (diffuse * entityColor * lit * lightColor);
}
// техника для отрисовки
technique Diffuse
{
pass p0
{
VertexShader = compile vs_2_0 VSMain();
PixelShader = compile ps_2_0 PSMain();
}
}
в общем ввел я деформацию в шейдер. Ништяк, теперь плоскость гнется без затрат процессорного времени. Прям как будто я рендрю просто плоскость и ничего с ней не делаю. Но нормали не меняются. А рассчитать нормали я пока умею посчитав плоскость по трем точкам. Но как получить координаты трех точек принадлежащих полигону в шейдере? Или проще научиться искать касательные к уравнениям деформации? Это вроде производная от них?
Вопрос такой: Как вы находите новые нормали изменив геометрию вершинным шейдером? Может есть простой способ?
HolyDel, а шерсть это тоже только от 10 версии?
|
(Offline)
|
|
13.07.2011, 03:08
|
#164
|
Терабайт исходников
Регистрация: 13.09.2008
Сообщений: 3,947
Написано 2,189 полезных сообщений (для 6,051 пользователей)
|
Ответ: Имитация водной поверхности.
HolyDel, а шерсть это тоже только от 10 версии?
|
если ты про пример из сдк, там по-тупому.
рендерится много раз кубик, каждый приподнятее другого. на каждого текстура шерсти в разрезе - получается эффект её. нормали так показывать можно конечно, но это достаточно нелепо и затратно + в любом случае главное - несколько пассов, шейдер нужен лишь затем чтобы отодвигать вертексы в направлении нормали.
Вопрос такой: Как вы находите новые нормали изменив геометрию вершинным шейдером? Может есть простой способ?
|
нету. либо действительно найди формулу нормалей, подходящую под твою формулу деформации, либо читать из текстуры, но читать её в VS, это очень медленно.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
13.07.2011, 04:03
|
#165
|
Мастер
Регистрация: 13.06.2011
Сообщений: 1,103
Написано 481 полезных сообщений (для 1,836 пользователей)
|
Ответ: Имитация водной поверхности.
Риторический пост.
Пока пытался вырубиться, пришло следующее. Коль моя поверхность задана параметрически, то мне в принципе все равно существуют ли в реальности те точки по которым я рассчитываю поверхность. Соответственно в некой небольшой окрестности от точки я считаю координаты трех точек. Получаю уравнение плоскости проходящей через них, соответственно имею перпендикулярный вектор к плоскости. Нормализую его, цель вроде достигнута, причем итоговое приближение поверхности должно быть визуально ближе к уравнениям.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 05:55.
|