lighting, automatic parameter assignment

This commit is contained in:
Vadim Lopatin 2016-04-05 09:33:16 +03:00
parent d8bca0d935
commit 1a1e904f2e
5 changed files with 97 additions and 38 deletions

View File

@ -115,10 +115,11 @@ class UiWidget : VerticalLayout, CellVisitor {
_scene.activeCamera = _cam; _scene.activeCamera = _cam;
Node3d dirLightNode = new Node3d(); Node3d dirLightNode = new Node3d();
dirLightNode.lookAt(vec3(-5, -5, -5), vec3(0, 0, 0), vec3(0, 1, 0)); //dirLightNode.lookAt(vec3(-5, -5, -5), vec3(0, 0, 0), vec3(0, 1, 0));
//dirLightNode.rotateY(-15); //dirLightNode.rotateY(-15);
//dirLightNode.rotateX(20); //dirLightNode.rotateX(20);
dirLightNode.light = Light.createDirectional(vec3(1, 0.5, 0.5)); dirLightNode.light = Light.createPoint(vec3(1, 0.5, 0.5), 5); //Light.createDirectional(vec3(1, 0.5, 0.5));
dirLightNode.light.enabled = false;
_scene.addChild(dirLightNode); _scene.addChild(dirLightNode);
int x0 = 0; int x0 = 0;
@ -137,7 +138,7 @@ class UiWidget : VerticalLayout, CellVisitor {
_mesh.addCubeMesh(vec3(x0+ i * 2 + 1.0f, y0+-i * 2 + 1.0f, z0+ i * 2 + 1.0f), 0.2f, vec4(i / 12, 1 - i / 12, i / 12, 1)); _mesh.addCubeMesh(vec3(x0+ i * 2 + 1.0f, y0+-i * 2 + 1.0f, z0+ i * 2 + 1.0f), 0.2f, vec4(i / 12, 1 - i / 12, i / 12, 1));
_mesh.addCubeMesh(vec3(x0+ -i * 2 - 1.0f, y0+-i * 2 - 1.0f, z0+ -i * 2 - 1.0f), 0.2f, vec4(1 - i / 12, i / 12, i / 12, 1)); _mesh.addCubeMesh(vec3(x0+ -i * 2 - 1.0f, y0+-i * 2 - 1.0f, z0+ -i * 2 - 1.0f), 0.2f, vec4(1 - i / 12, i / 12, i / 12, 1));
} }
Material cubeMaterial = new Material(EffectId("textured.vert", "textured.frag", null), "crate"); Material cubeMaterial = new Material(EffectId("textured.vert", "textured.frag", "SPECULAR"), "crate");
Model cubeDrawable = new Model(cubeMaterial, _mesh); Model cubeDrawable = new Model(cubeMaterial, _mesh);
Node3d cubeNode = new Node3d("cubes", cubeDrawable); Node3d cubeNode = new Node3d("cubes", cubeDrawable);
_scene.addChild(cubeNode); _scene.addChild(cubeNode);
@ -146,8 +147,8 @@ class UiWidget : VerticalLayout, CellVisitor {
string src = loadTextResource("suzanne.obj"); string src = loadTextResource("suzanne.obj");
importer.parse(src); importer.parse(src);
Log.d("suzanne mesh:", importer.mesh.dumpVertexes(20)); Log.d("suzanne mesh:", importer.mesh.dumpVertexes(20));
Material suzanneMaterial = new Material(EffectId("colored.vert", "colored.frag", null), null); //"DIRECTIONAL_LIGHT_COUNT 1" Material suzanneMaterial = new Material(EffectId("colored.vert", "colored.frag", "SPECULAR"), null); //"SPECULAR"
suzanneMaterial.ambientColor = vec3(0.5, 1.0, 0.5); suzanneMaterial.ambientColor = vec3(0.0, 0.0, 0.0);
suzanneMaterial.diffuseColor = vec4(1.0, 0.7, 0.7, 1.0); suzanneMaterial.diffuseColor = vec4(1.0, 0.7, 0.7, 1.0);
Model suzanneDrawable = new Model(suzanneMaterial, importer.mesh); Model suzanneDrawable = new Model(suzanneMaterial, importer.mesh);
Node3d suzanneNode = new Node3d("suzanne", suzanneDrawable); Node3d suzanneNode = new Node3d("suzanne", suzanneDrawable);

View File

@ -132,30 +132,30 @@ struct Lights {
@property int directionalCount() const { return cast(int)directional.length; } @property int directionalCount() const { return cast(int)directional.length; }
@property int pointCount() const { return cast(int)point.length; } @property int pointCount() const { return cast(int)point.length; }
@property int spotCount() const { return cast(int)spot.length; } @property int spotCount() const { return cast(int)spot.length; }
/// return light count definition for shaders, e.g. "DIRECTIONAL_LIGHT_COUNT 2;POINT_LIGHT_COUNT 1" ///// return light count definition for shaders, e.g. "DIRECTIONAL_LIGHT_COUNT 2;POINT_LIGHT_COUNT 1"
@property string defs() const { //@property string defs() const {
if (!directional.length && !point.length && !spot.length) // if (!directional.length && !point.length && !spot.length)
return null; // return null;
static __gshared char[] buf; // static __gshared char[] buf;
buf.length = 0; // reset buffer // buf.length = 0; // reset buffer
if (directional.length) { // if (directional.length) {
buf ~= "DIRECTIONAL_LIGHT_COUNT "; // buf ~= "DIRECTIONAL_LIGHT_COUNT ";
buf ~= directional.length.to!string; // buf ~= directional.length.to!string;
} // }
if (point.length) { // if (point.length) {
if (buf) // if (buf.length)
buf ~= ";"; // buf ~= ";";
buf ~= "POINT_LIGHT_COUNT "; // buf ~= "POINT_LIGHT_COUNT ";
buf ~= point.length.to!string; // buf ~= point.length.to!string;
} // }
if (spot.length) { // if (spot.length) {
if (buf) // if (buf.length)
buf ~= ";"; // buf ~= ";";
buf ~= "SPOT_LIGHT_COUNT "; // buf ~= "SPOT_LIGHT_COUNT ";
buf ~= spot.length.to!string; // buf ~= spot.length.to!string;
} // }
return buf.dup; // return buf.dup;
} //}
void remove(Light light) { void remove(Light light) {
import std.algorithm : remove; import std.algorithm : remove;
switch(light.type) { switch(light.type) {
@ -228,7 +228,7 @@ struct LightParams {
Lights _lights; Lights _lights;
@property bool empty() const { return _lights.empty; } @property bool empty() const { return _lights.empty; }
@property string defs() const { return _lights.defs; } //@property string defs() const { return _lights.defs; }
void reset() { void reset() {
_lights.reset(); _lights.reset();

View File

@ -27,7 +27,7 @@ class Material : RefCountedObject {
// colors // colors
protected vec4 _diffuseColor = vec4(1, 1, 1, 1); protected vec4 _diffuseColor = vec4(1, 1, 1, 1);
protected vec3 _ambientColor = vec3(1, 1, 1); protected vec3 _ambientColor = vec3(0, 0, 0);
protected vec4 _modulateColor = vec4(1, 1, 1, 1); protected vec4 _modulateColor = vec4(1, 1, 1, 1);
protected float _modulateAlpha = 1; protected float _modulateAlpha = 1;
@ -101,14 +101,19 @@ class Material : RefCountedObject {
return this; return this;
} }
string calcAutoEffectParams(LightParams * lights) { private AutoParams _lastParams;
if (!lights || lights.empty) private string _lastDefs;
return null; string calcAutoEffectParams(Mesh mesh, LightParams * lights) {
return lights.defs; AutoParams newParams = AutoParams(mesh, lights, false);
if (newParams != _lastParams) {
_lastParams = newParams;
_lastDefs = _lastParams.defs;
}
return _lastDefs;
} }
void bind(Node3d node, LightParams * lights = null) { void bind(Node3d node, Mesh mesh, LightParams * lights = null) {
autoEffectParams = calcAutoEffectParams(lights); autoEffectParams = calcAutoEffectParams(mesh, lights);
assert(!effect.isNull); assert(!effect.isNull);
effect.bind(); effect.bind();
if (!texture.isNull) { if (!texture.isNull) {
@ -173,3 +178,51 @@ class Material : RefCountedObject {
effect.unbind(); effect.unbind();
} }
} }
struct AutoParams {
ubyte directionalLightCount = 0;
ubyte pointLightCount = 0;
ubyte spotLightCount = 0;
bool vertexColor = false;
bool specular = false;
this(Mesh mesh, LightParams * lights, bool specular) {
if (mesh)
vertexColor = mesh.hasElement(VertexElementType.COLOR);
if (lights) {
directionalLightCount = cast(ubyte)lights.u_directionalLightDirection.length;
pointLightCount = cast(ubyte)lights.u_pointLightPosition.length;
spotLightCount = cast(ubyte)lights.u_spotLightPosition.length;
}
this.specular = specular;
}
string defs() {
char buf[];
if (directionalLightCount) {
buf ~= "DIRECTIONAL_LIGHT_COUNT ";
buf ~= directionalLightCount.to!string;
}
if (pointLightCount) {
if (buf.length)
buf ~= ";";
buf ~= "POINT_LIGHT_COUNT ";
buf ~= pointLightCount.to!string;
}
if (spotLightCount) {
if (buf.length)
buf ~= ";";
buf ~= "SPOT_LIGHT_COUNT ";
buf ~= spotLightCount.to!string;
}
if (vertexColor) {
if (buf.length)
buf ~= ";";
buf ~= "VERTEX_COLOR";
}
if (specular) {
if (buf.length)
buf ~= ";";
buf ~= "SPECULAR";
}
return buf.dup;
}
}

View File

@ -314,6 +314,11 @@ class Mesh : RefCountedObject {
@property ref VertexFormat vertexFormat() { return _vertexFormat; } @property ref VertexFormat vertexFormat() { return _vertexFormat; }
@property const(VertexFormat) * vertexFormatPtr() { return &_vertexFormat; } @property const(VertexFormat) * vertexFormatPtr() { return &_vertexFormat; }
/// returns true if vertex format contains specified element
bool hasElement(VertexElementType type) const {
return _vertexFormat.hasElement(type);
}
//@property ref VertexFormat vertexFormat() { return _vertexFormat; } //@property ref VertexFormat vertexFormat() { return _vertexFormat; }
@property void vertexFormat(VertexFormat format) { @property void vertexFormat(VertexFormat format) {

View File

@ -56,7 +56,7 @@ class Model : DrawableObject {
override void draw(Node3d node, bool wireframe) { override void draw(Node3d node, bool wireframe) {
/// override it /// override it
_material.bind(node, lights(node)); _material.bind(node, _mesh, lights(node));
_material.drawMesh(_mesh); _material.drawMesh(_mesh);
_material.unbind(); _material.unbind();
} }