Code: Select all
/'
********************************************************************************************
*
* raylib [models] example - PBR material
*
* This example has been created using raylib 1.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2017 Ramon Santamaria (@raysan5)
*
********************************************************************************************
'/
#include once "../raylib.bi"
#include once "../raymath.bi"
#define RLIGHTS_IMPLEMENTATION
#include "../rlights.bi"
#define CUBEMAP_SIZE 512 '' Cubemap texture size
#define IRRADIANCE_SIZE 32 '' Irradiance texture size
#define PREFILTERED_SIZE 256 '' Prefiltered HDR environment texture size
#define BRDF_SIZE 512 '' BRDF LUT texture size
'' PBR material loading
declare function _
LoadMaterialPBR( _
byref albedo as Color, _
byval metalness as single, _
byval roughness as single ) _
as Material
const as integer _
screenWidth => 800, _
screenHeight => 450
const as string _
resPath => "../resources/models/"
'' Enable Multi Sampling Anti Aliasing 4x (if available)
SetConfigFlags( FLAG_MSAA_4X_HINT )
InitWindow( _
screenWidth, _
screenHeight, _
"raylib [models] example - pbr material" )
'' Define the camera to look into our 3d world
dim as Camera _
camera
with camera
.position => Vector3( 4.0!, 4.0!, 4.0! ) '' Camera position
.target => Vector3( 0.0!, 0.5!, 0.0! ) '' Camera looking at point
.up => Vector3( 0.0!, 1.0!, 0.0! ) '' Camera up vector (rotation towards target)
.fovy => 45.0! '' Camera field-of-view Y
.type => CAMERA_PERSPECTIVE '' Camera mode type
end with
'' Load model and PBR material
dim as Model _
model => LoadModel( resPath + "pbr/trooper.obj" )
/'
Mesh tangents are generated... and uploaded to GPU
NOTE: New VBO for tangents is generated at default location and also binded to mesh VAO
'/
MeshTangents( @model.meshes[ 0 ] )
UnloadMaterial( model.materials[ 0 ] ) '' get rid of default material
model.materials[ 0 ] => LoadMaterialPBR( _
Color( 255, 255, 255, 255 ), 1.0!, 1.0! )
/'
Create lights
NOTE: Lights are added to an internal lights pool automatically
'/
CreateLight( _
LIGHT_POINT, _
Vector3( LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0! ), _
Vector3( 0.0!, 0.0!, 0.0! ), _
Color( 255, 0, 0, 255 ), _
model.materials[ 0 ].shader )
CreateLight( _
LIGHT_POINT, _
Vector3( 0.0!, LIGHT_HEIGHT, LIGHT_DISTANCE ), _
Vector3( 0.0!, 0.0!, 0.0! ), _
Color( 0, 255, 0, 255 ), _
model.materials[ 0 ].shader )
CreateLight( _
LIGHT_POINT, _
Vector3( -LIGHT_DISTANCE, LIGHT_HEIGHT, 0.0! ), _
Vector3( 0.0!, 0.0!, 0.0! ), _
Color( 0, 0, 255, 255 ), _
model.materials[ 0 ].shader )
CreateLight( _
LIGHT_DIRECTIONAL, _
Vector3( 0.0!, LIGHT_HEIGHT * 2.0!, -LIGHT_DISTANCE ), _
Vector3( 0.0!, 0.0!, 0.0! ), _
Color( 255, 0, 255, 255 ), _
model.materials[ 0 ].shader )
'' Set an orbital camera mode
SetCameraMode( camera, CAMERA_ORBITAL )
SetTargetFPS( 60 )
do while( not WindowShouldClose() )
UpdateCamera( @camera )
'' Send to material PBR shader camera view position
dim as single _
cameraPos( 0 to 2 ) => { _
camera.position.x, _
camera.position.y, _
camera.position.z }
SetShaderValue( _
model.materials[ 0 ].shader, _
model.materials[ 0 ].shader.locs[ LOC_VECTOR_VIEW ], _
@cameraPos( 0 ), _
UNIFORM_VEC3 )
'' Render
BeginDrawing()
ClearBackground( RAYWHITE )
BeginMode3D( camera )
DrawModel( model, Vector3Zero(), 1.0!, WHITE )
DrawGrid( 10, 1.0! )
EndMode3D()
DrawFPS( 10, 10 )
EndDrawing()
loop
'' Shaders and textures must be unloaded by user,
'' they could be in use by other models
with model
UnloadTexture( .materials[ 0 ].maps[ MAP_ALBEDO ].texture )
UnloadTexture( .materials[ 0 ].maps[ MAP_NORMAL ].texture )
UnloadTexture( .materials[ 0 ].maps[ MAP_METALNESS ].texture )
UnloadTexture( .materials[ 0 ].maps[ MAP_ROUGHNESS ].texture )
UnloadTexture( .materials[ 0 ].maps[ MAP_OCCLUSION ].texture )
UnloadTexture( .materials[ 0 ].maps[ MAP_IRRADIANCE ].texture )
UnloadTexture( .materials[ 0 ].maps[ MAP_PREFILTER ].texture )
UnloadTexture( .materials[ 0 ].maps[ MAP_BRDF ].texture )
UnloadShader( .materials[ 0 ].shader )
end with
UnloadModel(model)
CloseWindow()
/'
Load PBR material (Supports: ALBEDO, NORMAL, METALNESS, ROUGHNESS, AO, EMMISIVE, HEIGHT maps).
NOTE: PBR shader is loaded inside this function.
'/
function _
LoadMaterialPBR( _
byref albedo as Color, _
byval metalness as single, _
byval roughness as single ) _
as Material
'' Initialize material to default
dim as Material _
mat
mat => LoadMaterialDefault()
#if defined( PLATFORM_DESKTOP )
mat.shader => LoadShader( _
resPath + "shaders/glsl330/pbr.vs", _
resPath + "shaders/glsl330/pbr.fs" )
#else '' PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
mat.shader => LoadShader( _
resPath + "shaders/glsl100/pbr.vs", _
resPath + "shaders/glsl100/pbr.fs" )
#endif
/'
Get required locations points for PBR material.
NOTE: Those location names must be available and used in the shader code.
'/
with mat.shader
.locs[ LOC_MAP_ALBEDO ] => GetShaderLocation( mat.shader, "albedo.sampler" )
.locs[ LOC_MAP_METALNESS ] => GetShaderLocation( mat.shader, "metalness.sampler" )
.locs[ LOC_MAP_NORMAL ] => GetShaderLocation( mat.shader, "normals.sampler" )
.locs[ LOC_MAP_ROUGHNESS ] => GetShaderLocation( mat.shader, "roughness.sampler" )
.locs[ LOC_MAP_OCCLUSION ] => GetShaderLocation( mat.shader, "occlusion.sampler" )
.locs[ LOC_MAP_IRRADIANCE ] => GetShaderLocation( mat.shader, "irradianceMap" )
.locs[ LOC_MAP_PREFILTER ] => GetShaderLocation( mat.shader, "prefilterMap" )
.locs[ LOC_MAP_BRDF ] => GetShaderLocation( mat.shader, "brdfLUT" )
'' Set view matrix location
.locs[ LOC_MATRIX_MODEL ] => GetShaderLocation( mat.shader, "matModel" )
.locs[ LOC_VECTOR_VIEW ] => GetShaderLocation( mat.shader, "viewPos" )
end with
'' Set PBR standard maps
with mat
.maps[ MAP_ALBEDO ].texture => LoadTexture( _
resPath + "pbr/trooper_albedo.png" )
.maps[ MAP_NORMAL ].texture => LoadTexture( _
resPath + "pbr/trooper_normals.png" )
.maps[ MAP_METALNESS ].texture => LoadTexture( _
resPath + "pbr/trooper_metalness.png" )
.maps[ MAP_ROUGHNESS ].texture => LoadTexture( _
resPath + "pbr/trooper_roughness.png" )
.maps[ MAP_OCCLUSION ].texture => LoadTexture( _
resPath + "pbr/trooper_ao.png" )
end with
'' Load equirectangular to cubemap shader
#if defined( PLATFORM_DESKTOP )
dim as Shader _
shdrCubemap => LoadShader( _
resPath + "shaders/glsl330/cubemap.vs", _
resPath + "shaders/glsl330/cubemap.fs" )
#else '' PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
dim as Shader _
shdrCubemap => LoadShader( _
resPath + "shaders/glsl100/cubemap.vs", _
resPath + "shaders/glsl100/cubemap.fs" )
#endif
'' Load irradiance (GI) calculation shader
#if defined( PLATFORM_DESKTOP )
dim as Shader _
shdrIrradiance => LoadShader( _
resPath + "shaders/glsl330/skybox.vs", _
resPath + "shaders/glsl330/irradiance.fs" )
#else '' PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
dim as Shader _
shdrIrradiance => LoadShader( _
resPath + "shaders/glsl100/skybox.vs", _
resPath + "shaders/glsl100/irradiance.fs" )
#endif
'' Load reflection prefilter calculation shader
#if defined( PLATFORM_DESKTOP )
dim as Shader _
shdrPrefilter => LoadShader( _
resPath + "shaders/glsl330/skybox.vs", _
resPath + "shaders/glsl330/prefilter.fs" )
#else
dim as Shader _
shdrPrefilter => LoadShader( _
resPath + "shaders/glsl100/skybox.vs", _
resPath + "shaders/glsl100/prefilter.fs" )
#endif
'' Load bidirectional reflectance distribution function shader
#if defined( PLATFORM_DESKTOP )
dim as Shader _
shdrBRDF => LoadShader( _
resPath + "shaders/glsl330/brdf.vs", _
resPath + "shaders/glsl330/brdf.fs" )
#else
dim as Shader _
shdrBRDF => LoadShader( _
resPath + "shaders/glsl100/brdf.vs", _
resPath + "shaders/glsl100/brdf.fs" )
#endif
dim as long _
zero => 0, _
one => 1
'' Setup required shader locations
SetShaderValue( _
shdrCubemap, GetShaderLocation( _
shdrCubemap, "equirectangularMap" ), _
@zero, UNIFORM_INT)
SetShaderValue( _
shdrIrradiance, GetShaderLocation( _
shdrIrradiance, "environmentMap" ), _
@zero, UNIFORM_INT)
SetShaderValue( _
shdrPrefilter, GetShaderLocation( _
shdrPrefilter, "environmentMap" ), _
@zero, UNIFORM_INT )
dim as Texture2D _
texHDR => LoadTexture( resPath + "dresden_square.hdr" )
dim as Texture2D _
cubemap => GenTextureCubemap( _
shdrCubemap, texHDR, CUBEMAP_SIZE )
with mat
.maps[ MAP_IRRADIANCE ].texture => GenTextureIrradiance( _
shdrIrradiance, cubemap, IRRADIANCE_SIZE )
.maps[ MAP_PREFILTER ].texture => GenTexturePrefilter( _
shdrPrefilter, cubemap, PREFILTERED_SIZE )
.maps[ MAP_BRDF ].texture => GenTextureBRDF( _
shdrBRDF, BRDF_SIZE )
end with
UnloadTexture( cubemap )
UnloadTexture( texHDR )
'' Unload already used shaders (to create specific textures)
UnloadShader( shdrCubemap )
UnloadShader( shdrIrradiance )
UnloadShader( shdrPrefilter )
UnloadShader( shdrBRDF )
with mat
'' Set textures filtering for better quality
SetTextureFilter( _
.maps[ MAP_ALBEDO ].texture, FILTER_BILINEAR )
SetTextureFilter( _
.maps[ MAP_NORMAL ].texture, FILTER_BILINEAR )
SetTextureFilter( _
.maps[ MAP_METALNESS ].texture, FILTER_BILINEAR )
SetTextureFilter( _
.maps[ MAP_ROUGHNESS ].texture, FILTER_BILINEAR )
SetTextureFilter( _
.maps[ MAP_OCCLUSION ].texture, FILTER_BILINEAR )
'' Enable sample usage in shader for assigned textures
SetShaderValue( _
.shader, GetShaderLocation( _
.shader, "albedo.useSampler" ), _
@one, UNIFORM_INT )
SetShaderValue( _
.shader, GetShaderLocation( _
.shader, "normals.useSampler" ), _
@one, UNIFORM_INT )
SetShaderValue( _
.shader, GetShaderLocation( _
.shader, "metalness.useSampler" ), _
@one, UNIFORM_INT )
SetShaderValue( _
.shader, GetShaderLocation( _
.shader, "roughness.useSampler" ), _
@one, UNIFORM_INT )
SetShaderValue( _
.shader, GetShaderLocation( _
.shader, "occlusion.useSampler" ), _
@one, UNIFORM_INT)
dim as long _
renderModeLoc => GetShaderLocation( .shader, "renderMode" )
SetShaderValue( _
.shader, renderModeLoc, @zero, UNIFORM_INT )
'' Set up material properties color
.maps[ MAP_ALBEDO ].color => albedo
.maps[ MAP_NORMAL ].color => Color( 128, 128, 255, 255 )
.maps[ MAP_METALNESS ].value => metalness
.maps[ MAP_ROUGHNESS ].value => roughness
.maps[ MAP_OCCLUSION ].value => 1.0!
.maps[ MAP_EMISSION ].value => 0.5!
.maps[ MAP_HEIGHT ].value => 0.5!
end with
return( mat )
end function
Code: Select all
/'
***********************************************************************************************
*
* raylib.lights - Some useful functions to deal with lights data
*
* CONFIGURATION:
*
* #define RLIGHTS_IMPLEMENTATION
* Generates the implementation of the library into the included file.
* If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation.
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2017 Victor Fisac and Ramon Santamaria
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************
'/
#ifndef RLIGHTS_H
#define RLIGHTS_H
#include once "raylib.bi"
/'
Defines and Macros
'/
#define MAX_LIGHTS 4 '' Max lights supported by shader
#define LIGHT_DISTANCE 3.5! '' Light distance from world center
#define LIGHT_HEIGHT 1.0! '' Light height position
/'
Types and Structures Definition
'/
enum _
LightType
LIGHT_DIRECTIONAL
LIGHT_POINT
end enum
type _
Light
as boolean _
enabled
as LightType _
type
as Vector3 _
position, _
target
as Color _
color
as long _
enabledLoc, _
typeLoc, _
posLoc, _
targetLoc, _
colorLoc
end type
extern "C" '' Prevents name mangling of functions
/'
Module Functions Declaration
'/
'' Defines a light and get locations from PBR shader
declare sub _
CreateLight( _
byval _type as long, byref _pos as Vector3, byref targ as Vector3, byref _color as Color, byref _shader as Shader )
'' Send to PBR shader light values
declare sub _
UpdateLightValues( byref _shader as Shader, byref _light as Light )
end extern
#endif '' RLIGHTS_H
/'
************************************************************************************
*
* RLIGHTS IMPLEMENTATION
*
************************************************************************************/
'/
#if defined( RLIGHTS_IMPLEMENTATION )
#include once "raylib.bi"
dim shared as Light _
lights( MAX_LIGHTS )
'' Current amount of created lights
dim shared as long _
lightsCount => 0
extern "C"
'' Defines a light and get locations from PBR shader
sub _
CreateLight( _
byval _type as long, _
byref _pos as Vector3, _
byref targ as Vector3, _
byref _color as Color, _
byref _shader as Shader )
dim as Light _
_light
if( lightsCount < MAX_LIGHTS ) then
with _light
.enabled => true
.type => _type
.position => _pos
.target => targ
.color => _color
end with
dim as string _
enabledName => "lights[" & lightsCount & "].enabled", _
typeName => "lights[" & lightsCount & "].type", _
posName => "lights[" & lightsCount & "].position", _
targetName => "lights[" & lightsCount & "].target", _
colorName => "lights[" & lightsCount & "].color"
with _light
.enabledLoc => GetShaderLocation( _shader, strPtr( enabledName ) )
.typeLoc => GetShaderLocation( _shader, strPtr( typeName ) )
.posLoc => GetShaderLocation( _shader, strPtr( posName ) )
.targetLoc => GetShaderLocation( _shader, strPtr( targetName ) )
.colorLoc => GetShaderLocation( _shader, strPtr( colorName ) )
end with
UpdateLightValues( _shader, _light )
lights( lightsCount ) => _light
lightsCount +=> 1
end if
end sub
'' Send to PBR shader light values
sub _
UpdateLightValues( _
byref _shader as Shader, _
byref _light as Light )
'' Send to shader light enabled state and type
SetShaderValue( _shader, _light.enabledLoc, @_light.enabled, UNIFORM_INT )
SetShaderValue( _shader, _light.typeLoc, @_light.type, UNIFORM_INT )
'' Send to shader light position values
dim as single _
position( 0 to 2 ) => { _
_light.position.x, _
_light.position.y, _
_light.position.z }
SetShaderValue( _shader, _light.posLoc, @position( 0 ), UNIFORM_VEC3 )
'' Send to shader light target position values
dim as single _
target( 0 to 2 ) => { _
_light.target.x, _
_light.target.y, _
_light.target.z }
SetShaderValue( _shader, _light.targetLoc, @target( 0 ), UNIFORM_VEC3 )
'' Send to shader light color values
dim as single _
diff( 0 to 3 ) => { _
_light.color.r / 255, _
_light.color.g / 255, _
_light.color.b / 255, _
_light.color.a / 255 }
SetShaderValue( _shader, _light.colorLoc, @diff( 0 ), UNIFORM_VEC4 )
end sub
end extern
#endif '' RLIGHTS_IMPLEMENTATION
It needs the above header to run.