commit 897ac30c0e6ffed35b3536a1c2fec624797ec1b1
parent 1dad40f9d7f732011017b4c8f8c6b0e046047574
Author: Matsuda Kenji <info@mtkn.jp>
Date: Fri, 22 Nov 2024 16:55:29 +0900
use Program.Uniforms
Diffstat:
5 files changed, 124 insertions(+), 92 deletions(-)
diff --git a/cmd/sample/fragment.glsl b/cmd/sample/fragment.glsl
@@ -1,9 +1,9 @@
#version 330 core
-struct Material {
- sampler2D diffuse;
- sampler2D specular;
- float shiness;
+struct material {
+ sampler2D Diffuse;
+ sampler2D Specular;
+ float Shiness;
};
struct DirLight {
@@ -27,9 +27,9 @@ in vec3 fnormal;
in vec3 fpos;
in vec2 texPos;
-uniform vec3 camPos;
+uniform vec3 CamPos;
uniform vec3 objCol;
-uniform Material material;
+uniform material Material;
uniform DirLight Sun;
uniform SpotLight Light;
@@ -50,33 +50,33 @@ void main() {
dist = length(Light.Pos - fpos);
attenuation = 1 / (Light.Kc + Light.Kl * dist + Light.Kq * dist * dist);
- ambient = vec3(texture(material.diffuse, texPos)) * Light.Ambient;
+ ambient = vec3(texture(Material.Diffuse, texPos)) * Light.Ambient;
lightDir = normalize(Light.Pos - fpos);
theta = dot(lightDir, normalize(-lightDir));
epsilon = Light.CutOff - Light.OuterCutOff;
intensity = clamp((theta - Light.OuterCutOff) / epsilon, 0.0, 1.0);
diff = max(dot(fnormal, lightDir), 0.0);
- diffuse = diff * vec3(texture(material.diffuse, texPos)) * Light.Diffuse * intensity;
+ diffuse = diff * vec3(texture(Material.Diffuse, texPos)) * Light.Diffuse * intensity;
- viewDir = normalize(camPos - fpos);
+ viewDir = normalize(CamPos - fpos);
reflectDir = reflect(-lightDir, normalize(fnormal));
- spec = pow(max(dot(viewDir, reflectDir), 0), material.shiness);
- specular = vec3(texture(material.specular, texPos)) * spec * Light.Specular * intensity;
+ spec = pow(max(dot(viewDir, reflectDir), 0), Material.Shiness);
+ specular = vec3(texture(Material.Specular, texPos)) * spec * Light.Specular * intensity;
fcol += vec4(ambient + diffuse + specular, 0) * attenuation;
- ambient = vec3(texture(material.diffuse, texPos)) * Sun.Ambient;
+ ambient = vec3(texture(Material.Diffuse, texPos)) * Sun.Ambient;
lightDir = normalize(-Sun.Dir);
diff = max(dot(fnormal, lightDir), 0.0);
- diffuse = diff * vec3(texture(material.diffuse, texPos)) * Sun.Diffuse;
+ diffuse = diff * vec3(texture(Material.Diffuse, texPos)) * Sun.Diffuse;
- viewDir = normalize(camPos - fpos);
+ viewDir = normalize(CamPos - fpos);
reflectDir = reflect(-lightDir, fnormal);
- spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shiness);
- specular = vec3(texture(material.specular, texPos)) * spec * Sun.Specular;
+ spec = pow(max(dot(viewDir, reflectDir), 0.0), Material.Shiness);
+ specular = vec3(texture(Material.Specular, texPos)) * spec * Sun.Specular;
fcol += vec4(ambient + diffuse + specular, 0);
diff --git a/cmd/sample/light_fragment.glsl b/cmd/sample/light_fragment.glsl
@@ -1,7 +1,7 @@
#version 330 core
-uniform vec3 lightCol;
+uniform vec3 LightCol;
out vec4 fcol;
void main() {
- fcol = vec4(lightCol, 1.0);
+ fcol = vec4(LightCol, 1.0);
}
diff --git a/cmd/sample/main.go b/cmd/sample/main.go
@@ -201,7 +201,6 @@ type Trans struct {
Projection, View, Model tofu.Mat4
}
-var teapotTrans = new(Trans)
var cubeTrans = new(Trans)
var cubePositions = []tofu.Vec3{
@@ -217,6 +216,53 @@ var cubePositions = []tofu.Vec3{
{-2.00, 0.92, 4.57},
}
+type Material struct {
+ Diffuse tofu.Vec3
+ Specular tofu.Vec3
+ Shiness float32
+}
+
+type MaterialTexture struct {
+ Diffuse *tofu.Texture
+ Specular *tofu.Texture
+ Shiness float32
+}
+
+var cubeUniforms = struct {
+ CamPos tofu.Vec3
+ Trans Trans
+ Material MaterialTexture
+ Sun *DirLight
+ Light *SpotLight
+}{
+ Material: MaterialTexture{Shiness: 32},
+ Sun: sun,
+ Light: spotLight,
+}
+
+var teapotUniforms = struct {
+ CamPos tofu.Vec3
+ Trans Trans
+ Material Material
+ Sun *DirLight
+ Light *SpotLight
+}{
+ Material: Material{
+ Diffuse: tofu.Vec3{0.3, 0.4, 0.4},
+ Specular: tofu.Vec3{0.3, 0.4, 0.4},
+ Shiness: 32,
+ },
+ Sun: sun,
+ Light: spotLight,
+}
+
+var lightUniforms = struct {
+ Trans Trans
+ LightCol tofu.Vec3
+}{
+ LightCol: spotLight.Specular,
+}
+
var alpha float32 = 0.2
type App struct {
@@ -229,8 +275,6 @@ type App struct {
camera *tofu.Camera
termination bool
startedAt time.Time
- texture *tofu.Texture
- specularMap *tofu.Texture
}
func (app *App) Update() error {
@@ -251,36 +295,29 @@ func (app *App) Update() error {
spotLight.Dir = tofu.Vec3{0, 0, 0}.Sub(spotLight.Pos)
app.program.Use()
- cubeTrans.View = view
- cubeTrans.Projection = projection
- app.program.SetVec3("camPos", camera.Pos)
- app.program.SetTexture("material.diffuse", app.texture)
- app.program.SetTexture("material.specular", app.specularMap)
- app.program.SetFloat32("material.shiness", 32)
+ cubeUniforms.Trans.View = view
+ cubeUniforms.Trans.Projection = projection
+ cubeUniforms.CamPos = camera.Pos
for _, p := range cubePositions {
model := tofu.Translate(p.Inverse())
- cubeTrans.Model = model
+ cubeUniforms.Trans.Model = model
app.program.SetUniforms()
cube.Draw(app.program)
}
app.teapotProgram.Use()
- teapotTrans.View = view
- teapotTrans.Projection = projection
- teapotTrans.Model = tofu.Translate(tofu.Vec3{0, 0, 0}).
+ teapotUniforms.Trans.View = view
+ teapotUniforms.Trans.Projection = projection
+ teapotUniforms.Trans.Model = tofu.Translate(tofu.Vec3{0, 0, 0}).
Mul(tofu.Rotate(now, tofu.Vec3{0, 1, 0})).
Mul(tofu.Scale(0.06))
- app.teapotProgram.SetVec3("camPos", camera.Pos)
- app.teapotProgram.SetVec3("material.diffuse", tofu.Vec3{0.3, 0.4, 0.4})
- app.teapotProgram.SetVec3("material.specular", tofu.Vec3{0.3, 0.4, 0.4})
- app.teapotProgram.SetFloat32("material.shiness", 32)
+ teapotUniforms.CamPos = camera.Pos
app.teapotProgram.SetUniforms()
teapot.Draw(app.teapotProgram)
app.lightProgram.Use()
- app.lightProgram.SetMat4("Trans.View", view)
- app.lightProgram.SetMat4("Trans.Projection", projection)
- app.lightProgram.SetMat4("Trans.Model", lightModel)
- app.lightProgram.SetVec3("lightCol", spotLight.Specular)
+ lightUniforms.Trans.View = view
+ lightUniforms.Trans.Projection = projection
+ lightUniforms.Trans.Model = lightModel
app.lightProgram.SetUniforms()
light.Draw(app.lightProgram)
@@ -320,44 +357,31 @@ func main() {
if err != nil {
log.Fatal(err)
}
- teapot.SetNormals()
+ //teapot.SetNormals()
teapot.Load()
app.program, err = tofu.NewProgram(vpath, fpath)
if err != nil {
log.Fatalf("create shader program: %v", err)
}
- app.program.Uniforms = struct {
- Sun *DirLight
- Light *SpotLight
- Trans *Trans
- }{
- sun,
- spotLight,
- cubeTrans,
- }
+ app.program.Uniforms = &cubeUniforms
app.lightProgram, err = tofu.NewProgram(vpath, lightFpath)
if err != nil {
log.Fatalf("create light shader program: %v", err)
}
+ app.lightProgram.Uniforms = &lightUniforms
+
app.teapotProgram, err = tofu.NewProgram(vpath, teapotFpath)
if err != nil {
log.Fatalf("create teapot shader program: %v", err)
}
- app.teapotProgram.Uniforms = struct {
- Sun *DirLight
- Light *SpotLight
- Trans *Trans
- }{
- Sun: sun,
- Light: spotLight,
- Trans: teapotTrans,
- }
- app.texture, err = tofu.NewTexture(texturePath)
+ app.teapotProgram.Uniforms = &teapotUniforms
+
+ cubeUniforms.Material.Diffuse, err = tofu.NewTexture(texturePath)
if err != nil {
log.Fatalf("NewTesture: %v", err)
}
- app.specularMap, err = tofu.NewTexture(specularMapPath)
+ cubeUniforms.Material.Specular, err = tofu.NewTexture(specularMapPath)
if err != nil {
log.Fatalf("NewTesture: %v", err)
}
diff --git a/cmd/sample/teapot.glsl b/cmd/sample/teapot.glsl
@@ -1,9 +1,9 @@
#version 330 core
-struct Material {
- vec3 diffuse;
- vec3 specular;
- float shiness;
+struct material {
+ vec3 Diffuse;
+ vec3 Specular;
+ float Shiness;
};
struct DirLight {
@@ -27,9 +27,9 @@ in vec3 fnormal;
in vec3 fpos;
in vec2 texPos;
-uniform vec3 camPos;
+uniform vec3 CamPos;
uniform vec3 objCol;
-uniform Material material;
+uniform material Material;
uniform DirLight Sun;
uniform SpotLight Light;
@@ -50,33 +50,33 @@ void main() {
dist = length(Light.Pos - fpos);
attenuation = 1 / (Light.Kc + Light.Kl * dist + Light.Kq * dist * dist);
- ambient = material.diffuse * Light.Ambient;
+ ambient = Material.Diffuse * Light.Ambient;
lightDir = normalize(Light.Pos - fpos);
theta = dot(lightDir, normalize(-Light.Dir));
epsilon = Light.CutOff - Light.OuterCutOff;
intensity = clamp((theta - Light.OuterCutOff) / epsilon, 0.0, 1.0);
diff = max(dot(fnormal, lightDir), 0.0);
- diffuse = diff * material.diffuse * Light.Diffuse * intensity;
+ diffuse = diff * Material.Diffuse * Light.Diffuse * intensity;
- viewDir = normalize(camPos - fpos);
+ viewDir = normalize(CamPos - fpos);
reflectDir = reflect(-lightDir, fnormal);
- spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shiness);
- specular = material.specular * spec * Light.Specular * intensity;
+ spec = pow(max(dot(viewDir, reflectDir), 0.0), Material.Shiness);
+ specular = Material.Specular * spec * Light.Specular * intensity;
fcol += vec4((ambient+diffuse+specular) * attenuation, 0);
- ambient = material.diffuse * Sun.Ambient;
+ ambient = Material.Diffuse * Sun.Ambient;
lightDir = normalize(-Sun.Dir);
diff = max(dot(fnormal, lightDir), 0.0);
- diffuse = diff * material.diffuse * Sun.Diffuse;
+ diffuse = diff * Material.Diffuse * Sun.Diffuse;
- viewDir = normalize(camPos - fpos);
+ viewDir = normalize(CamPos - fpos);
reflectDir = reflect(-lightDir, fnormal);
- spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shiness);
- specular = material.specular * spec * Sun.Specular;
+ spec = pow(max(dot(viewDir, reflectDir), 0.0), Material.Shiness);
+ specular = Material.Specular * spec * Sun.Specular;
fcol += vec4(ambient + diffuse + specular, 0);
}
diff --git a/shader.go b/shader.go
@@ -97,6 +97,9 @@ func (p *Program) setUniforms(uniforms any, prefix string) error {
if uniforms == nil {
return nil
}
+ if reflect.TypeOf(uniforms).Kind() == reflect.Pointer {
+ uniforms = reflect.ValueOf(uniforms).Elem().Interface()
+ }
s := reflect.ValueOf(uniforms)
fields := reflect.VisibleFields(s.Type())
for i := 0; i < s.NumField(); i++ {
@@ -109,33 +112,38 @@ func (p *Program) setUniforms(uniforms any, prefix string) error {
if prefix != "" {
tag = prefix + "." + tag
}
- switch fv.Kind() {
- case reflect.Struct:
- if err := p.setUniforms(fv.Interface(), tag); err != nil {
- return err
- }
- continue
- case reflect.Pointer:
- if err := p.setUniforms(fv.Elem().Interface(), tag); err != nil {
- return err
- }
- continue
- }
switch ft.Type.String() {
case "tofu.Mat4":
if err := p.SetMat4(tag, fv.Interface().(Mat4)); err != nil {
- return err
+ return fmt.Errorf("set %s: %v", tag, err)
}
case "tofu.Vec3":
if err := p.SetVec3(tag, fv.Interface().(Vec3)); err != nil {
- return err
+ return fmt.Errorf("set %s: %v", tag, err)
}
case "float32":
if err := p.SetFloat32(tag, fv.Interface().(float32)); err != nil {
- return err
+ return fmt.Errorf("set %s: %v", tag, err)
+ }
+ case "*tofu.Texture":
+ if err := p.SetTexture(tag, fv.Interface().(*Texture)); err != nil {
+ return fmt.Errorf("set %s: %v", tag, err)
}
default:
- return fmt.Errorf("unknown uniform type: %s", ft.Type)
+ switch fv.Kind() {
+ case reflect.Struct:
+ if err := p.setUniforms(fv.Interface(), tag); err != nil {
+ return err
+ }
+ continue
+ case reflect.Pointer:
+ if err := p.setUniforms(fv.Elem().Interface(), tag); err != nil {
+ return err
+ }
+ continue
+ default:
+ return fmt.Errorf("unknown uniform type: %s", ft.Type)
+ }
}
}
return nil