瀏覽代碼

Add conversions to linear/gamma space

Popov72 4 年之前
父節點
當前提交
9ef22e38a9
共有 1 個文件被更改,包括 63 次插入0 次删除
  1. 63 0
      src/Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts

+ 63 - 0
src/Materials/Node/Blocks/Fragment/fragmentOutputBlock.ts

@@ -4,11 +4,21 @@ import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
 import { NodeMaterialBlockTargets } from '../../Enums/nodeMaterialBlockTargets';
 import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
 import { _TypeStore } from '../../../../Misc/typeStore';
+import { Scene } from '../../../../scene';
+import { AbstractMesh } from '../../../../Meshes/abstractMesh';
+import { NodeMaterialDefines } from '../../nodeMaterial';
+import { editableInPropertyPage, PropertyTypeForEdition } from "../../nodeMaterialDecorator";
+
+declare type NodeMaterial = import("../../nodeMaterial").NodeMaterial;
 
 /**
  * Block used to output the final color
  */
 export class FragmentOutputBlock extends NodeMaterialBlock {
+
+    private _linearDefineName: string;
+    private _gammaDefineName: string;
+
     /**
      * Create a new FragmentOutputBlock
      * @param name defines the block name
@@ -23,6 +33,14 @@ export class FragmentOutputBlock extends NodeMaterialBlock {
         this.rgb.acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);
     }
 
+    /** Gets or sets a boolean indicating if content needs to be converted to gamma space */
+    @editableInPropertyPage("Convert to gamma space", PropertyTypeForEdition.Boolean, "PROPERTIES", { "notifiers": { "update": true }})
+    public convertToGammaSpace = false;
+
+    /** Gets or sets a boolean indicating if content needs to be converted to linear space */
+    @editableInPropertyPage("Convert to linear space", PropertyTypeForEdition.Boolean, "PROPERTIES", { "notifiers": { "update": true }})
+    public convertToLinearSpace = false;
+
     /**
      * Gets the current class name
      * @returns the class name
@@ -52,13 +70,26 @@ export class FragmentOutputBlock extends NodeMaterialBlock {
         return this._inputs[2];
     }
 
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
+        defines.setValue(this._linearDefineName, this.convertToLinearSpace, true);
+        defines.setValue(this._gammaDefineName, this.convertToGammaSpace, true);
+    }
+
     protected _buildBlock(state: NodeMaterialBuildState) {
         super._buildBlock(state);
 
         let rgba = this.rgba;
         let rgb = this.rgb;
         let a = this.a;
+
         state.sharedData.hints.needAlphaBlending = rgba.isConnected || a.isConnected;
+        state.sharedData.blocksWithDefines.push(this);
+
+        this._linearDefineName = state._getFreeDefineName("CONVERTTOLINEAR");
+        this._gammaDefineName = state._getFreeDefineName("CONVERTTOGAMMA");
+
+        let comments = `//${this.name}`;
+        state._emitFunctionFromInclude("helperFunctions", comments);
 
         if (rgba.connectedPoint) {
             if (a.isConnected) {
@@ -82,8 +113,40 @@ export class FragmentOutputBlock extends NodeMaterialBlock {
             state.sharedData.checks.notConnectedNonOptionalInputs.push(rgba);
         }
 
+        state.compilationString += `#ifdef ${this._linearDefineName}\r\n`;
+        state.compilationString += `gl_FragColor = toLinearSpace(gl_FragColor);\r\n`;
+        state.compilationString += `#endif\r\n`;
+
+        state.compilationString += `#ifdef ${this._gammaDefineName}\r\n`;
+        state.compilationString += `gl_FragColor = toGammaSpace(gl_FragColor);\r\n`;
+        state.compilationString += `#endif\r\n`;
+
         return this;
     }
+
+    protected _dumpPropertiesCode() {
+        var codeString = "";
+        codeString += `${this._codeVariableName}.convertToGammaSpace = ${this.convertToGammaSpace};\r\n`;
+        codeString += `${this._codeVariableName}.convertToLinearSpace = ${this.convertToLinearSpace};\r\n`;
+
+        return codeString;
+    }
+
+    public serialize(): any {
+        let serializationObject = super.serialize();
+
+        serializationObject.convertToGammaSpace = this.convertToGammaSpace;
+        serializationObject.convertToLinearSpace = this.convertToLinearSpace;
+
+        return serializationObject;
+    }
+
+    public _deserialize(serializationObject: any, scene: Scene, rootUrl: string) {
+        super._deserialize(serializationObject, scene, rootUrl);
+
+        this.convertToGammaSpace = serializationObject.convertToGammaSpace;
+        this.convertToLinearSpace = serializationObject.convertToLinearSpace;
+    }
 }
 
 _TypeStore.RegisteredTypes["BABYLON.FragmentOutputBlock"] = FragmentOutputBlock;