demo - Fresnel
Publié : jeu. 21/mars/2019 20:36
salut,
m'étant aperçu que la couche alpha était gerée au niveau des vertex, je me suis dis que ça serais con de pas en profiter
l'effet fresnel se traduit par une variation de la reflexion en fonction de l'orientation des faces de l'objet par rapport à la caméra. Quand l'axe de la caméra est perpendiculaire à la surface le niveau de réflexion diminue et à l'inverse quand l'axe de la caméra tend à être parallèle l'intensité augmente
par exemple, quand on regarde un plan d'eau, la reflexion du ciel est plus marquée à l'horizon qu'a ses pieds
(ici, en guise de reflexion, y'a juste un petit:SetMaterialAttribute(num,#PB_Material_EnvironmentMap,#PB_Material_ReflectionMap) )
j'en ai profité aussi pour inverser l'effet, du coup le bord des objets est transparent
dommage on ne peut pas activer la brillance (mais dans la prochaine version de pb on pourra)
cette démo est juste une curiosité, on peut à la rigueur utiliser ma fonction "mesh_fresnel" pour un plan d'eau, mais sinon y'a quelques contraintes
je vais pas en faire la liste...
la bonne façon de faire c'est par les scripts shader
si y'a un connaisseur je suis preneur !
Code : Tout sélectionner
; Fresnel 3D - pf Shadoko - 2019
EnableExplicit
Structure vector3
x.f
y.f
z.f
EndStructure
Structure PB_MeshVertexV
p.vector3
n.vector3
t.vector3
u.f
v.f
color.l
EndStructure
Macro vec3d(v,vx,vy,vz)
v\x=vx
v\y=vy
v\z=vz
EndMacro
Macro sub3D(p,p1,p2)
p\x=p1\x-p2\x
p\y=p1\y-p2\y
p\z=p1\z-p2\z
EndMacro
Macro add3d(p,p1,p2)
p\x=p1\x+p2\x
p\y=p1\y+p2\y
p\z=p1\z+p2\z
EndMacro
Procedure.f lng3D(*v.Vector3)
ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
EndProcedure
Procedure Norme3D(*V.Vector3,l.f=1)
Protected.f lm
lm = l / lng3d(*v)
*V\x * lm
*V\y * lm
*V\z * lm
EndProcedure
Procedure.f Pscalaire3d(*p.vector3,*q.vector3)
ProcedureReturn *p\x * *q\x + *p\y * *q\y + *p\z * *q\z
EndProcedure
Procedure fresnel_samples(num,type,txt,reflex=0)
Protected i,j,n=32,n2=n/2
Protected.f ai,aj,r
Dim t.PB_MeshVertex(n,n)
For j=0 To n
For i=0 To n
With t(i,j)
Select type
Case 1
\x=(i-n2)*10/n
\z=(j-n2)*10/n
\y=-4
Case 2
ai=i/n*2*#PI
aj=j/n*#PI
r=Sin(aj)
\x=-Cos(ai)*r
\z=Sin(ai)*r
\y=Cos(aj)
EndSelect
\u=i/4
\v=j/4
\Color=$ffffff
EndWith
Next
Next
CreateDataMesh(num,t())
NormalizeMesh(num)
CreateMaterial(num,TextureID(txt))
DisableMaterialLighting(num,1)
;DisableDebugger:SetMaterialAttribute(num,21,3):EnableDebugger
;SetMaterialColor(num,#PB_Material_SpecularColor,$ffffff):MaterialShininess(num,20)
If reflex:SetMaterialAttribute(num,#PB_Material_EnvironmentMap,#PB_Material_ReflectionMap):EndIf
MaterialBlendingMode(num,#PB_Material_AlphaBlend)
CreateEntity(num,MeshID(num),MaterialID(num))
EndProcedure
Procedure mesh_fresnel(camera,entity,mesh,transparency.f=1,inverse=0,color=$ffffff)
Protected.vector3 c,e,d,vv
Protected nv,i,alpha,ps.f
color=RGB(Blue(color),Green(color),Red(color))
c\x=CameraX(camera)
c\y=CameraY(camera)
c\z=CameraZ(camera)
e\x=EntityX(entity)
e\y=EntityY(entity)
e\z=EntityZ(entity)
sub3d(vv,e,c)
nv=MeshVertexCount(mesh)-1
Dim v.PB_MeshVertexV(nv)
GetMeshData(mesh,0,v(),#PB_Mesh_Vertex|#PB_Mesh_Normal,0,nv)
For i=0 To nv
add3d(d,vv,v(i)\p):Norme3D(d)
ps=Abs(Pscalaire3d(d,v(i)\n)):If inverse:ps=1-ps:EndIf
alpha=255-((ps)*transparency)*255
v(i)\Color=alpha*$01000000+color
Next
SetMeshData(mesh,0,v(),#PB_Mesh_Color,0,nv)
EndProcedure
Procedure init()
Protected ex,ey,i
InitEngine3D():InitSprite():InitKeyboard():InitMouse()
ExamineDesktops()
ex=DesktopWidth (0)*1
ey=DesktopHeight(0)*1
OpenWindow(0, 0,0, ex,ey, "Test 3d - [F12] Wireframe - [Esc] quit",#PB_Window_ScreenCentered|#PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, ex, ey, 0, 0, 0)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures",#PB_3DArchive_FileSystem)
Parse3DScripts()
CreateCamera(0, 0, 0, 100, 100):MoveCamera(0,5,1,0):CameraLookAt(0,0,0,0)
CreateLight(0,$ffffff, 10000, 10000, 0000)
AmbientColor($444444)
LoadTexture(0,"soil_wall.jpg")
LoadTexture(1, "rustysteel.jpg")
LoadTexture(2, "dirt.jpg")
LoadTexture(3, "doscarte.png")
CreateMaterial(0,TextureID(1))
MaterialCullingMode(0,#PB_Material_AntiClockWiseCull)
DisableMaterialLighting(0,1)
ScaleMaterial(0,1/8,1/8)
CreateSphere(0,100):CreateEntity(0,MeshID(0),MaterialID(0))
CreateMaterial(1,TextureID(1))
fresnel_samples(1,1,0)
fresnel_samples(2,2,3,1)
fresnel_samples(3,2,2)
fresnel_samples(4,2,3,1)
fresnel_samples(5,2,2)
EndProcedure
Procedure rendu()
Protected.l i,col
Protected.f keyx,keyz,MouseX,Mousey,a,ai
Repeat
While WindowEvent():Wend
mesh_fresnel(0,1,1,0.9)
mesh_fresnel(0,2,2,0.9,0,$ff8888)
mesh_fresnel(0,3,3,1 ,1,$ff00ff)
mesh_fresnel(0,4,4,0.9,0,$44ff44)
mesh_fresnel(0,5,5,1 ,1,$88ccff)
a+0.01:For i=2 To 5:ai=a+i*#PI/2:MoveEntity(i,Cos(ai)*2,0,Sin(ai)*2,#PB_Absolute):Next
WindowEvent()
ExamineMouse()
ExamineKeyboard()
MouseX = -MouseDeltaX() * 0.05
MouseY = -MouseDeltaY() * 0.05
keyx=(-Bool(KeyboardPushed(#PB_Key_Left)<>0)+Bool(KeyboardPushed(#PB_Key_Right)<>0))*0.05
keyz=(-Bool(KeyboardPushed(#PB_Key_Down)<>0)+Bool(KeyboardPushed(#PB_Key_Up )<>0))*0.05+MouseWheel()*2
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative):MoveCamera(0, keyx, 0, -keyz,#PB_Local )
RenderWorld()
FlipBuffers()
Until MouseButton(#PB_MouseButton_Left) Or KeyboardReleased(#PB_Key_Escape)
EndProcedure
init()
rendu()