raylib-go/examples/shaders/pbr/pbr.go
2025-01-26 21:57:23 +03:30

218 lines
8.6 KiB
Go

package main
import (
"fmt"
"reflect"
"unsafe"
rl "github.com/gen2brain/raylib-go/raylib"
)
const (
LIGHT_DIRECTIONAL int32 = iota
LIGHT_POINT
LIGHT_SPOT
)
type light struct {
Enabled int32
Type int32
Target rl.Vector3
Position rl.Vector3
Color [4]float32
Intensity float32
// Shader light parameters locations
enabledLoc int32
typeLoc int32
targetLoc int32
positionLoc int32
colorLoc int32
intensityLoc int32
}
type PhysicRender struct {
Shader *rl.Shader
combineStatus bool
}
// make light and pbr Shader
func (ph *PhysicRender) Init() {
if !ph.combineStatus {
ph.configShader()
}
ph.Shader.UpdateLocation(rl.ShaderLocMapAlbedo, rl.GetShaderLocation(*ph.Shader, "albedoMap"))
ph.Shader.UpdateLocation(rl.ShaderLocMapMetalness, rl.GetShaderLocation(*ph.Shader, "mraMap"))
ph.Shader.UpdateLocation(rl.ShaderLocMapNormal, rl.GetShaderLocation(*ph.Shader, "normalMap"))
ph.Shader.UpdateLocation(rl.ShaderLocMapEmission, rl.GetShaderLocation(*ph.Shader, "emissiveMap"))
ph.Shader.UpdateLocation(12, rl.GetShaderLocation(*ph.Shader, "albedoColor"))
ph.Shader.UpdateLocation(rl.ShaderLocVectorView, rl.GetShaderLocation(*ph.Shader, "viewPos"))
ambientColor := rl.Color{R: 122, G: 36, B: 26, A: 100}
ambientColorNormalized := rl.NewVector3(float32(ambientColor.R)/255.0, float32(ambientColor.G)/255.0, float32(ambientColor.B)/255.0)
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "ambientColor"), []float32{ambientColorNormalized.X, ambientColorNormalized.Y, ambientColorNormalized.Z}, rl.ShaderUniformVec3)
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "ambient"), []float32{float32(0.03)}, rl.ShaderUniformFloat)
lightCountLoc := rl.GetShaderLocation(*ph.Shader, "numOfLights")
rl.SetShaderValue(*ph.Shader, lightCountLoc, generiteIntForGlsl(int32(MaxLights)), rl.ShaderUniformInt)
}
func (ph *PhysicRender) UpadteByCamera(pos rl.Vector3) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "viewPos"), []float32{pos.X, pos.Y, pos.Z}, rl.ShaderUniformVec3)
}
func (ph *PhysicRender) CreateLight(typeLight int32, position rl.Vector3, target rl.Vector3, color rl.Color, intensity float32) light {
light := light{}
if lightCount < MaxLights {
light.Enabled = 1
light.Position = position
light.Type = typeLight
light.Target = target
light.Color[0] = float32(float32(color.R) / 255.0)
light.Color[1] = float32(float32(color.G) / 255.0)
light.Color[2] = float32(float32(color.B) / 255.0)
light.Color[3] = float32(float32(color.A) / 255.0)
light.Intensity = intensity
// NOTE: Shader parameters names for lights must match the requested ones
light.enabledLoc = rl.GetShaderLocation(*ph.Shader, fmt.Sprintf("lights[%d].enabled", lightCount))
light.positionLoc = rl.GetShaderLocation(*ph.Shader, fmt.Sprintf("lights[%d].position", lightCount))
light.colorLoc = rl.GetShaderLocation(*ph.Shader, fmt.Sprintf("lights[%d].color", lightCount))
light.intensityLoc = rl.GetShaderLocation(*ph.Shader, fmt.Sprintf("lights[%d].intensity", lightCount))
light.typeLoc = rl.GetShaderLocation(*ph.Shader, fmt.Sprintf("lights[%d].type", lightCount))
//light.targetLoc = rl.GetShaderLocation(ph.Shader, fmt.Sprintf("lights[%d].target", lightCount))
ph.UpdateLight(*ph.Shader, light)
lightCount++
}
return light
}
func (ph *PhysicRender) UpdateLight(Shader rl.Shader, light light) {
rl.SetShaderValue(Shader, light.enabledLoc, generiteIntForGlsl(light.Enabled), rl.ShaderUniformInt)
rl.SetShaderValue(Shader, light.positionLoc, []float32{light.Position.X, light.Position.Y, light.Position.Z}, rl.ShaderUniformVec3)
rl.SetShaderValue(Shader, light.colorLoc, []float32{light.Color[0], light.Color[1], light.Color[2], light.Color[3]}, rl.ShaderUniformVec4)
rl.SetShaderValue(Shader, light.intensityLoc, []float32{light.Intensity}, rl.ShaderUniformFloat)
rl.SetShaderValue(Shader, light.typeLoc, generiteIntForGlsl(light.Type), rl.ShaderUniformInt)
//rl.SetShaderValue(Shader, light.targetLoc,[]float32{light.Target.X, light.Target.Y, light.Target.Z}, rl.ShaderUniformVec3)
}
func (ph *PhysicRender) MaxLights(value int) {
MaxLights = value
}
func (ph *PhysicRender) TextureMapAlbedo(modelMaterials *rl.Material, texture rl.Texture2D) {
rl.SetMaterialTexture(modelMaterials, rl.MapAlbedo, texture)
}
func (ph *PhysicRender) TextureMapMetalness(modelMaterials *rl.Material, texture rl.Texture2D) {
rl.SetMaterialTexture(modelMaterials, rl.MapMetalness, texture)
}
func (ph *PhysicRender) TextureMapRoughness(modelMaterials *rl.Material, texture rl.Texture2D) {
rl.SetMaterialTexture(modelMaterials, rl.MapRoughness, texture)
}
func (ph *PhysicRender) TextureMapNormal(modelMaterials *rl.Material, texture rl.Texture2D) {
rl.SetMaterialTexture(modelMaterials, rl.MapNormal, texture)
}
func (ph *PhysicRender) TextureMapOcclusion(modelMaterials *rl.Material, texture rl.Texture2D) {
rl.SetMaterialTexture(modelMaterials, rl.MapOcclusion, texture)
}
func (ph *PhysicRender) DrawSphereLoctionLight(li light, color rl.Color) {
rl.DrawSphereEx(li.Position, 0.2, 8, 8, color)
}
func (ph *PhysicRender) AlbedoColorModel(model *rl.Model, color rl.Color) {
model.GetMaterials()[0].GetMap(rl.MapAlbedo).Color = color
}
func (ph *PhysicRender) EmissiveColor(color rl.Color) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "emissiveColor"), []float32{float32(color.R), float32(color.G), float32(color.B), float32(color.A)}, rl.ShaderUniformVec4)
}
func (ph *PhysicRender) NormalValue(value float32) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "emissiveColor"), []float32{value}, rl.ShaderUniformFloat)
}
func (ph *PhysicRender) MetallicValue(value float32) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "metallicValue"), []float32{value}, rl.ShaderUniformFloat)
}
func (ph *PhysicRender) RoughnessValue(value float32) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "roughnessValue"), []float32{value}, rl.ShaderUniformFloat)
}
func (ph *PhysicRender) AoValue(value float32) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "aoValue"), []float32{value}, rl.ShaderUniformFloat)
}
func (ph *PhysicRender) EmissivePower(value float32) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "emissivePower"), []float32{value}, rl.ShaderUniformFloat)
}
func (ph *PhysicRender) AmbientColor(colorAmbient rl.Vector3, ambientValue float32) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "ambientColor"), []float32{colorAmbient.X, colorAmbient.Y, colorAmbient.Z}, rl.ShaderUniformVec3)
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "ambient"), []float32{ambientValue}, rl.ShaderUniformFloat)
}
func (ph *PhysicRender) SetTiling(value rl.Vector2) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "tiling"), []float32{value.X, value.Y}, rl.ShaderUniformVec2)
}
func (ph *PhysicRender) SetOffset(value rl.Vector2) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "offset"), []float32{value.X, value.Y}, rl.ShaderUniformVec2)
}
func (ph *PhysicRender) SetTilingFlashlight(value rl.Vector2) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "tilingFlashlight"), []float32{value.X, value.Y}, rl.ShaderUniformVec2)
}
func (ph *PhysicRender) SetOffsetFlashlight(value rl.Vector2) {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "offsetFlashlight"), []float32{value.X, value.Y}, rl.ShaderUniformVec2)
}
func (ph *PhysicRender) UseTexAlbedo() {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "useTexAlbedo"), generiteIntForGlsl(1), rl.ShaderUniformInt)
}
func (ph *PhysicRender) UseTexNormal() {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "useTexNormal"), generiteIntForGlsl(1), rl.ShaderUniformInt)
}
func (ph *PhysicRender) UseTexMRA() {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "useTexMRA"), generiteIntForGlsl(1), rl.ShaderUniformInt)
}
func (ph *PhysicRender) UseTexEmissive() {
rl.SetShaderValue(*ph.Shader, rl.GetShaderLocation(*ph.Shader, "useTexEmissive"), generiteIntForGlsl(1), rl.ShaderUniformInt)
}
func (ph *PhysicRender) configShader() {
sh := rl.LoadShader("./pbr.vs", "./pbr.fs")
ph.Shader = &sh
}
// exce before init or set manually
func (ph *PhysicRender) SetCombineShader(CombineShader *rl.Shader) {
ph.combineStatus = true
ph.Shader = CombineShader
}
func (ph *PhysicRender) Unload() {
rl.UnloadShader(*ph.Shader)
}
func generiteIntForGlsl(value int32) []float32 {
data := &reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(&value)),
Len: 4,
Cap: 4,
}
return *(*[]float32)(unsafe.Pointer(data))
}